diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2022-05-01 12:21:32 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-01 12:21:32 +1000 |
commit | d85f4792af2a760fe07251e66e286e5a6929c26d (patch) | |
tree | c25977fa3283f8f515c9e0cf36532af4fb20a69b /pkg/gui | |
parent | babb9d86567593bb0707570d3105d1010bf8aca9 (diff) | |
parent | 5524f007f3b32dcb0b88175c7c51b4c069d1c544 (diff) |
Merge pull request #1894 from Ryooooooga/feature/icons
Diffstat (limited to 'pkg/gui')
-rw-r--r-- | pkg/gui/gui.go | 2 | ||||
-rw-r--r-- | pkg/gui/presentation/branches.go | 10 | ||||
-rw-r--r-- | pkg/gui/presentation/commits.go | 6 | ||||
-rw-r--r-- | pkg/gui/presentation/files.go | 26 | ||||
-rw-r--r-- | pkg/gui/presentation/icons/file_icons.go | 331 | ||||
-rw-r--r-- | pkg/gui/presentation/icons/git_icons.go | 61 | ||||
-rw-r--r-- | pkg/gui/presentation/icons/icons.go | 11 | ||||
-rw-r--r-- | pkg/gui/presentation/remote_branches.go | 8 | ||||
-rw-r--r-- | pkg/gui/presentation/remotes.go | 8 | ||||
-rw-r--r-- | pkg/gui/presentation/tags.go | 8 |
10 files changed, 461 insertions, 10 deletions
diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 23b8ae8ca..f2dd1c3f4 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -28,6 +28,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/gui/presentation" "github.com/jesseduffield/lazygit/pkg/gui/presentation/authors" "github.com/jesseduffield/lazygit/pkg/gui/presentation/graph" + "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/gui/services/custom_commands" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/gui/types" @@ -479,6 +480,7 @@ func NewGui( gui.c = helperCommon authors.SetCustomAuthors(gui.UserConfig.Gui.AuthorColors) + icons.SetIconEnabled(gui.UserConfig.Gui.ShowIcons) presentation.SetCustomBranches(gui.UserConfig.Gui.BranchColors) return gui, nil diff --git a/pkg/gui/presentation/branches.go b/pkg/gui/presentation/branches.go index b7d8b0270..7d68b04d5 100644 --- a/pkg/gui/presentation/branches.go +++ b/pkg/gui/presentation/branches.go @@ -6,6 +6,7 @@ import ( "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/i18n" "github.com/jesseduffield/lazygit/pkg/theme" @@ -42,9 +43,14 @@ func getBranchDisplayStrings(b *models.Branch, fullDescription bool, diffed bool recencyColor = style.FgGreen } - res := []string{recencyColor.Sprint(b.Recency), coloredName} + res := make([]string, 0, 4) + res = append(res, recencyColor.Sprint(b.Recency)) + if icons.IsIconEnabled() { + res = append(res, nameTextStyle.Sprint(icons.IconForBranch(b))) + } + res = append(res, coloredName) if fullDescription { - return append( + res = append( res, fmt.Sprintf("%s %s", style.FgYellow.Sprint(b.UpstreamRemote), diff --git a/pkg/gui/presentation/commits.go b/pkg/gui/presentation/commits.go index 7ec4e78af..59802dabf 100644 --- a/pkg/gui/presentation/commits.go +++ b/pkg/gui/presentation/commits.go @@ -9,6 +9,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/presentation/authors" "github.com/jesseduffield/lazygit/pkg/gui/presentation/graph" + "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/theme" "github.com/jesseduffield/lazygit/pkg/utils" @@ -275,7 +276,10 @@ func displayCommit( authorFunc = authors.LongAuthor } - cols := make([]string, 0, 5) + cols := make([]string, 0, 7) + if icons.IsIconEnabled() { + cols = append(cols, shaColor.Sprint(icons.IconForCommit(commit))) + } cols = append(cols, shaColor.Sprint(commit.ShortSha())) cols = append(cols, bisectString) if fullDescription { diff --git a/pkg/gui/presentation/files.go b/pkg/gui/presentation/files.go index b095975ad..cb4d19cec 100644 --- a/pkg/gui/presentation/files.go +++ b/pkg/gui/presentation/files.go @@ -6,6 +6,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/patch" "github.com/jesseduffield/lazygit/pkg/gui/filetree" + "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/theme" "github.com/jesseduffield/lazygit/pkg/utils" @@ -154,9 +155,16 @@ func getFileLine(hasUnstagedChanges bool, hasStagedChanges bool, name string, di output += restColor.Sprint(" ") } + isSubmodule := file != nil && file.IsSubmodule(submoduleConfigs) + isDirectory := file == nil + + if icons.IsIconEnabled() { + output += restColor.Sprintf("%s ", icons.IconForFile(name, isSubmodule, isDirectory)) + } + output += restColor.Sprint(utils.EscapeSpecialChars(name)) - if file != nil && file.IsSubmodule(submoduleConfigs) { + if isSubmodule { output += theme.DefaultTextColor.Sprint(" (submodule)") } @@ -178,12 +186,22 @@ func getCommitFileLine(name string, diffName string, commitFile *models.CommitFi } } + output := "" + name = utils.EscapeSpecialChars(name) - if commitFile == nil { - return colour.Sprint(name) + if commitFile != nil { + output += getColorForChangeStatus(commitFile.ChangeStatus).Sprint(commitFile.ChangeStatus) + " " } - return getColorForChangeStatus(commitFile.ChangeStatus).Sprint(commitFile.ChangeStatus) + " " + colour.Sprint(name) + isSubmodule := false + isDirectory := commitFile == nil + + if icons.IsIconEnabled() { + output += colour.Sprintf("%s ", icons.IconForFile(name, isSubmodule, isDirectory)) + } + + output += colour.Sprint(name) + return output } func getColorForChangeStatus(changeStatus string) style.TextStyle { diff --git a/pkg/gui/presentation/icons/file_icons.go b/pkg/gui/presentation/icons/file_icons.go new file mode 100644 index 000000000..e3f2b68eb --- /dev/null +++ b/pkg/gui/presentation/icons/file_icons.go @@ -0,0 +1,331 @@ +package icons + +import ( + "path/filepath" +) + +// https://github.com/ogham/exa/blob/master/src/output/icons.rs +const ( + DEFAULT_FILE_ICON = "\uf15b" // + DEFAULT_SUBMODULE_ICON = "\uf1d3" // + DEFAULT_DIRECTORY_ICON = "\uf114" // +) + +var nameIconMap = map[string]string{ + ".Trash": "\uf1f8", // + ".atom": "\ue764", // + ".bashprofile": "\ue615", // + ".bashrc": "\uf489", // + ".idea": "\ue7b5", // + ".git": "\uf1d3", // + ".gitattributes": "\uf1d3", // + ".gitconfig": "\uf1d3", // + ".github": "\uf408", // + ".gitignore": "\uf1d3", // + ".gitmodules": "\uf1d3", // + ".rvm": "\ue21e", // + ".vimrc": "\ue62b", // + ".vscode": "\ue70c", // + ".zshrc": "\uf489", // + "Cargo.lock": "\ue7a8", // + "Cargo.toml": "\ue7a8", // + "bin": "\ue5fc", // + "config": "\ue5fc", // + "docker-compose.yml": "\uf308", // + "Dockerfile": "\uf308", // + "ds_store": "\uf179", // + "gitignore_global": "\uf1d3", // + "go.mod": "\ue626", // + "go.sum": "\ue626", // + "gradle": "\ue256", // + "gruntfile.coffee": "\ue611", // + "gruntfile.js": "\ue611", // + "gruntfile.ls": "\ue611", // + "gulpfile.coffee": "\ue610", // + "gulpfile.js": "\ue610", // + "gulpfile.ls": "\ue610", // + "hidden": "\uf023", // + "include": "\ue5fc", // + "lib": "\uf121", // + "localized": "\uf179", // + "Makefile": "\uf489", // + "node_modules": "\ue718", // + "npmignore": "\ue71e", // + "PKGBUILD": "\uf303", // + "rubydoc": "\ue73b", // + "yarn.lock": "\ue718", // +} + +var extIconMap = map[string]string{ + ".ai": "\ue7b4", // + ".android": "\ue70e", // + ".apk": "\ue70e", // + ".apple": "\uf179", // + ".avi": "\uf03d", // + ".avif": "\uf1c5", // + ".avro": "\ue60b", // + ".awk": "\uf489", // + ".bash": "\uf489", // + ".bash_history": "\uf489", // + ".bash_profile": "\uf489", // + ".bashrc": "\uf489", // + ".bat": "\uf17a", // + ".bats": "\uf489", // + ".bmp": "\uf1c5", // + ".bz": "\uf410", // + ".bz2": "\uf410", // + ".c": "\ue61e", // + ".c++": "\ue61d", // + ".cab": "\ue70f", // + ".cc": "\ue61d", // + ".cfg": "\ue615", // + ".class": "\ue256", // + ".clj": "\ue768", // + ".cljs": "\ue76a", // + ".cls": "\uf034", // + ".cmd": "\ue70f", // + ".coffee": "\uf0f4", // + ".conf": "\ue615", // + ".cp": "\ue61d", // + ".cpio": "\uf410", // + ".cpp": "\ue61d", // + ".cs": "\uf81a", // + ".csh": "\uf489", // + ".cshtml": "\uf1fa", // + ".csproj": "\uf81a", // + ".css": "\ue749", // + ".csv": "\uf1c3", // + ".csx": "\uf81a", // + ".cxx": "\ue61d", // + ".d": "\ue7af", // + ".dart": "\ue798", // + ".db": "\uf1c0", // + ".deb": "\ue77d", // + ".diff": "\uf440", // + ".djvu": "\uf02d", // + ".dll": "\ue70f", // + ".doc": "\uf1c2", // + ".docx": "\uf1c2", // + ".ds_store": "\uf179", // + ".DS_store": "\uf179", // + ".dump": "\uf1c0", // + ".ebook": "\ue28b", // + ".ebuild": "\uf30d", // + ".editorconfig": "\ue615", // + ".ejs": "\ue618", // + ".elm": "\ue62c", // + ".env": "\uf462", // + ".eot": "\uf031", // + ".epub": "\ue28a", // + ".erb": "\ue73b", // + ".erl": "\ue7b1", // + ".ex": "\ue62d", // + ".exe": "\uf17a", // + ".exs": "\ue62d", // + ".fish": "\uf489", // + ".flac": "\uf001", // + ".flv": "\uf03d", // + ".font": "\uf031", // + ".fs": "\ue7a7", // + ".fsi": "\ue7a7", // + ".fsx": "\ue7a7", // + ".gdoc": "\uf1c2", // + ".gem": "\ue21e", // + ".gemfile": "\ue21e", // + ".gemspec": "\ue21e", // + ".gform": "\uf298", // + ".gif": "\uf1c5", // + ".git": "\uf1d3", // + ".gitattributes": "\uf1d3", // + ".gitignore": "\uf1d3", // + ".gitmodules": "\uf1d3", // + ".go": "\ue626", // + ".gradle": "\ue256", // + ".groovy": "\ue775", // + ".gsheet": "\uf1c3", // + ".gslides": "\uf1c4", // + ".guardfile": "\ue21e", // + ".gz": "\uf410", // + ".h": "\uf0fd", // + ".hbs": "\ue60f", // + ".hpp": "\uf0fd", // + ".hs": "\ue777", // + ".htm": "\uf13b", // + ".html": "\uf13b", // + ".hxx": "\uf0fd", // + ".ico": "\uf1c5", // + ".image": "\uf1c5", // + ".iml": "\ue7b5", // + ".ini": "\uf17a", // + ".ipynb": "\ue606", // + ".iso": "\ue271", // + ".j2c": "\uf1c5", // + ".j2k": "\uf1c5", // + ".jad": "\ue256", // + ".jar": "\ue256", // + ".java": "\ue256", // + ".jfi": "\uf1c5", // + ".jfif": "\uf1c5", // + ".jif": "\uf1c5", // + ".jl": "\ue624", // + ".jmd": "\uf48a", // + ".jp2": "\uf1c5", // + ".jpe": "\uf1c5", // + ".jpeg": "\uf1c5", // + ".jpg": "\uf1c5", // + ".jpx": "\uf1c5", // + ".js": "\ue74e", // + ".json": "\ue60b", // + ".jsx": "\ue7ba", // + ".jxl": "\uf1c5", // + ".ksh": "\uf489", // + ".latex": "\uf034", // + ".less": "\ue758", // + ".lhs": "\ue777", // + ".license": "\uf718", // + ".localized": "\uf179", // + ".lock": "\uf023", // + ".log": "\uf18d", // + ".lua": "\ue620", // + ".lz": "\uf410", // + ".lz4": "\uf410", // + ".lzh": "\uf410", // + ".lzma": "\uf410", // + ".lzo": "\uf410", // + ".m": "\ue61e", // + ".mm": "\ue61d", // + ".m4a": "\uf001", // + ".markdown": "\uf48a", // + ".md": "\uf48a", // + ".mjs": "\ue74e", // + ".mk": "\uf489", // + ".mkd": "\uf48a", // + ".mkv": "\uf03d", // + ".mobi": "\ue28b", // + ".mov": "\uf03d", // + ".mp3": "\uf001", // + ".mp4": "\uf03d", // + ".msi": "\ue70f", // + ".mustache": "\ue60f", // + ".nix": "\uf313", // + ".node": "\uf898", // + ".npmignore": "\ue71e", // + ".odp": "\uf1c4", // + ".ods": "\uf1c3", // + ".odt": "\uf1c2", // + ".ogg": "\uf001", // + ".ogv": "\uf03d", // + ".otf": "\uf031", // + ".part": "\uf43a", // + ".patch": "\uf440", // + ".pdf": "\uf1c1", // + ".php": "\ue73d", // + ".pl": "\ue769", // + ".png": "\uf1c5", // + ".ppt": "\uf1c4", // + ".pptx": "\uf1c4", // + ".procfile": "\ue21e", // + ".properties": "\ue60b", // + ".ps1": "\uf489", // + ".psd": "\ue7b8", // + ".pxm": "\uf1c5", // + ".py": "\ue606", // + ".pyc": "\ue606", // + ".r": "\uf25d", // + ".rakefile": "\ue21e", // + ".rar": "\uf410", // + ".razor": "\uf1fa", // + ".rb": "\ue21e", // + ".rdata": "\uf25d", // + ".rdb": "\ue76d", // + ".rdoc": "\uf48a", // + ".rds": "\uf25d", // + ".readme": "\uf48a", // + ".rlib": "\ue7a8", // + ".rmd": "\uf48a", // + ".rpm": "\ue7bb", // + ".rs": "\ue7a8", // + ".rspec": "\ue21e", // + ".rspec_parallel": "\ue21e", // + ".rspec_status": "\ue21e", // + ".rss": "\uf09e", // + ".rtf": "\uf718", // + ".ru": "\ue21e", // + ".rubydoc": "\ue73b", // + ".sass": "\ue603", // + ".scala": "\ue737", // + ".scss": "\ue749", // + ".sh": "\uf489", // + ".shell": "\uf489", // + ".slim": "\ue73b", // + ".sln": "\ue70c", // + ".so": "\uf17c", // + ".sql": "\uf1c0", // + ".sqlite3": "\ue7c4", // + ".sty": "\uf034", // + ".styl": "\ue600", // + ".stylus": "\ue600", // + ".svg": "\uf1c5", // + ".swift": "\ue755", // + ".tar": "\uf410", // + ".taz": "\uf410", // + ".tbz": "\uf410", // + ".tbz2": "\uf410", // + ".tex": "\uf034", // + ".tgz": "\uf410", // + ".tiff": "\uf1c5", // + ".tlz": "\uf410", // + ".toml": "\ue615", // + ".torrent": "\ue275", // + ".ts": "\ue628", // + ".tsv": "\uf1c3", // + ".tsx": "\ue7ba", // + ".ttf": "\uf031", // + ".twig": "\ue61c", // + ".txt": "\uf15c", // + ".txz": "\uf410", // + ".tz": "\uf410", // + ".tzo": "\uf410", // + ".video": "\uf03d", // + ".vim": "\ue62b", // + ".vue": "\ufd42", // ﵂ + ".war": "\ue256", // + ".wav": "\uf001", // + ".webm": "\uf03d", // + ".webp": "\uf1c5", // + ".windows": "\uf17a", // + ".woff": "\uf031", // + ".woff2": "\uf031", // + ".xhtml": "\uf13b", // + ".xls": "\uf1c3", // + ".xlsx": "\uf1c3", // + ".xml": "\uf121", // + ".xul": "\uf121", // + ".xz": "\uf410", // + ".yaml": "\uf481", // + ".yml": "\uf481", // + ".zip": "\uf410", // + ".zsh": "\uf489", // + ".zsh-theme": "\uf489", // + ".zshrc": "\uf489", // + ".zst": "\uf410", // +} + +func IconForFile(name string, isSubmodule bool, isDirectory bool) string { + base := filepath.Base(name) + if icon, ok := nameIconMap[base]; ok { + return icon + } + + ext := filepath.Ext(name) + if icon, ok := extIconMap[ext]; ok { + return icon + } + + if isSubmodule { + return DEFAULT_SUBMODULE_ICON + } else if isDirectory { + return DEFAULT_DIRECTORY_ICON + } + return DEFAULT_FILE_ICON +} diff --git a/pkg/gui/presentation/icons/git_icons.go b/pkg/gui/presentation/icons/git_icons.go new file mode 100644 index 000000000..0f891d7bd --- /dev/null +++ b/pkg/gui/presentation/icons/git_icons.go @@ -0,0 +1,61 @@ +package icons + +import ( + "strings" + + "github.com/jesseduffield/lazygit/pkg/commands/models" +) + +const ( + BRANCH_ICON = "\ufb2b" // שׂ + DETACHED_HEAD_ICON = "\ue729" // + TAG_ICON = "\uf02b" // + COMMIT_ICON = "\ufc16" // ﰖ + MERGE_COMMIT_ICON = "\ufb2c" // שּׁ + DEFAULT_REMOTE_ICON = "\uf7a1" // +) + +type remoteIcon struct { + domain string + icon string +} + +var remoteIcons = []remoteIcon{ + {domain: "github.com", icon: "\ue709"}, // + {domain: "bitbucket.org", icon: "\ue703"}, // + {domain: "gitlab.com", icon: "\uf296"}, // + {domain: "dev.azure.com", icon: "\ufd03"}, // ﴃ +} + +func IconForBranch(branch *models.Branch) string { + if branch.DisplayName != "" { + return DETACHED_HEAD_ICON + } + return BRANCH_ICON +} + +func IconForRemoteBranch(branch *models.RemoteBranch) string { + return BRANCH_ICON +} + +func IconForTag(tag *models.Tag) string { + return TAG_ICON +} + +func IconForCommit(commit *models.Commit) string { + if len(commit.Parents) > 1 { + return MERGE_COMMIT_ICON + } + return COMMIT_ICON +} + +func IconForRemote(remote *models.Remote) string { + for _, r := range remoteIcons { + for _, url := range remote.Urls { + if strings.Contains(url, r.domain) { + return r.icon + } + } + } + return DEFAULT_REMOTE_ICON +} diff --git a/pkg/gui/presentation/icons/icons.go b/pkg/gui/presentation/icons/icons.go new file mode 100644 index 000000000..81b16108b --- /dev/null +++ b/pkg/gui/presentation/icons/icons.go @@ -0,0 +1,11 @@ +package icons + +var isIconEnabled = false + +func IsIconEnabled() bool { + return isIconEnabled +} + +func SetIconEnabled(showIcons bool) { + isIconEnabled = showIcons +} diff --git a/pkg/gui/presentation/remote_branches.go b/pkg/gui/presentation/remote_branches.go index c5c54dfcb..4052d3fed 100644 --- a/pkg/gui/presentation/remote_branches.go +++ b/pkg/gui/presentation/remote_branches.go @@ -3,6 +3,7 @@ package presentation import ( "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/theme" ) @@ -20,5 +21,10 @@ func getRemoteBranchDisplayStrings(b *models.RemoteBranch, diffed bool) []string textStyle = theme.DiffTerminalColor } - return []string{textStyle.Sprint(b.Name)} + res := make([]string, 0, 2) + if icons.IsIconEnabled() { + res = append(res, textStyle.Sprint(icons.IconForRemoteBranch(b))) + } + res = append(res, textStyle.Sprint(b.Name)) + return res } diff --git a/pkg/gui/presentation/remotes.go b/pkg/gui/presentation/remotes.go index 9b26cbfae..7f82fe970 100644 --- a/pkg/gui/presentation/remotes.go +++ b/pkg/gui/presentation/remotes.go @@ -3,6 +3,7 @@ package presentation import ( "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/theme" ) @@ -23,5 +24,10 @@ func getRemoteDisplayStrings(r *models.Remote, diffed bool) []string { textStyle = theme.DiffTerminalColor } - return []string{textStyle.Sprint(r.Name), style.FgBlue.Sprintf("%d branches", branchCount)} + res := make([]string, 0, 3) + if icons.IsIconEnabled() { + res = append(res, textStyle.Sprint(icons.IconForRemote(r))) + } + res = append(res, textStyle.Sprint(r.Name), style.FgBlue.Sprintf("%d branches", branchCount)) + return res } diff --git a/pkg/gui/presentation/tags.go b/pkg/gui/presentation/tags.go index 2157e29c9..2996db18d 100644 --- a/pkg/gui/presentation/tags.go +++ b/pkg/gui/presentation/tags.go @@ -3,6 +3,7 @@ package presentation import ( "github.com/jesseduffield/generics/slices" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/gui/presentation/icons" "github.com/jesseduffield/lazygit/pkg/theme" ) @@ -19,5 +20,10 @@ func getTagDisplayStrings(t *models.Tag, diffed bool) []string { if diffed { textStyle = theme.DiffTerminalColor } - return []string{textStyle.Sprint(t.Name)} + res := make([]string, 0, 2) + if icons.IsIconEnabled() { + res = append(res, textStyle.Sprint(icons.IconForTag(t))) + } + res = append(res, textStyle.Sprint(t.Name)) + return res } |