Skip to content

Commit 8ec37f8

Browse files
Let users to define custom icons and color for files on the config file
Co-authored-by: Stefan Haller <stefan@haller-berlin.de>
1 parent 1eb00d8 commit 8ec37f8

File tree

8 files changed

+105
-9
lines changed

8 files changed

+105
-9
lines changed

docs/Config.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,15 @@ gui:
4343
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
4444
branchColorPatterns: {}
4545

46+
# Custom icons for filenames and file extensions
47+
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-files-icon--color
48+
customIcons:
49+
# Map of filenames to icon properties (icon and color)
50+
filenames: {}
51+
52+
# Map of file extensions (including the dot) to icon properties (icon and color)
53+
extensions: {}
54+
4655
# The number of lines you scroll by when scrolling the main window
4756
scrollHeight: 2
4857

@@ -841,6 +850,27 @@ gui:
841850

842851
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.
843852

853+
## Custom Files Icon & Color
854+
855+
You can customize the icon and color of files based on filenames or extensions:
856+
857+
```yaml
858+
gui:
859+
customIcons:
860+
filenames:
861+
"CONTRIBUTING.md": { icon: "\uede2", color: "#FEDDEF" }
862+
"HACKING.md": { icon: "\uede2", color: "#FEDDEF" }
863+
extensions:
864+
".cat":
865+
icon: "\U000f011b"
866+
color: "#BC4009"
867+
".dog":
868+
icon: "\U000f0a43"
869+
color: "#B6977E"
870+
```
871+
872+
Note that there is no support for regular expressions.
873+
844874
## Example Coloring
845875

846876
![border example](../../assets/colored-border-example.png)

pkg/config/user_config.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ type GuiConfig struct {
5757
BranchColors map[string]string `yaml:"branchColors" jsonschema:"deprecated"`
5858
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
5959
BranchColorPatterns map[string]string `yaml:"branchColorPatterns"`
60+
// Custom icons for filenames and file extensions
61+
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-files-icon--color
62+
CustomIcons CustomIconsConfig `yaml:"customIcons"`
6063
// The number of lines you scroll by when scrolling the main window
6164
ScrollHeight int `yaml:"scrollHeight" jsonschema:"minimum=1"`
6265
// If true, allow scrolling past the bottom of the content in the main window
@@ -707,6 +710,18 @@ type CustomCommandMenuOption struct {
707710
Value string `yaml:"value" jsonschema:"example=feature,minLength=1"`
708711
}
709712

713+
type CustomIconsConfig struct {
714+
// Map of filenames to icon properties (icon and color)
715+
Filenames map[string]IconProperties `yaml:"filenames"`
716+
// Map of file extensions (including the dot) to icon properties (icon and color)
717+
Extensions map[string]IconProperties `yaml:"extensions"`
718+
}
719+
720+
type IconProperties struct {
721+
Icon string `yaml:"icon"`
722+
Color string `yaml:"color"`
723+
}
724+
710725
func GetDefaultConfig() *UserConfig {
711726
return &UserConfig{
712727
Gui: GuiConfig{

pkg/gui/context/commit_files_context.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext {
3939
}
4040

4141
showFileIcons := icons.IsIconEnabled() && c.UserConfig().Gui.ShowFileIcons
42-
lines := presentation.RenderCommitFileTree(viewModel, c.Git().Patch.PatchBuilder, showFileIcons)
42+
lines := presentation.RenderCommitFileTree(viewModel, c.Git().Patch.PatchBuilder, showFileIcons, &c.UserConfig().Gui.CustomIcons)
4343
return lo.Map(lines, func(line string, _ int) []string {
4444
return []string{line}
4545
})

pkg/gui/context/working_tree_context.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ func NewWorkingTreeContext(c *ContextCommon) *WorkingTreeContext {
3131
getDisplayStrings := func(_ int, _ int) [][]string {
3232
showFileIcons := icons.IsIconEnabled() && c.UserConfig().Gui.ShowFileIcons
3333
showNumstat := c.UserConfig().Gui.ShowNumstatInFilesView
34-
lines := presentation.RenderFileTree(viewModel, c.Model().Submodules, showFileIcons, showNumstat)
34+
lines := presentation.RenderFileTree(viewModel, c.Model().Submodules, showFileIcons, showNumstat, &c.UserConfig().Gui.CustomIcons)
3535
return lo.Map(lines, func(line string, _ int) []string {
3636
return []string{line}
3737
})

pkg/gui/presentation/files.go

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"github.com/gookit/color"
77
"github.com/jesseduffield/lazygit/pkg/commands/models"
88
"github.com/jesseduffield/lazygit/pkg/commands/patch"
9+
"github.com/jesseduffield/lazygit/pkg/config"
910
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
1011
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
1112
"github.com/jesseduffield/lazygit/pkg/gui/style"
@@ -23,25 +24,27 @@ func RenderFileTree(
2324
submoduleConfigs []*models.SubmoduleConfig,
2425
showFileIcons bool,
2526
showNumstat bool,
27+
customIconsConfig *config.CustomIconsConfig,
2628
) []string {
2729
collapsedPaths := tree.CollapsedPaths()
2830
return renderAux(tree.GetRoot().Raw(), collapsedPaths, -1, -1, func(node *filetree.Node[models.File], treeDepth int, visualDepth int, isCollapsed bool) string {
2931
fileNode := filetree.NewFileNode(node)
3032

31-
return getFileLine(isCollapsed, fileNode.GetHasUnstagedChanges(), fileNode.GetHasStagedChanges(), treeDepth, visualDepth, showNumstat, showFileIcons, submoduleConfigs, node)
33+
return getFileLine(isCollapsed, fileNode.GetHasUnstagedChanges(), fileNode.GetHasStagedChanges(), treeDepth, visualDepth, showNumstat, showFileIcons, submoduleConfigs, node, customIconsConfig)
3234
})
3335
}
3436

3537
func RenderCommitFileTree(
3638
tree *filetree.CommitFileTreeViewModel,
3739
patchBuilder *patch.PatchBuilder,
3840
showFileIcons bool,
41+
customIconsConfig *config.CustomIconsConfig,
3942
) []string {
4043
collapsedPaths := tree.CollapsedPaths()
4144
return renderAux(tree.GetRoot().Raw(), collapsedPaths, -1, -1, func(node *filetree.Node[models.CommitFile], treeDepth int, visualDepth int, isCollapsed bool) string {
4245
status := commitFilePatchStatus(node, tree, patchBuilder)
4346

44-
return getCommitFileLine(isCollapsed, treeDepth, visualDepth, node, status, showFileIcons)
47+
return getCommitFileLine(isCollapsed, treeDepth, visualDepth, node, status, showFileIcons, customIconsConfig)
4548
})
4649
}
4750

@@ -116,6 +119,7 @@ func getFileLine(
116119
showFileIcons bool,
117120
submoduleConfigs []*models.SubmoduleConfig,
118121
node *filetree.Node[models.File],
122+
customIconsConfig *config.CustomIconsConfig,
119123
) string {
120124
name := fileNameAtDepth(node, treeDepth)
121125
output := ""
@@ -156,7 +160,7 @@ func getFileLine(
156160
isDirectory := file == nil
157161

158162
if showFileIcons {
159-
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory)
163+
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory, customIconsConfig)
160164
paint := color.HEX(icon.Color, false)
161165
output += paint.Sprint(icon.Icon) + nameColor.Sprint(" ")
162166
}
@@ -218,6 +222,7 @@ func getCommitFileLine(
218222
node *filetree.Node[models.CommitFile],
219223
status patch.PatchStatus,
220224
showFileIcons bool,
225+
customIconsConfig *config.CustomIconsConfig,
221226
) string {
222227
indentation := strings.Repeat(" ", visualDepth)
223228
name := commitFileNameAtDepth(node, treeDepth)
@@ -266,7 +271,7 @@ func getCommitFileLine(
266271
isLinkedWorktree := false
267272

268273
if showFileIcons {
269-
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory)
274+
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory, customIconsConfig)
270275
paint := color.HEX(icon.Color, false)
271276
output += paint.Sprint(icon.Icon) + " "
272277
}

pkg/gui/presentation/files_test.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"github.com/gookit/color"
88
"github.com/jesseduffield/lazygit/pkg/commands/models"
99
"github.com/jesseduffield/lazygit/pkg/commands/patch"
10+
"github.com/jesseduffield/lazygit/pkg/config"
1011
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
1112
"github.com/jesseduffield/lazygit/pkg/utils"
1213
"github.com/stretchr/testify/assert"
@@ -91,7 +92,7 @@ func TestRenderFileTree(t *testing.T) {
9192
for _, path := range s.collapsedPaths {
9293
viewModel.ToggleCollapsed(path)
9394
}
94-
result := RenderFileTree(viewModel, nil, false, s.showLineChanges)
95+
result := RenderFileTree(viewModel, nil, false, s.showLineChanges, &config.CustomIconsConfig{})
9596
assert.EqualValues(t, s.expected, result)
9697
})
9798
}
@@ -161,7 +162,7 @@ func TestRenderCommitFileTree(t *testing.T) {
161162
},
162163
)
163164
patchBuilder.Start("from", "to", false, false)
164-
result := RenderCommitFileTree(viewModel, patchBuilder, false)
165+
result := RenderCommitFileTree(viewModel, patchBuilder, false, &config.CustomIconsConfig{})
165166
assert.EqualValues(t, s.expected, result)
166167
})
167168
}

pkg/gui/presentation/icons/file_icons.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package icons
33
import (
44
"path/filepath"
55
"strings"
6+
7+
"github.com/jesseduffield/lazygit/pkg/config"
68
)
79

810
// NOTE: Visit next links for inspiration:
@@ -763,13 +765,19 @@ func patchFileIconsForNerdFontsV2() {
763765
extIconMap[".vue"] = IconProperties{Icon: "\ufd42", Color: "#89e051"} // ﵂
764766
}
765767

766-
func IconForFile(name string, isSubmodule bool, isLinkedWorktree bool, isDirectory bool) IconProperties {
768+
func IconForFile(name string, isSubmodule bool, isLinkedWorktree bool, isDirectory bool, customIconsConfig *config.CustomIconsConfig) IconProperties {
767769
base := filepath.Base(name)
770+
if icon, ok := customIconsConfig.Filenames[base]; ok {
771+
return IconProperties{Color: icon.Color, Icon: icon.Icon}
772+
}
768773
if icon, ok := nameIconMap[base]; ok {
769774
return icon
770775
}
771776

772777
ext := strings.ToLower(filepath.Ext(name))
778+
if icon, ok := customIconsConfig.Extensions[ext]; ok {
779+
return IconProperties{Color: icon.Color, Icon: icon.Icon}
780+
}
773781
if icon, ok := extIconMap[ext]; ok {
774782
return icon
775783
}

schema/config.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,27 @@
263263
"additionalProperties": false,
264264
"type": "object"
265265
},
266+
"CustomIconsConfig": {
267+
"properties": {
268+
"filenames": {
269+
"additionalProperties": {
270+
"$ref": "#/$defs/IconProperties"
271+
},
272+
"type": "object",
273+
"description": "Map of filenames to icon properties (icon and color)"
274+
},
275+
"extensions": {
276+
"additionalProperties": {
277+
"$ref": "#/$defs/IconProperties"
278+
},
279+
"type": "object",
280+
"description": "Map of file extensions (including the dot) to icon properties (icon and color)"
281+
}
282+
},
283+
"additionalProperties": false,
284+
"type": "object",
285+
"description": "Custom icons for filenames and file extensions\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-files-icon--color"
286+
},
266287
"GitConfig": {
267288
"properties": {
268289
"paging": {
@@ -404,6 +425,10 @@
404425
"type": "object",
405426
"description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color"
406427
},
428+
"customIcons": {
429+
"$ref": "#/$defs/CustomIconsConfig",
430+
"description": "Custom icons for filenames and file extensions\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-files-icon--color"
431+
},
407432
"scrollHeight": {
408433
"type": "integer",
409434
"minimum": 1,
@@ -700,6 +725,18 @@
700725
"type": "object",
701726
"description": "Config relating to the Lazygit UI"
702727
},
728+
"IconProperties": {
729+
"properties": {
730+
"icon": {
731+
"type": "string"
732+
},
733+
"color": {
734+
"type": "string"
735+
}
736+
},
737+
"additionalProperties": false,
738+
"type": "object"
739+
},
703740
"KeybindingAmendAttributeConfig": {
704741
"properties": {
705742
"resetAuthor": {

0 commit comments

Comments
 (0)