Move gui.authorColors and gui.branchColorPatterns into gui.theme

We are about to add overrides of gui.theme for dark and light
backgrounds. Author and branch colors need them too, because a color
that reads well on a dark background may be hard to read on a light
one. Move them into gui.theme, so that the overrides cover them without
a mechanism of their own.

The migration of gui.branchColors creates gui.branchColorPatterns, so it
now has to run before the moves.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stefan Haller
2026-09-27 08:16:06 +02:00
co-authored by Claude Opus 5.5
parent 8e396228e9
commit 51002cc473
9 changed files with 113 additions and 63 deletions
+20 -17
View File
@@ -37,12 +37,6 @@ This is only meant as a reference for what config options exist, and what their
```yaml
# Config relating to the Lazygit UI
gui:
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color
authorColors: {}
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
branchColorPatterns: {}
# Custom icons for filenames and file extensions
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-files-icon--color
customIcons:
@@ -230,6 +224,12 @@ gui:
defaultFgColor:
- default
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color
authorColors: {}
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
branchColorPatterns: {}
# Config relating to the commit length indicator
commitLength:
# If true, show an indicator of commit message length
@@ -1040,20 +1040,22 @@ You can customize the color in case you're not happy with the randomly assigned
```yaml
gui:
authorColors:
'John Smith': 'red' # use red for John Smith
'Alan Smithee': '#00ff00' # use green for Alan Smithee
theme:
authorColors:
'John Smith': 'red' # use red for John Smith
'Alan Smithee': '#00ff00' # use green for Alan Smithee
```
You can use wildcard to set a unified color in case your are lazy to customize the color for every author or you just want a single color for all/other authors:
```yaml
gui:
authorColors:
# use red for John Smith
'John Smith': 'red'
# use blue for other authors
'*': '#0000ff'
theme:
authorColors:
# use red for John Smith
'John Smith': 'red'
# use blue for other authors
'*': '#0000ff'
```
## Custom Branch Color
@@ -1062,9 +1064,10 @@ You can customize the color of branches based on branch patterns (regular expres
```yaml
gui:
branchColorPatterns:
'^docs/': '#11aaff' # use a light blue for branches beginning with 'docs/'
'ISSUE-\d+': '#ff5733' # use a bright orange for branches containing 'ISSUE-<some-number>'
theme:
branchColorPatterns:
'^docs/': '#11aaff' # use a light blue for branches beginning with 'docs/'
'ISSUE-\d+': '#ff5733' # use a bright orange for branches containing 'ISSUE-<some-number>'
```
Note that the regular expressions are not implicitly anchored to the beginning/end of the branch name. If you want to do that, add leading `^` and/or trailing `$` as needed.
+15 -5
View File
@@ -310,6 +310,13 @@ func computeMigratedConfig(path string, content []byte, changes *ChangesSet) ([]
}
}
// This creates gui.branchColorPatterns, so it must run before the move of
// that key into gui.theme below.
err = migrateBranchColors(&rootNode, changes)
if err != nil {
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %w", path, err)
}
pathsToMove := []struct {
oldPath []string
newPath []string
@@ -318,6 +325,14 @@ func computeMigratedConfig(path string, content []byte, changes *ChangesSet) ([]
[]string{"keybinding", "worktrees", "viewWorktreeOptions"},
[]string{"keybinding", "universal", "newWorktree"},
},
{
[]string{"gui", "authorColors"},
[]string{"gui", "theme", "authorColors"},
},
{
[]string{"gui", "branchColorPatterns"},
[]string{"gui", "theme", "branchColorPatterns"},
},
}
for _, pathToMove := range pathsToMove {
@@ -365,11 +380,6 @@ func computeMigratedConfig(path string, content []byte, changes *ChangesSet) ([]
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %w", path, err)
}
err = migrateBranchColors(&rootNode, changes)
if err != nil {
return nil, false, fmt.Errorf("Couldn't migrate config file at `%s`: %w", path, err)
}
// Add more migrations here...
if reflect.DeepEqual(rootNode, originalCopy) {
+58 -20
View File
@@ -175,6 +175,32 @@ func TestMigrationOfMovedKeys(t *testing.T) {
expectedDidChange: true,
expectedChanges: []string{"Moved 'keybinding.worktrees.viewWorktreeOptions' to 'keybinding.universal.newWorktree'"},
},
{
name: "Move author and branch colors into the theme",
input: `gui:
authorColors:
John Smith: red
theme:
activeBorderColor:
- green
branchColorPatterns:
^docs/: blue
`,
expected: `gui:
theme:
activeBorderColor:
- green
authorColors:
John Smith: red
branchColorPatterns:
^docs/: blue
`,
expectedDidChange: true,
expectedChanges: []string{
"Moved 'gui.authorColors' to 'gui.theme.authorColors'",
"Moved 'gui.branchColorPatterns' to 'gui.theme.branchColorPatterns'",
},
},
}
for _, s := range scenarios {
@@ -823,6 +849,8 @@ func TestPagerMigration(t *testing.T) {
}
func TestBranchColorsMigration(t *testing.T) {
moved := "Moved 'gui.branchColorPatterns' to 'gui.theme.branchColorPatterns'"
scenarios := []struct {
name string
input string
@@ -833,8 +861,9 @@ func TestBranchColorsMigration(t *testing.T) {
{
name: "No branchColors",
input: "gui:\n" +
" branchColorPatterns:\n" +
" '^docs/': blue\n",
" theme:\n" +
" branchColorPatterns:\n" +
" '^docs/': blue\n",
expectedDidChange: false,
expectedChanges: []string{},
},
@@ -846,7 +875,7 @@ func TestBranchColorsMigration(t *testing.T) {
expectedChanges: []string{},
},
{
name: "branchColors is converted to patterns in place",
name: "branchColors is converted to patterns",
input: "gui:\n" +
" scrollHeight: 2\n" +
" branchColors:\n" +
@@ -856,13 +885,14 @@ func TestBranchColorsMigration(t *testing.T) {
" mouseEvents: false\n",
expected: "gui:\n" +
" scrollHeight: 2\n" +
" branchColorPatterns:\n" +
" ^feature(/|$): green\n" +
" ^v1\\.x(/|$): '#ff0000'\n" +
" ^123(/|$): red\n" +
" mouseEvents: false\n",
" mouseEvents: false\n" +
" theme:\n" +
" branchColorPatterns:\n" +
" ^feature(/|$): green\n" +
" ^v1\\.x(/|$): '#ff0000'\n" +
" ^123(/|$): red\n",
expectedDidChange: true,
expectedChanges: []string{"Converted 'gui.branchColors' to 'gui.branchColorPatterns'"},
expectedChanges: []string{"Converted 'gui.branchColors' to 'gui.branchColorPatterns'", moved},
},
{
name: "branchColors is removed if branchColorPatterns is set",
@@ -872,10 +902,11 @@ func TestBranchColorsMigration(t *testing.T) {
" branchColorPatterns:\n" +
" '^docs/': blue\n",
expected: "gui:\n" +
" branchColorPatterns:\n" +
" '^docs/': blue\n",
" theme:\n" +
" branchColorPatterns:\n" +
" '^docs/': blue\n",
expectedDidChange: true,
expectedChanges: []string{"Removed 'gui.branchColors'; it had no effect because 'gui.branchColorPatterns' is set"},
expectedChanges: []string{"Removed 'gui.branchColors'; it had no effect because 'gui.branchColorPatterns' is set", moved},
},
{
name: "branchColors replaces an empty branchColorPatterns",
@@ -884,10 +915,11 @@ func TestBranchColorsMigration(t *testing.T) {
" branchColors:\n" +
" feature: green\n",
expected: "gui:\n" +
" branchColorPatterns:\n" +
" ^feature(/|$): green\n",
" theme:\n" +
" branchColorPatterns:\n" +
" ^feature(/|$): green\n",
expectedDidChange: true,
expectedChanges: []string{"Converted 'gui.branchColors' to 'gui.branchColorPatterns'"},
expectedChanges: []string{"Converted 'gui.branchColors' to 'gui.branchColorPatterns'", moved},
},
{
name: "branchColors replaces a null branchColorPatterns",
@@ -896,10 +928,11 @@ func TestBranchColorsMigration(t *testing.T) {
" branchColors:\n" +
" feature: green\n",
expected: "gui:\n" +
" branchColorPatterns:\n" +
" ^feature(/|$): green\n",
" theme:\n" +
" branchColorPatterns:\n" +
" ^feature(/|$): green\n",
expectedDidChange: true,
expectedChanges: []string{"Converted 'gui.branchColors' to 'gui.branchColorPatterns'"},
expectedChanges: []string{"Converted 'gui.branchColors' to 'gui.branchColorPatterns'", moved},
},
{
name: "branchColors is kept if branchColorPatterns is not an object",
@@ -907,8 +940,13 @@ func TestBranchColorsMigration(t *testing.T) {
" branchColorPatterns: 5\n" +
" branchColors:\n" +
" feature: green\n",
expectedDidChange: false,
expectedChanges: []string{},
expected: "gui:\n" +
" branchColors:\n" +
" feature: green\n" +
" theme:\n" +
" branchColorPatterns: 5\n",
expectedDidChange: true,
expectedChanges: []string{moved},
},
}
+4 -4
View File
@@ -68,10 +68,6 @@ func (c *RefresherConfig) ExternalChangeCheckIntervalDuration() time.Duration {
}
type GuiConfig struct {
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color
AuthorColors map[string]string `yaml:"authorColors"`
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
BranchColorPatterns ColorPatterns `yaml:"branchColorPatterns"`
// Custom icons for filenames and file extensions
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-files-icon--color
CustomIcons CustomIconsConfig `yaml:"customIcons"`
@@ -255,6 +251,10 @@ type ThemeConfig struct {
UnstagedChangesColor []string `yaml:"unstagedChangesColor" jsonschema:"minItems=1,uniqueItems=true"`
// Default text color
DefaultFgColor []string `yaml:"defaultFgColor" jsonschema:"minItems=1,uniqueItems=true"`
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color
AuthorColors map[string]string `yaml:"authorColors"`
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
BranchColorPatterns ColorPatterns `yaml:"branchColorPatterns"`
}
type CommitLengthConfig struct {
+2 -3
View File
@@ -517,7 +517,6 @@ func (gui *Gui) onUserConfigLoaded() error {
// sake of backwards compatibility. We're making use of short circuiting here
gui.ShowExtrasWindow = userConfig.Gui.ShowCommandLog && !gui.c.GetAppState().HideCommandLog
authors.SetCustomAuthors(userConfig.Gui.AuthorColors)
if userConfig.Gui.NerdFontsVersion != "" {
icons.SetNerdFontsVersion(userConfig.Gui.NerdFontsVersion)
} else if userConfig.Gui.ShowIcons {
@@ -526,8 +525,6 @@ func (gui *Gui) onUserConfigLoaded() error {
icons.SetNerdFontsVersion("")
}
presentation.SetCustomBranches(userConfig.Gui.BranchColorPatterns)
return nil
}
@@ -1253,6 +1250,8 @@ func (gui *Gui) showBreakingChangesMessage() {
func (gui *Gui) setColorScheme() {
userConfig := gui.UserConfig()
theme.UpdateTheme(userConfig.Gui.Theme)
authors.SetCustomAuthors(userConfig.Gui.Theme.AuthorColors)
presentation.SetCustomBranches(userConfig.Gui.Theme.BranchColorPatterns)
gui.g.FgColor = theme.InactiveBorderColor
gui.g.SelFgColor = theme.ActiveBorderColor
+1 -1
View File
@@ -422,7 +422,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
defer color.ForceSetColorLevel(oldColorLevel)
c := common.NewDummyCommon()
SetCustomBranches(c.UserConfig().Gui.BranchColorPatterns)
SetCustomBranches(c.UserConfig().Gui.Theme.BranchColorPatterns)
for i, s := range scenarios {
icons.SetNerdFontsVersion(lo.Ternary(s.useIcons, "3", ""))
+1 -1
View File
@@ -11,7 +11,7 @@ var Highlight = NewIntegrationTest(NewIntegrationTestArgs{
Skip: false,
SetupConfig: func(config *config.AppConfig) {
config.GetUserConfig().Git.Log.ShowGraph = "always"
config.GetUserConfig().Gui.AuthorColors = map[string]string{
config.GetUserConfig().Gui.Theme.AuthorColors = map[string]string{
"CI": "red",
}
},
+1 -1
View File
@@ -4,7 +4,7 @@ import "github.com/jesseduffield/lazygit/pkg/config"
// Gives us nicer colours when we generate a git repo history with `shell.CreateRepoHistory()`
func setGeneratedAuthorColours(config *config.AppConfig) {
config.GetUserConfig().Gui.AuthorColors = map[string]string{
config.GetUserConfig().Gui.Theme.AuthorColors = map[string]string{
"Fredrica Greenhill": "#fb5aa3",
"Oscar Reuenthal": "#86c82f",
"Paul Oberstein": "#ffd500",
+11 -11
View File
@@ -537,17 +537,6 @@
},
"GuiConfig": {
"properties": {
"authorColors": {
"additionalProperties": {
"type": "string"
},
"type": "object",
"description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color"
},
"branchColorPatterns": {
"$ref": "#/$defs/ColorPatterns",
"description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color"
},
"customIcons": {
"$ref": "#/$defs/CustomIconsConfig",
"description": "Custom icons for filenames and file extensions\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-files-icon--color"
@@ -3807,6 +3796,17 @@
"default": [
"default"
]
},
"authorColors": {
"additionalProperties": {
"type": "string"
},
"type": "object",
"description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-author-color"
},
"branchColorPatterns": {
"$ref": "#/$defs/ColorPatterns",
"description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color"
}
},
"additionalProperties": false,