From 7561703e8d9cadd3cae72ab5d9f1d23b5df362bc Mon Sep 17 00:00:00 2001 From: Jesse Duffield Date: Sat, 30 Oct 2021 17:42:43 +1100 Subject: move author name colouring code into its own file --- pkg/gui/presentation/authors/authors.go | 103 +++++++++++++++++++++++++++ pkg/gui/presentation/authors/authors_test.go | 20 ++++++ pkg/gui/presentation/commits.go | 82 +-------------------- pkg/gui/presentation/commits_test.go | 20 ------ 4 files changed, 126 insertions(+), 99 deletions(-) create mode 100644 pkg/gui/presentation/authors/authors.go create mode 100644 pkg/gui/presentation/authors/authors_test.go delete mode 100644 pkg/gui/presentation/commits_test.go (limited to 'pkg/gui') diff --git a/pkg/gui/presentation/authors/authors.go b/pkg/gui/presentation/authors/authors.go new file mode 100644 index 000000000..8040a8d4b --- /dev/null +++ b/pkg/gui/presentation/authors/authors.go @@ -0,0 +1,103 @@ +package authors + +import ( + "crypto/md5" + "strings" + + "github.com/gookit/color" + "github.com/jesseduffield/lazygit/pkg/gui/style" + "github.com/jesseduffield/lazygit/pkg/utils" + "github.com/lucasb-eyer/go-colorful" + "github.com/mattn/go-runewidth" +) + +var authorInitialCache = make(map[string]string) +var authorNameCache = make(map[string]string) +var authorStyleCache = make(map[string]style.TextStyle) + +func ShortAuthor(authorName string) string { + if value, ok := authorInitialCache[authorName]; ok { + return value + } + + initials := getInitials(authorName) + if initials == "" { + return "" + } + + value := AuthorStyle(authorName).Sprint(initials) + authorInitialCache[authorName] = value + + return value +} + +func LongAuthor(authorName string) string { + if value, ok := authorNameCache[authorName]; ok { + return value + } + + paddedAuthorName := utils.WithPadding(authorName, 17) + truncatedName := utils.TruncateWithEllipsis(paddedAuthorName, 17) + value := AuthorStyle(authorName).Sprint(truncatedName) + authorNameCache[authorName] = value + + return value +} + +func AuthorStyle(authorName string) style.TextStyle { + if value, ok := authorStyleCache[authorName]; ok { + return value + } + + value := trueColorStyle(authorName) + + authorStyleCache[authorName] = value + + return value +} + +func trueColorStyle(str string) style.TextStyle { + hash := md5.Sum([]byte(str)) + 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 { + return float64(randInt(hash, 100)) / 100 +} + +func randInt(hash []byte, max int) int { + sum := 0 + for _, b := range hash { + sum = (sum + int(b)) % max + } + return sum +} + +func getInitials(authorName string) string { + if authorName == "" { + return authorName + } + + firstRune := getFirstRune(authorName) + if runewidth.RuneWidth(firstRune) > 1 { + return string(firstRune) + } + + split := strings.Split(authorName, " ") + if len(split) == 1 { + return utils.LimitStr(authorName, 2) + } + + return utils.LimitStr(split[0], 1) + utils.LimitStr(split[1], 1) +} + +func getFirstRune(str string) rune { + // just using the loop for the sake of getting the first rune + for _, r := range str { + return r + } + // should never land here + return 0 +} diff --git a/pkg/gui/presentation/authors/authors_test.go b/pkg/gui/presentation/authors/authors_test.go new file mode 100644 index 000000000..58efba297 --- /dev/null +++ b/pkg/gui/presentation/authors/authors_test.go @@ -0,0 +1,20 @@ +package authors + +import "testing" + +func TestGetInitials(t *testing.T) { + for input, expectedOutput := range map[string]string{ + "Jesse Duffield": "JD", + "Jesse Duffield Man": "JD", + "JesseDuffield": "Je", + "J": "J", + "六书六書": "六", + "書": "書", + "": "", + } { + output := getInitials(input) + if output != expectedOutput { + t.Errorf("Expected %s to be %s", output, expectedOutput) + } + } +} diff --git a/pkg/gui/presentation/commits.go b/pkg/gui/presentation/commits.go index 0018d45df..2474a283e 100644 --- a/pkg/gui/presentation/commits.go +++ b/pkg/gui/presentation/commits.go @@ -1,17 +1,14 @@ package presentation import ( - "crypto/md5" "strings" - "github.com/gookit/color" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/gui/presentation/authors" "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" - "github.com/mattn/go-runewidth" ) func GetCommitListDisplayStrings(commits []*models.Commit, fullDescription bool, cherryPickedCommitShaMap map[string]bool, diffName string, parseEmoji bool) [][]string { @@ -72,7 +69,7 @@ func getFullDescriptionDisplayStringsForCommit(c *models.Commit, cherryPickedCom return []string{ shaColor.Sprint(c.ShortSha()), secondColumnString, - longAuthor(c.Author), + authors.LongAuthor(c.Author), tagString + theme.DefaultTextColor.Sprint(name), } } @@ -116,84 +113,11 @@ func getDisplayStringsForCommit(c *models.Commit, cherryPickedCommitShaMap map[s return []string{ shaColor.Sprint(c.ShortSha()), - shortAuthor(c.Author), + authors.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 value, ok := authorInitialCache[authorName]; ok { - return value - } - - initials := getInitials(authorName) - if initials == "" { - return "" - } - - value := authorColor(authorName).Sprint(initials) - authorInitialCache[authorName] = value - - return value -} - -func longAuthor(authorName string) string { - if value, ok := authorNameCache[authorName]; ok { - return value - } - - 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 -} - -func getInitials(authorName string) string { - if authorName == "" { - return authorName - } - - firstRune := getFirstRune(authorName) - if runewidth.RuneWidth(firstRune) > 1 { - return string(firstRune) - } - - split := strings.Split(authorName, " ") - if len(split) == 1 { - return utils.LimitStr(authorName, 2) - } - - return utils.LimitStr(split[0], 1) + utils.LimitStr(split[1], 1) -} - -func getFirstRune(str string) rune { - // just using the loop for the sake of getting the first rune - for _, r := range str { - return r - } - // should never land here - return 0 -} - 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 deleted file mode 100644 index 578091166..000000000 --- a/pkg/gui/presentation/commits_test.go +++ /dev/null @@ -1,20 +0,0 @@ -package presentation - -import "testing" - -func TestGetInitials(t *testing.T) { - for input, expectedOutput := range map[string]string{ - "Jesse Duffield": "JD", - "Jesse Duffield Man": "JD", - "JesseDuffield": "Je", - "J": "J", - "六书六書": "六", - "書": "書", - "": "", - } { - output := getInitials(input) - if output != expectedOutput { - t.Errorf("Expected %s to be %s", output, expectedOutput) - } - } -} -- cgit v1.2.3