feat(block): allow templates for filler text
Some checks failed
Code QL / code-ql (push) Waiting to run
Release / changelog (push) Waiting to run
Release / artifacts (push) Blocked by required conditions
Release / msi (arm64) (push) Blocked by required conditions
Release / msi (x64) (push) Blocked by required conditions
Release / msi (x86) (push) Blocked by required conditions
Release / cdn (arm64) (push) Blocked by required conditions
Release / cdn (x64) (push) Blocked by required conditions
Release / cdn (x86) (push) Blocked by required conditions
Release / release (push) Blocked by required conditions
Azure Static Web Apps CI/CD / Build and Deploy (push) Has been cancelled

This change allows the user to specify a template for filler so that
different behavior can be configured when the block is handling an
overflow.

An example configuration might be:

```yaml
- type: prompt
  alignment: right
  filler: "{{ if .Overflow }} {{ else }}<#3d59a1,transparent>━</>{{ end }}"
  overflow: break
```

This would draw filler text ("-") when there is no overflow and empty
space when there is an overflow.
This commit is contained in:
Tucker Beck 2024-11-26 17:31:00 -08:00 committed by Jan De Dobbeleer
parent ebc7d25922
commit b4fe0a09ce
3 changed files with 143 additions and 1 deletions

View file

@ -20,9 +20,11 @@ type Engine struct {
activeSegment *config.Segment
previousActiveSegment *config.Segment
rprompt string
Overflow config.Overflow
prompt strings.Builder
currentLineLength int
rpromptLength int
Padding int
Plain bool
}
@ -157,7 +159,13 @@ func (e *Engine) shouldFill(filler string, padLength int) (string, bool) {
return "", false
}
if padLength <= 0 {
tmpl := &template.Text{
Template: filler,
Context: e,
}
var err error
if filler, err = tmpl.Render(); err != nil {
return "", false
}
@ -218,6 +226,7 @@ func (e *Engine) renderBlock(block *config.Block, cancelNewline bool) bool {
// we can't print the right block as there's not enough room available
if !OK {
e.Overflow = block.Overflow
switch block.Overflow {
case config.Break:
e.writeNewline()
@ -234,6 +243,7 @@ func (e *Engine) renderBlock(block *config.Block, cancelNewline bool) bool {
defer func() {
e.currentLineLength = 0
e.Overflow = ""
}()
// validate if we have a filler and fill if needed

View file

@ -2,9 +2,11 @@ package prompt
import (
"errors"
"strings"
"testing"
"github.com/jandedobbeleer/oh-my-posh/src/cache"
"github.com/jandedobbeleer/oh-my-posh/src/color"
"github.com/jandedobbeleer/oh-my-posh/src/config"
"github.com/jandedobbeleer/oh-my-posh/src/maps"
"github.com/jandedobbeleer/oh-my-posh/src/runtime"
@ -276,3 +278,112 @@ func TestGetConsoleTitleIfGethostnameReturnsError(t *testing.T) {
assert.Equal(t, tc.Expected, got)
}
}
func TestShouldFill(t *testing.T) {
cases := []struct {
Case string
Overflow config.Overflow
ExpectedFiller string
Block config.Block
Padding int
ExpectedBool bool
}{
{
Case: "Plain single character with no padding",
Padding: 0,
ExpectedFiller: "",
ExpectedBool: true,
Block: config.Block{
Overflow: config.Hide,
Filler: "-",
},
},
{
Case: "Plain single character with 1 padding",
Padding: 1,
ExpectedFiller: "-",
ExpectedBool: true,
Block: config.Block{
Overflow: config.Hide,
Filler: "-",
},
},
{
Case: "Plain single character with lots of padding",
Padding: 200,
ExpectedFiller: strings.Repeat("-", 200),
ExpectedBool: true,
Block: config.Block{
Overflow: config.Hide,
Filler: "-",
},
},
{
Case: "Plain multi-character with some padding",
Padding: 20,
ExpectedFiller: strings.Repeat("-^-", 6) + " ",
ExpectedBool: true,
Block: config.Block{
Overflow: config.Hide,
Filler: "-^-",
},
},
{
Case: "Template conditional on overflow with no overflow",
Padding: 3,
ExpectedFiller: strings.Repeat("X", 3),
ExpectedBool: true,
Block: config.Block{
Overflow: config.Hide,
Filler: "{{ if .Overflow -}} O {{- else -}} X {{- end }}",
},
},
{
Case: "Template conditional on overflow with an overflow",
Overflow: config.Break,
Padding: 3,
ExpectedFiller: strings.Repeat("O", 3),
ExpectedBool: true,
Block: config.Block{
Overflow: config.Hide,
Filler: "{{ if .Overflow -}} O {{- else -}} X {{- end }}",
},
},
{
Case: "Template conditional on overflow break",
Overflow: config.Break,
Padding: 3,
ExpectedFiller: strings.Repeat("O", 3),
ExpectedBool: true,
Block: config.Block{
Overflow: config.Break,
Filler: `{{ if eq .Overflow "break" -}} O {{- else -}} X {{- end }}`,
},
},
}
for _, tc := range cases {
env := new(mock.Environment)
env.On("Shell").Return(shell.GENERIC)
engine := &Engine{
Env: env,
Overflow: tc.Overflow,
}
template.Cache = &cache.Template{
Shell: shell.GENERIC,
Segments: maps.NewConcurrent(),
}
template.Init(env, nil)
terminal.Init(shell.GENERIC)
terminal.Plain = true
terminal.Colors = &color.Defaults{}
gotFiller, gotBool := engine.shouldFill(tc.Block.Filler, tc.Padding)
assert.Equal(t, tc.ExpectedFiller, gotFiller, tc.Case)
assert.Equal(t, tc.ExpectedBool, gotBool, tc.Case)
}
}

View file

@ -71,6 +71,27 @@ to be repeated to this property. Add this property to the _right_ aligned block.
}}
/>
Filler allows you to specify a template to tweak the text used as filler. This template behaves the same as
Segment templates, however, fewer properties are available.
| Name | Type | Description |
| ----------- | ------ | --------------------------------------------------------------------- |
| `.Overflow` | `text` | if no overflow was needed, this is empty. Otherwise `hide` or `break` |
| `.Padding` | `int` | the computed length of the padding between left and right blocks |
This can be very useful if you wish to use a filler text when there is no overflow and use
empty space when the right block is hidden or drawn on a newline due to overflow.
<Config
data={{
block: {
alignment: "right",
overflow: "hide",
filler: "{{ if .Overflow }} {{ else }}-{{ end }}",
},
}}
/>
### Overflow
- `break`