diff options
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | pkg/gui/presentation/commits.go | 75 | ||||
-rw-r--r-- | pkg/gui/presentation/commits_test.go | 17 | ||||
-rw-r--r-- | pkg/utils/slice.go | 7 | ||||
-rw-r--r-- | pkg/utils/slice_test.go | 48 |
5 files changed, 145 insertions, 4 deletions
@@ -29,7 +29,7 @@ require ( github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/kyokomi/emoji/v2 v2.2.8 - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 github.com/mattn/go-colorable v0.1.7 // indirect github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mgutz/str v1.2.0 diff --git a/pkg/gui/presentation/commits.go b/pkg/gui/presentation/commits.go index de1d168dc..1524734f2 100644 --- a/pkg/gui/presentation/commits.go +++ b/pkg/gui/presentation/commits.go @@ -1,13 +1,16 @@ package presentation import ( + "crypto/md5" "strings" + "github.com/gookit/color" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/gui/style" "github.com/jesseduffield/lazygit/pkg/theme" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/kyokomi/emoji/v2" + colorful "github.com/lucasb-eyer/go-colorful" ) func GetCommitListDisplayStrings(commits []*models.Commit, fullDescription bool, cherryPickedCommitShaMap map[string]bool, diffName string, parseEmoji bool) [][]string { @@ -60,8 +63,6 @@ func getFullDescriptionDisplayStringsForCommit(c *models.Commit, cherryPickedCom tagString = style.FgMagenta.SetBold().Sprint(c.ExtraInfo) + " " } - truncatedAuthor := utils.TruncateWithEllipsis(c.Author, 17) - name := c.Name if parseEmoji { name = emoji.Sprint(name) @@ -70,7 +71,7 @@ func getFullDescriptionDisplayStringsForCommit(c *models.Commit, cherryPickedCom return []string{ shaColor.Sprint(c.ShortSha()), secondColumnString, - style.FgYellow.Sprint(truncatedAuthor), + longAuthor(c.Author), tagString + theme.DefaultTextColor.Sprint(name), } } @@ -114,10 +115,78 @@ func getDisplayStringsForCommit(c *models.Commit, cherryPickedCommitShaMap map[s return []string{ shaColor.Sprint(c.ShortSha()), + shortAuthor(c.Author), actionString + tagString + theme.DefaultTextColor.Sprint(name), } } +var authorInitialCache = make(map[string]string) +var authorNameCache = make(map[string]string) + +func shortAuthor(authorName string) string { + if _, ok := authorInitialCache[authorName]; ok { + return authorInitialCache[authorName] + } + + initials := getInitials(authorName) + if initials == "" { + return "" + } + + value := authorColor(authorName).Sprint(initials) + authorInitialCache[authorName] = value + + return value +} + +func longAuthor(authorName string) string { + if _, ok := authorNameCache[authorName]; ok { + return authorNameCache[authorName] + } + + truncatedName := utils.TruncateWithEllipsis(authorName, 17) + value := authorColor(authorName).Sprint(truncatedName) + authorNameCache[authorName] = value + + return value +} + +func authorColor(authorName string) style.TextStyle { + hash := md5.Sum([]byte(authorName)) + c := colorful.Hsl(randFloat(hash[0:4])*360.0, 0.6+0.4*randFloat(hash[4:8]), 0.4+randFloat(hash[8:12])*0.2) + + return style.New().SetFg(style.NewRGBColor(color.RGB(uint8(c.R*255), uint8(c.G*255), uint8(c.B*255)))) +} + +func randFloat(hash []byte) float64 { + sum := 0 + for _, b := range hash { + sum = (sum + int(b)) % 100 + } + return float64(sum) / 100 +} + +var authorStyles = []style.TextStyle{ + style.FgGreen, + style.FgYellow, + style.FgMagenta, + style.FgCyan, + style.FgRed, +} + +func getInitials(authorName string) string { + if authorName == "" { + return authorName + } + + split := strings.Split(authorName, " ") + if len(split) == 1 { + return utils.LimitStr(authorName, 2) + } + + return split[0][0:1] + split[1][0:1] +} + func actionColorMap(str string) style.TextStyle { switch str { case "pick": diff --git a/pkg/gui/presentation/commits_test.go b/pkg/gui/presentation/commits_test.go new file mode 100644 index 000000000..78b798010 --- /dev/null +++ b/pkg/gui/presentation/commits_test.go @@ -0,0 +1,17 @@ +package presentation + +import "testing" + +func TestGetInitials(t *testing.T) { + for input, output := range map[string]string{ + "Jesse Duffield": "JD", + "Jesse Duffield Man": "JD", + "JesseDuffield": "Je", + "J": "J", + "": "", + } { + if output != getInitials(input) { + t.Errorf("Expected %s to be %s", input, output) + } + } +} diff --git a/pkg/utils/slice.go b/pkg/utils/slice.go index 48acdbd2d..0ee8dec66 100644 --- a/pkg/utils/slice.go +++ b/pkg/utils/slice.go @@ -144,3 +144,10 @@ func Reverse(values []string) []string { } return result } + +func LimitStr(value string, limit int) string { + if len(value) > limit { + return value[:limit] + } + return value +} diff --git a/pkg/utils/slice_test.go b/pkg/utils/slice_test.go index 3636f44cb..b5919b3e6 100644 --- a/pkg/utils/slice_test.go +++ b/pkg/utils/slice_test.go @@ -248,3 +248,51 @@ func TestReverse(t *testing.T) { } } } + +func TestLimitStr(t *testing.T) { + for _, test := range []struct { + values string + limit int + want string + }{ + { + values: "", + limit: 10, + want: "", + }, + { + values: "", + limit: 0, + want: "", + }, + { + values: "a", + limit: 1, + want: "a", + }, + { + values: "ab", + limit: 2, + want: "ab", + }, + { + values: "abc", + limit: 3, + want: "abc", + }, + { + values: "abcd", + limit: 3, + want: "abc", + }, + { + values: "abcde", + limit: 3, + want: "abc", + }, + } { + if got := LimitStr(test.values, test.limit); !assert.EqualValues(t, got, test.want) { + t.Errorf("LimitString(%v, %d) = %v; want %v", test.values, test.limit, got, test.want) + } + } +} |