mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-11 04:15:48 +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:
parent
1eb00d8d14
commit
8ec37f80b7
8 changed files with 105 additions and 9 deletions
|
@ -43,6 +43,15 @@ gui:
|
||||||
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
|
# See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
|
||||||
branchColorPatterns: {}
|
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
|
# The number of lines you scroll by when scrolling the main window
|
||||||
scrollHeight: 2
|
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.
|
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
|
## Example Coloring
|
||||||
|
|
||||||

|

|
||||||
|
|
|
@ -57,6 +57,9 @@ type GuiConfig struct {
|
||||||
BranchColors map[string]string `yaml:"branchColors" jsonschema:"deprecated"`
|
BranchColors map[string]string `yaml:"branchColors" jsonschema:"deprecated"`
|
||||||
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
|
// See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color
|
||||||
BranchColorPatterns map[string]string `yaml:"branchColorPatterns"`
|
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
|
// The number of lines you scroll by when scrolling the main window
|
||||||
ScrollHeight int `yaml:"scrollHeight" jsonschema:"minimum=1"`
|
ScrollHeight int `yaml:"scrollHeight" jsonschema:"minimum=1"`
|
||||||
// If true, allow scrolling past the bottom of the content in the main window
|
// 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"`
|
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 {
|
func GetDefaultConfig() *UserConfig {
|
||||||
return &UserConfig{
|
return &UserConfig{
|
||||||
Gui: GuiConfig{
|
Gui: GuiConfig{
|
||||||
|
|
|
@ -39,7 +39,7 @@ func NewCommitFilesContext(c *ContextCommon) *CommitFilesContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
showFileIcons := icons.IsIconEnabled() && c.UserConfig().Gui.ShowFileIcons
|
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 lo.Map(lines, func(line string, _ int) []string {
|
||||||
return []string{line}
|
return []string{line}
|
||||||
})
|
})
|
||||||
|
|
|
@ -31,7 +31,7 @@ func NewWorkingTreeContext(c *ContextCommon) *WorkingTreeContext {
|
||||||
getDisplayStrings := func(_ int, _ int) [][]string {
|
getDisplayStrings := func(_ int, _ int) [][]string {
|
||||||
showFileIcons := icons.IsIconEnabled() && c.UserConfig().Gui.ShowFileIcons
|
showFileIcons := icons.IsIconEnabled() && c.UserConfig().Gui.ShowFileIcons
|
||||||
showNumstat := c.UserConfig().Gui.ShowNumstatInFilesView
|
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 lo.Map(lines, func(line string, _ int) []string {
|
||||||
return []string{line}
|
return []string{line}
|
||||||
})
|
})
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"github.com/gookit/color"
|
"github.com/gookit/color"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
"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/filetree"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
|
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
"github.com/jesseduffield/lazygit/pkg/gui/style"
|
||||||
|
@ -23,12 +24,13 @@ func RenderFileTree(
|
||||||
submoduleConfigs []*models.SubmoduleConfig,
|
submoduleConfigs []*models.SubmoduleConfig,
|
||||||
showFileIcons bool,
|
showFileIcons bool,
|
||||||
showNumstat bool,
|
showNumstat bool,
|
||||||
|
customIconsConfig *config.CustomIconsConfig,
|
||||||
) []string {
|
) []string {
|
||||||
collapsedPaths := tree.CollapsedPaths()
|
collapsedPaths := tree.CollapsedPaths()
|
||||||
return renderAux(tree.GetRoot().Raw(), collapsedPaths, -1, -1, func(node *filetree.Node[models.File], treeDepth int, visualDepth int, isCollapsed bool) string {
|
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)
|
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,
|
tree *filetree.CommitFileTreeViewModel,
|
||||||
patchBuilder *patch.PatchBuilder,
|
patchBuilder *patch.PatchBuilder,
|
||||||
showFileIcons bool,
|
showFileIcons bool,
|
||||||
|
customIconsConfig *config.CustomIconsConfig,
|
||||||
) []string {
|
) []string {
|
||||||
collapsedPaths := tree.CollapsedPaths()
|
collapsedPaths := tree.CollapsedPaths()
|
||||||
return renderAux(tree.GetRoot().Raw(), collapsedPaths, -1, -1, func(node *filetree.Node[models.CommitFile], treeDepth int, visualDepth int, isCollapsed bool) string {
|
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)
|
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,
|
showFileIcons bool,
|
||||||
submoduleConfigs []*models.SubmoduleConfig,
|
submoduleConfigs []*models.SubmoduleConfig,
|
||||||
node *filetree.Node[models.File],
|
node *filetree.Node[models.File],
|
||||||
|
customIconsConfig *config.CustomIconsConfig,
|
||||||
) string {
|
) string {
|
||||||
name := fileNameAtDepth(node, treeDepth)
|
name := fileNameAtDepth(node, treeDepth)
|
||||||
output := ""
|
output := ""
|
||||||
|
@ -156,7 +160,7 @@ func getFileLine(
|
||||||
isDirectory := file == nil
|
isDirectory := file == nil
|
||||||
|
|
||||||
if showFileIcons {
|
if showFileIcons {
|
||||||
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory)
|
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory, customIconsConfig)
|
||||||
paint := color.HEX(icon.Color, false)
|
paint := color.HEX(icon.Color, false)
|
||||||
output += paint.Sprint(icon.Icon) + nameColor.Sprint(" ")
|
output += paint.Sprint(icon.Icon) + nameColor.Sprint(" ")
|
||||||
}
|
}
|
||||||
|
@ -218,6 +222,7 @@ func getCommitFileLine(
|
||||||
node *filetree.Node[models.CommitFile],
|
node *filetree.Node[models.CommitFile],
|
||||||
status patch.PatchStatus,
|
status patch.PatchStatus,
|
||||||
showFileIcons bool,
|
showFileIcons bool,
|
||||||
|
customIconsConfig *config.CustomIconsConfig,
|
||||||
) string {
|
) string {
|
||||||
indentation := strings.Repeat(" ", visualDepth)
|
indentation := strings.Repeat(" ", visualDepth)
|
||||||
name := commitFileNameAtDepth(node, treeDepth)
|
name := commitFileNameAtDepth(node, treeDepth)
|
||||||
|
@ -266,7 +271,7 @@ func getCommitFileLine(
|
||||||
isLinkedWorktree := false
|
isLinkedWorktree := false
|
||||||
|
|
||||||
if showFileIcons {
|
if showFileIcons {
|
||||||
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory)
|
icon := icons.IconForFile(name, isSubmodule, isLinkedWorktree, isDirectory, customIconsConfig)
|
||||||
paint := color.HEX(icon.Color, false)
|
paint := color.HEX(icon.Color, false)
|
||||||
output += paint.Sprint(icon.Icon) + " "
|
output += paint.Sprint(icon.Icon) + " "
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"github.com/gookit/color"
|
"github.com/gookit/color"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/patch"
|
"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/filetree"
|
||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
|
@ -91,7 +92,7 @@ func TestRenderFileTree(t *testing.T) {
|
||||||
for _, path := range s.collapsedPaths {
|
for _, path := range s.collapsedPaths {
|
||||||
viewModel.ToggleCollapsed(path)
|
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)
|
assert.EqualValues(t, s.expected, result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -161,7 +162,7 @@ func TestRenderCommitFileTree(t *testing.T) {
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
patchBuilder.Start("from", "to", false, false)
|
patchBuilder.Start("from", "to", false, false)
|
||||||
result := RenderCommitFileTree(viewModel, patchBuilder, false)
|
result := RenderCommitFileTree(viewModel, patchBuilder, false, &config.CustomIconsConfig{})
|
||||||
assert.EqualValues(t, s.expected, result)
|
assert.EqualValues(t, s.expected, result)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,8 @@ package icons
|
||||||
import (
|
import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NOTE: Visit next links for inspiration:
|
// NOTE: Visit next links for inspiration:
|
||||||
|
@ -763,13 +765,19 @@ func patchFileIconsForNerdFontsV2() {
|
||||||
extIconMap[".vue"] = IconProperties{Icon: "\ufd42", Color: "#89e051"} // ﵂
|
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)
|
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 {
|
if icon, ok := nameIconMap[base]; ok {
|
||||||
return icon
|
return icon
|
||||||
}
|
}
|
||||||
|
|
||||||
ext := strings.ToLower(filepath.Ext(name))
|
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 {
|
if icon, ok := extIconMap[ext]; ok {
|
||||||
return icon
|
return icon
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,6 +263,27 @@
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
"type": "object"
|
"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": {
|
"GitConfig": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"paging": {
|
"paging": {
|
||||||
|
@ -404,6 +425,10 @@
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "See https://github.com/jesseduffield/lazygit/blob/master/docs/Config.md#custom-branch-color"
|
"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": {
|
"scrollHeight": {
|
||||||
"type": "integer",
|
"type": "integer",
|
||||||
"minimum": 1,
|
"minimum": 1,
|
||||||
|
@ -700,6 +725,18 @@
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"description": "Config relating to the Lazygit UI"
|
"description": "Config relating to the Lazygit UI"
|
||||||
},
|
},
|
||||||
|
"IconProperties": {
|
||||||
|
"properties": {
|
||||||
|
"icon": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"color": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"type": "object"
|
||||||
|
},
|
||||||
"KeybindingAmendAttributeConfig": {
|
"KeybindingAmendAttributeConfig": {
|
||||||
"properties": {
|
"properties": {
|
||||||
"resetAuthor": {
|
"resetAuthor": {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue