mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-29 23:17:32 +02:00
Merge pull request #1423 from FoamScience/feature/colorsInMenuFromCommand
Support match colors in `labelFormat` entry in menuFromCommand prompts
This commit is contained in:
commit
a3a14e9ff4
@ -48,7 +48,7 @@ customCommands:
|
|||||||
command: 'git branch -r --list {{index .PromptResponses 0}}/*'
|
command: 'git branch -r --list {{index .PromptResponses 0}}/*'
|
||||||
filter: '.*{{index .PromptResponses 0}}/(?P<branch>.*)'
|
filter: '.*{{index .PromptResponses 0}}/(?P<branch>.*)'
|
||||||
valueFormat: '{{ .branch }}'
|
valueFormat: '{{ .branch }}'
|
||||||
labelFormat: ''
|
labelFormat: '{{ .branch | green }}'
|
||||||
```
|
```
|
||||||
|
|
||||||
Looking at the command assigned to the 'n' key, here's what the result looks like:
|
Looking at the command assigned to the 'n' key, here's what the result looks like:
|
||||||
@ -110,8 +110,10 @@ The permitted prompt fields are:
|
|||||||
| | PS: named groups keep first match only | |
|
| | PS: named groups keep first match only | |
|
||||||
| labelFormat | (only applicable to 'menuFromCommand' prompts) how to format matched groups from | no |
|
| labelFormat | (only applicable to 'menuFromCommand' prompts) how to format matched groups from | no |
|
||||||
| | the filter to construct the item's label (What's shown on screen). You can use | |
|
| | the filter to construct the item's label (What's shown on screen). You can use | |
|
||||||
| | named groups, or `{{ .group_GROUPID }}`. If this is not specified, `valueFormat` | |
|
| | named groups, or `{{ .group_GROUPID }}`. You can also color each match with | |
|
||||||
| | is shown instead. | |
|
| | `{{ .group_GROUPID | colorname }}` (Color names from | |
|
||||||
|
| | [here](https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md)) | |
|
||||||
|
| | If `labelFormat` is not specified, `valueFormat` is shown instead. | |
|
||||||
| | PS: named groups keep first match only | |
|
| | PS: named groups keep first match only | |
|
||||||
|
|
||||||
The permitted option fields are:
|
The permitted option fields are:
|
||||||
|
@ -136,7 +136,9 @@ func (gui *Gui) GenerateMenuCandidates(commandOutput, filter, valueFormat, label
|
|||||||
return nil, gui.surfaceError(errors.New("unable to parse value format, error: " + err.Error()))
|
return nil, gui.surfaceError(errors.New("unable to parse value format, error: " + err.Error()))
|
||||||
}
|
}
|
||||||
|
|
||||||
descTemp, err := template.New("format").Parse(labelFormat)
|
colorFuncMap := style.TemplateFuncMapAddColors(template.FuncMap{})
|
||||||
|
|
||||||
|
descTemp, err := template.New("format").Funcs(colorFuncMap).Parse(labelFormat)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, gui.surfaceError(errors.New("unable to parse label format, error: " + err.Error()))
|
return nil, gui.surfaceError(errors.New("unable to parse label format, error: " + err.Error()))
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package style
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/gookit/color"
|
"github.com/gookit/color"
|
||||||
|
"text/template"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -27,6 +28,21 @@ var (
|
|||||||
|
|
||||||
AttrUnderline = New().SetUnderline()
|
AttrUnderline = New().SetUnderline()
|
||||||
AttrBold = New().SetBold()
|
AttrBold = New().SetBold()
|
||||||
|
|
||||||
|
ColorMap = map[string]struct {
|
||||||
|
Foreground TextStyle
|
||||||
|
Background TextStyle
|
||||||
|
}{
|
||||||
|
"default": {FgWhite, BgBlack},
|
||||||
|
"black": {FgBlack, BgBlack},
|
||||||
|
"red": {FgRed, BgRed},
|
||||||
|
"green": {FgGreen, BgGreen},
|
||||||
|
"yellow": {FgYellow, BgYellow},
|
||||||
|
"blue": {FgBlue, BgBlue},
|
||||||
|
"magenta": {FgMagenta, BgMagenta},
|
||||||
|
"cyan": {FgCyan, BgCyan},
|
||||||
|
"white": {FgWhite, BgWhite},
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func FromBasicFg(fg color.Color) TextStyle {
|
func FromBasicFg(fg color.Color) TextStyle {
|
||||||
@ -36,3 +52,12 @@ func FromBasicFg(fg color.Color) TextStyle {
|
|||||||
func FromBasicBg(bg color.Color) TextStyle {
|
func FromBasicBg(bg color.Color) TextStyle {
|
||||||
return New().SetBg(NewBasicColor(bg))
|
return New().SetBg(NewBasicColor(bg))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TemplateFuncMapAddColors(m template.FuncMap) template.FuncMap {
|
||||||
|
for k, v := range ColorMap {
|
||||||
|
m[k] = v.Foreground.Sprint
|
||||||
|
}
|
||||||
|
m["underline"] = color.OpUnderscore.Sprint
|
||||||
|
m["bold"] = color.OpBold.Sprint
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package style
|
package style
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"testing"
|
"testing"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
"github.com/gookit/color"
|
"github.com/gookit/color"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -157,3 +159,53 @@ func TestMerge(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTemplateFuncMapAddColors(t *testing.T) {
|
||||||
|
type scenario struct {
|
||||||
|
name string
|
||||||
|
tmpl string
|
||||||
|
expect string
|
||||||
|
}
|
||||||
|
|
||||||
|
scenarios := []scenario{
|
||||||
|
{
|
||||||
|
"normal template",
|
||||||
|
"{{ .Foo }}",
|
||||||
|
"bar",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"colored string",
|
||||||
|
"{{ .Foo | red }}",
|
||||||
|
"\x1b[31mbar\x1b[0m",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"string with decorator",
|
||||||
|
"{{ .Foo | bold }}",
|
||||||
|
"\x1b[1mbar\x1b[0m",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"string with color and decorator",
|
||||||
|
"{{ .Foo | bold | red }}",
|
||||||
|
"\x1b[31m\x1b[1mbar\x1b[0m\x1b[0m",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"multiple string with diffrent colors",
|
||||||
|
"{{ .Foo | red }} - {{ .Foo | blue }}",
|
||||||
|
"\x1b[31mbar\x1b[0m - \x1b[34mbar\x1b[0m",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, s := range scenarios {
|
||||||
|
s := s
|
||||||
|
t.Run(s.name, func(t *testing.T) {
|
||||||
|
tmpl, err := template.New("test template").Funcs(TemplateFuncMapAddColors(template.FuncMap{})).Parse(s.tmpl)
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
buff := bytes.NewBuffer(nil)
|
||||||
|
err = tmpl.Execute(buff, struct{ Foo string }{"bar"})
|
||||||
|
assert.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, s.expect, buff.String())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -6,21 +6,6 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
var colorMap = map[string]struct {
|
|
||||||
foreground style.TextStyle
|
|
||||||
background style.TextStyle
|
|
||||||
}{
|
|
||||||
"default": {style.FgWhite, style.BgBlack},
|
|
||||||
"black": {style.FgBlack, style.BgBlack},
|
|
||||||
"red": {style.FgRed, style.BgRed},
|
|
||||||
"green": {style.FgGreen, style.BgGreen},
|
|
||||||
"yellow": {style.FgYellow, style.BgYellow},
|
|
||||||
"blue": {style.FgBlue, style.BgBlue},
|
|
||||||
"magenta": {style.FgMagenta, style.BgMagenta},
|
|
||||||
"cyan": {style.FgCyan, style.BgCyan},
|
|
||||||
"white": {style.FgWhite, style.BgWhite},
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetTextStyle(keys []string, background bool) style.TextStyle {
|
func GetTextStyle(keys []string, background bool) style.TextStyle {
|
||||||
s := style.New()
|
s := style.New()
|
||||||
|
|
||||||
@ -33,13 +18,13 @@ func GetTextStyle(keys []string, background bool) style.TextStyle {
|
|||||||
case "underline":
|
case "underline":
|
||||||
s = s.SetUnderline()
|
s = s.SetUnderline()
|
||||||
default:
|
default:
|
||||||
value, present := colorMap[key]
|
value, present := style.ColorMap[key]
|
||||||
if present {
|
if present {
|
||||||
var c style.TextStyle
|
var c style.TextStyle
|
||||||
if background {
|
if background {
|
||||||
c = value.background
|
c = value.Background
|
||||||
} else {
|
} else {
|
||||||
c = value.foreground
|
c = value.Foreground
|
||||||
}
|
}
|
||||||
s = s.MergeStyle(c)
|
s = s.MergeStyle(c)
|
||||||
} else if utils.IsValidHexValue(key) {
|
} else if utils.IsValidHexValue(key) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user