mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-08-24 10:13:41 -05:00
Show PR icons in branches list
Co-authored-by: Stefan Haller <stefan@haller-berlin.de>
This commit is contained in:
committed by
Stefan Haller
co-authored by
Stefan Haller
parent
d33fa5bb05
commit
ca9eeebea3
@@ -28,6 +28,7 @@ func NewBranchesContext(c *ContextCommon) *BranchesContext {
|
||||
return presentation.GetBranchListDisplayStrings(
|
||||
viewModel.GetItems(),
|
||||
c.State().GetItemOperation,
|
||||
c.Model().PullRequestsMap,
|
||||
c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL,
|
||||
c.Modes().Diffing.Ref,
|
||||
c.Views().Branches.InnerWidth()+c.Views().Branches.OriginX(),
|
||||
|
||||
@@ -28,6 +28,7 @@ var colorPatterns *colorMatcher
|
||||
func GetBranchListDisplayStrings(
|
||||
branches []*models.Branch,
|
||||
getItemOperation func(item types.HasUrn) types.ItemOperation,
|
||||
prs map[string]*models.GithubPullRequest,
|
||||
fullDescription bool,
|
||||
diffName string,
|
||||
viewWidth int,
|
||||
@@ -37,7 +38,7 @@ func GetBranchListDisplayStrings(
|
||||
) [][]string {
|
||||
return lo.Map(branches, func(branch *models.Branch, _ int) []string {
|
||||
diffed := branch.Name == diffName
|
||||
return getBranchDisplayStrings(branch, getItemOperation(branch), fullDescription, diffed, viewWidth, tr, userConfig, worktrees, time.Now())
|
||||
return getBranchDisplayStrings(branch, getItemOperation(branch), fullDescription, diffed, viewWidth, tr, userConfig, worktrees, time.Now(), prs)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -52,6 +53,7 @@ func getBranchDisplayStrings(
|
||||
userConfig *config.UserConfig,
|
||||
worktrees []*models.Worktree,
|
||||
now time.Time,
|
||||
prs map[string]*models.GithubPullRequest,
|
||||
) []string {
|
||||
checkedOutByWorkTree := git_commands.CheckedOutByOtherWorktree(b, worktrees)
|
||||
showCommitHash := fullDescription || userConfig.Gui.ShowBranchCommitHash
|
||||
@@ -66,6 +68,10 @@ func getBranchDisplayStrings(
|
||||
if showCommitHash {
|
||||
availableWidth -= utils.COMMIT_HASH_SHORT_SIZE + 1
|
||||
}
|
||||
if len(prs) > 0 {
|
||||
// if we have PRs then we assume that at least one branch in the list has one
|
||||
availableWidth -= 2
|
||||
}
|
||||
paddingNeededForDivergence := availableWidth
|
||||
|
||||
displayName := b.Name
|
||||
@@ -133,6 +139,19 @@ func getBranchDisplayStrings(
|
||||
res := make([]string, 0, 6)
|
||||
res = append(res, recencyColor.Sprint(b.Recency))
|
||||
|
||||
var coloredPrIcon string
|
||||
pr, hasPr := prs[b.Name]
|
||||
if hasPr {
|
||||
var prIcon string
|
||||
if icons.IsIconEnabled() {
|
||||
prIcon = icons.IconForRemoteUrl(pr.Url)
|
||||
} else {
|
||||
prIcon = "●"
|
||||
}
|
||||
coloredPrIcon = prColor(pr.State).Sprint(prIcon)
|
||||
}
|
||||
res = append(res, coloredPrIcon)
|
||||
|
||||
if showCommitHash {
|
||||
res = append(res, utils.ShortHash(b.CommitHash))
|
||||
}
|
||||
@@ -251,3 +270,18 @@ func SetCustomBranches(customBranchColors map[string]string, isRegex bool) {
|
||||
isRegex: isRegex,
|
||||
}
|
||||
}
|
||||
|
||||
func prColor(state string) style.TextStyle {
|
||||
switch state {
|
||||
case "OPEN":
|
||||
return style.FgGreen
|
||||
case "CLOSED":
|
||||
return style.FgRed
|
||||
case "MERGED":
|
||||
return style.FgMagenta
|
||||
case "DRAFT":
|
||||
return style.FgBlackLighter
|
||||
default:
|
||||
return style.FgDefault
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branch_name"},
|
||||
expected: []string{"1m", "", "branch_name"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "🍉_special_char", Recency: "1m"},
|
||||
@@ -52,7 +52,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "🍉_special_char"},
|
||||
expected: []string{"1m", "", "🍉_special_char"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "branch_name", Recency: "1m"},
|
||||
@@ -62,7 +62,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: true,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branch_name (worktree other-worktree)"},
|
||||
expected: []string{"1m", "", "branch_name (worktree other-worktree)"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "branch_name", Recency: "1m"},
|
||||
@@ -72,7 +72,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: true,
|
||||
checkedOutByWorktree: true,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branch_name ( other-worktree)"},
|
||||
expected: []string{"1m", "", "branch_name ( other-worktree)"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{
|
||||
@@ -88,7 +88,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branch_name ✓"},
|
||||
expected: []string{"1m", "", "branch_name ✓"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{
|
||||
@@ -104,7 +104,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: true,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branch_name (worktree other-worktree) ↓5↑3"},
|
||||
expected: []string{"1m", "", "branch_name (worktree other-worktree) ↓5↑3"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{
|
||||
@@ -118,7 +118,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "onlyArrow",
|
||||
expected: []string{"1m", "branch_name ↓"},
|
||||
expected: []string{"1m", "", "branch_name ↓"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{
|
||||
@@ -135,7 +135,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "arrowAndNumber",
|
||||
expected: []string{"1m", "branch_name ✓ ↓2"},
|
||||
expected: []string{"1m", "", "branch_name ✓ ↓2"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{
|
||||
@@ -152,7 +152,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "arrowAndNumber",
|
||||
expected: []string{"1m", "branch_name ↓5↑3 ↓2"},
|
||||
expected: []string{"1m", "", "branch_name ↓5↑3 ↓2"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "branch_name", Recency: "1m"},
|
||||
@@ -162,7 +162,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branch_name Pushing |"},
|
||||
expected: []string{"1m", "", "branch_name Pushing |"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{
|
||||
@@ -181,7 +181,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "12345678", "branch_name ✓", "origin branch_name", "commit title"},
|
||||
expected: []string{"1m", "", "12345678", "branch_name ✓", "origin branch_name", "commit title"},
|
||||
},
|
||||
|
||||
// Now tests for how we truncate the branch name when there's not enough room:
|
||||
@@ -193,7 +193,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branch_na…"},
|
||||
expected: []string{"1m", "", "branch_na…"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "🍉_special_char", Recency: "1m"},
|
||||
@@ -203,7 +203,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "🍉_special_ch…"},
|
||||
expected: []string{"1m", "", "🍉_special_ch…"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "branch_name", Recency: "1m"},
|
||||
@@ -213,7 +213,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: true,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "bra… (worktree)"},
|
||||
expected: []string{"1m", "", "bra… (worktree)"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "branch_name", Recency: "1m"},
|
||||
@@ -223,7 +223,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: true,
|
||||
checkedOutByWorktree: true,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branc… "},
|
||||
expected: []string{"1m", "", "branc… "},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{
|
||||
@@ -239,7 +239,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branch_… ✓"},
|
||||
expected: []string{"1m", "", "branch_… ✓"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{
|
||||
@@ -256,7 +256,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "arrowAndNumber",
|
||||
expected: []string{"1m", "branch_n… ↓5↑3 ↓4"},
|
||||
expected: []string{"1m", "", "branch_n… ↓5↑3 ↓4"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{
|
||||
@@ -272,7 +272,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: true,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branch_na… (worktree) ↓5↑3"},
|
||||
expected: []string{"1m", "", "branch_na… (worktree) ↓5↑3"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "branch_name", Recency: "1m"},
|
||||
@@ -282,7 +282,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "branc… Pushing |"},
|
||||
expected: []string{"1m", "", "branc… Pushing |"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "abc", Recency: "1m"},
|
||||
@@ -292,7 +292,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "abc Pushing |"},
|
||||
expected: []string{"1m", "", "abc Pushing |"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "ab", Recency: "1m"},
|
||||
@@ -302,7 +302,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "ab Pushing |"},
|
||||
expected: []string{"1m", "", "ab Pushing |"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{Name: "a", Recency: "1m"},
|
||||
@@ -312,7 +312,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "a Pushing |"},
|
||||
expected: []string{"1m", "", "a Pushing |"},
|
||||
},
|
||||
{
|
||||
branch: &models.Branch{
|
||||
@@ -331,7 +331,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
useIcons: false,
|
||||
checkedOutByWorktree: false,
|
||||
showDivergenceCfg: "none",
|
||||
expected: []string{"1m", "12345678", "bran… ✓", "origin branch_name", "commit title"},
|
||||
expected: []string{"1m", "", "12345678", "bran… ✓", "origin branch_name", "commit title"},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ func Test_getBranchDisplayStrings(t *testing.T) {
|
||||
}
|
||||
|
||||
t.Run(fmt.Sprintf("getBranchDisplayStrings_%d", i), func(t *testing.T) {
|
||||
strings := getBranchDisplayStrings(s.branch, s.itemOperation, s.fullDescription, false, s.viewWidth, c.Tr, c.UserConfig(), worktrees, time.Time{})
|
||||
strings := getBranchDisplayStrings(s.branch, s.itemOperation, s.fullDescription, false, s.viewWidth, c.Tr, c.UserConfig(), worktrees, time.Time{}, map[string]*models.GithubPullRequest{})
|
||||
assert.Equal(t, s.expected, strings)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -79,6 +79,15 @@ func IconForRemote(remote *models.Remote) string {
|
||||
return DEFAULT_REMOTE_ICON
|
||||
}
|
||||
|
||||
func IconForRemoteUrl(url string) string {
|
||||
for domain, icon := range remoteIcons {
|
||||
if strings.Contains(url, domain) {
|
||||
return icon
|
||||
}
|
||||
}
|
||||
return DEFAULT_REMOTE_ICON
|
||||
}
|
||||
|
||||
func IconForStash(stash *models.StashEntry) string {
|
||||
return STASH_ICON
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user