1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-04-04 22:34:39 +02:00

Let users to define custom icons and color for files on the config file

Co-authored-by: Stefan Haller <stefan@haller-berlin.de>
This commit is contained in:
hasecilu 2025-03-14 13:58:16 -06:00 committed by Stefan Haller
parent 1eb00d8d14
commit 8ec37f80b7
8 changed files with 105 additions and 9 deletions

View File

@ -43,6 +43,15 @@ gui:
# 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:
# Map of filenames to icon properties (icon and color)
filenames: {}
# Map of file extensions (including the dot) to icon properties (icon and color)
extensions: {}
# The number of lines you scroll by when scrolling the main window
scrollHeight: 2
@ -841,6 +850,27 @@ gui:
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.
## Custom Files Icon & Color
You can customize the icon and color of files based on filenames or extensions:
```yaml
gui:
customIcons:
filenames:
"CONTRIBUTING.md": { icon: "\uede2", color: "#FEDDEF" }
"HACKING.md": { icon: "\uede2", color: "#FEDDEF" }
extensions:
".cat":
icon: "\U000f011b"
color: "#BC4009"
".dog":
icon: "\U000f0a43"
color: "#B6977E"
```
Note that there is no support for regular expressions.
## Example Coloring
![border example](../../assets/colored-border-example.png)

View File

@ -57,6 +57,9 @@ type GuiConfig struct {
BranchColors map[string]string `yaml:"branchColors" jsonschema:"deprecated"`
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
BranchColorPatterns map[string]string `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"`
// The number of lines you scroll by when scrolling the main window
ScrollHeight int `yaml:"scrollHeight" jsonschema:"minimum=1"`
// If true, allow scrolling past the bottom of the content in the main window
@ -707,6 +710,18 @@ type CustomCommandMenuOption struct {
Value string `yaml:"value" jsonschema:"example=feature,minLength=1"`
}
type CustomIconsConfig struct {
// Map of filenames to icon properties (icon and color)
Filenames map[string]IconProperties `yaml:"filenames"`
// Map of file extensions (including the dot) to icon properties (icon and color)
Extensions map[string]IconProperties `yaml:"extensions"`
}
type IconProperties struct {
Icon string `yaml:"icon"`
Color string `yaml:"color"`
}
func GetDefaultConfig() *UserConfig {
return &UserConfig{
Gui: GuiConfig{

View File

@ -39,7 +39,7 @@ func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext {
}
showFileIcons := icons.IsIconEnabled() && c.UserConfig().Gui.ShowFileIcons
lines := presentation.RenderCommitFileTree(viewModel, c.Git().Patch.PatchBuilder, showFileIcons)
lines := presentation.RenderCommitFileTree(viewModel, c.Git().Patch.PatchBuilder, showFileIcons, &c.UserConfig().Gui.CustomIcons)
return lo.Map(lines, func(line string, _ int) []string {
return []string{line}
})

View File

@ -31,7 +31,7 @@ func NewWorkingTreeContext(c *ContextCommon) *WorkingTreeContext {
getDisplayStrings := func(_ int, _ int) [][]string {
showFileIcons := icons.IsIconEnabled() && c.UserConfig().Gui.ShowFileIcons
showNumstat := c.UserConfig().Gui.ShowNumstatInFilesView
lines := presentation.RenderFileTree(viewModel, c.Model().Submodules, showFileIcons, showNumstat)
lines := presentation.RenderFileTree(viewModel, c.Model().Submodules, showFileIcons, showNumstat, &c.UserConfig().Gui.CustomIcons)
return lo.Map(lines, func(line string, _ int) []string {
return []string{line}
})

View File

@ -6,6 +6,7 @@ import (
"github.com/gookit/color"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/patch"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
"github.com/jesseduffield/lazygit/pkg/gui/style"
@ -23,12 +24,13 @@ func RenderFileTree(
submoduleConfigs []*models.SubmoduleConfig,
showFileIcons bool,
showNumstat bool,
customIconsConfig *config.CustomIconsConfig,
) []string {
collapsedPaths := tree.CollapsedPaths()
return renderAux(tree.GetRoot().Raw(), collapsedPaths, -1, -1, func(node *filetree.Node[models.File], treeDepth int, visualDepth int, isCollapsed bool) string {
fileNode := filetree.NewFileNode(node)
return getFileLine(isCollapsed, fileNode.GetHasUnstagedChanges(), fileNode.GetHasStagedChanges(), treeDepth, visualDepth, showNumstat, showFileIcons, submoduleConfigs, node)
return getFileLine(isCollapsed, fileNode.GetHasUnstagedChanges(), fileNode.GetHasStagedChanges(), treeDepth, visualDepth, showNumstat, showFileIcons, submoduleConfigs, node, customIconsConfig)
})
}
@ -36,12 +38,13 @@ func RenderCommitFileTree(
tree *filetree.CommitFileTreeViewModel,
patchBuilder *patch.PatchBuilder,
showFileIcons bool,
customIconsConfig *config.CustomIconsConfig,
) []string {
collapsedPaths := tree.CollapsedPaths()
return renderAux(tree.GetRoot().Raw(), collapsedPaths, -1, -1, func(node *filetree.Node[models.CommitFile], treeDepth int, visualDepth int, isCollapsed bool) string {
status := commitFilePatchStatus(node, tree, patchBuilder)
return getCommitFileLine(isCollapsed, treeDepth, visualDepth, node, status, showFileIcons)
return getCommitFileLine(isCollapsed, treeDepth, visualDepth, node, status, showFileIcons, customIconsConfig)
})
}
@ -116,6 +119,7 @@ func getFileLine(
showFileIcons bool,
submoduleConfigs []*models.SubmoduleConfig,
node *filetree.Node[models.File],
customIconsConfig *config.CustomIconsConfig,
) string {
name := fileNameAtDepth(node, treeDepth)
output := ""
@ -156,7 +160,7 @@ func getFileLine(
isDirectory := file == nil
if showFileIcons {
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory)
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory, customIconsConfig)
paint := color.HEX(icon.Color, false)
output += paint.Sprint(icon.Icon) + nameColor.Sprint(" ")
}
@ -218,6 +222,7 @@ func getCommitFileLine(
node *filetree.Node[models.CommitFile],
status patch.PatchStatus,
showFileIcons bool,
customIconsConfig *config.CustomIconsConfig,
) string {
indentation := strings.Repeat(" ", visualDepth)
name := commitFileNameAtDepth(node, treeDepth)
@ -266,7 +271,7 @@ func getCommitFileLine(
isLinkedWorktree := false
if showFileIcons {
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory)
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory, customIconsConfig)
paint := color.HEX(icon.Color, false)
output += paint.Sprint(icon.Icon) + " "
}

View File

@ -7,6 +7,7 @@ import (
"github.com/gookit/color"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/commands/patch"
"github.com/jesseduffield/lazygit/pkg/config"
"github.com/jesseduffield/lazygit/pkg/gui/filetree"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/stretchr/testify/assert"
@ -91,7 +92,7 @@ func TestRenderFileTree(t *testing.T) {
for _, path := range s.collapsedPaths {
viewModel.ToggleCollapsed(path)
}
result := RenderFileTree(viewModel, nil, false, s.showLineChanges)
result := RenderFileTree(viewModel, nil, false, s.showLineChanges, &config.CustomIconsConfig{})
assert.EqualValues(t, s.expected, result)
})
}
@ -161,7 +162,7 @@ func TestRenderCommitFileTree(t *testing.T) {
},
)
patchBuilder.Start("from", "to", false, false)
result := RenderCommitFileTree(viewModel, patchBuilder, false)
result := RenderCommitFileTree(viewModel, patchBuilder, false, &config.CustomIconsConfig{})
assert.EqualValues(t, s.expected, result)
})
}

View File

@ -3,6 +3,8 @@ package icons
import (
"path/filepath"
"strings"
"github.com/jesseduffield/lazygit/pkg/config"
)
// NOTE: Visit next links for inspiration:
@ -763,13 +765,19 @@ func patchFileIconsForNerdFontsV2() {
extIconMap[".vue"] = IconProperties{Icon: "\ufd42", Color: "#89e051"} // ﵂
}
func IconForFile(name string, isSubmodule bool, isLinkedWorktree bool, isDirectory bool) IconProperties {
func IconForFile(name string, isSubmodule bool, isLinkedWorktree bool, isDirectory bool, customIconsConfig *config.CustomIconsConfig) IconProperties {
base := filepath.Base(name)
if icon, ok := customIconsConfig.Filenames[base]; ok {
return IconProperties{Color: icon.Color, Icon: icon.Icon}
}
if icon, ok := nameIconMap[base]; ok {
return icon
}
ext := strings.ToLower(filepath.Ext(name))
if icon, ok := customIconsConfig.Extensions[ext]; ok {
return IconProperties{Color: icon.Color, Icon: icon.Icon}
}
if icon, ok := extIconMap[ext]; ok {
return icon
}

View File

@ -263,6 +263,27 @@
"additionalProperties": false,
"type": "object"
},
"CustomIconsConfig": {
"properties": {
"filenames": {
"additionalProperties": {
"$ref": "#/$defs/IconProperties"
},
"type": "object",
"description": "Map of filenames to icon properties (icon and color)"
},
"extensions": {
"additionalProperties": {
"$ref": "#/$defs/IconProperties"
},
"type": "object",
"description": "Map of file extensions (including the dot) to icon properties (icon and color)"
}
},
"additionalProperties": false,
"type": "object",
"description": "Custom icons for filenames and file extensions\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-files-icon--color"
},
"GitConfig": {
"properties": {
"paging": {
@ -404,6 +425,10 @@
"type": "object",
"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"
},
"scrollHeight": {
"type": "integer",
"minimum": 1,
@ -700,6 +725,18 @@
"type": "object",
"description": "Config relating to the Lazygit UI"
},
"IconProperties": {
"properties": {
"icon": {
"type": "string"
},
"color": {
"type": "string"
}
},
"additionalProperties": false,
"type": "object"
},
"KeybindingAmendAttributeConfig": {
"properties": {
"resetAuthor": {