Centralize pull-request header presentation

The branch controller should decide which pull request to show, not how its
header is styled and linked. Move the existing formatter and state badge next
to the branch presentation helpers so subsequent header changes stay in one
layer.
This commit is contained in:
Stefan Haller 2026-07-30 12:21:47 +02:00
parent ff26f61ffd
commit 320d33a8ef
3 changed files with 62 additions and 41 deletions

View file

@ -5,15 +5,12 @@ import (
"fmt"
"strings"
"github.com/gookit/color"
"github.com/jesseduffield/lazygit/pkg/commands/git_commands"
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/gocui"
"github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/presentation"
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
@ -214,13 +211,7 @@ func (self *BranchesController) GetOnRenderToMain() func() {
pr, ok := self.c.Model().PullRequestsMap[branch.Name]
if ok && presentation.ShouldShowPrForBranch(pr, branch.Name, self.c.UserConfig()) {
icon := lo.Ternary(icons.IsIconEnabled(), icons.IconForRemoteUrl(pr.Url)+" ", "")
ptyTask.Prefix = style.PrintHyperlink(fmt.Sprintf("%s%s %s %s\n",
icon,
coloredStateText(pr.State),
pr.Title,
style.FgCyan.Sprintf("#%d", pr.Number)),
pr.Url)
ptyTask.Prefix = presentation.FormatPullRequestHeader(pr)
ptyTask.Prefix += strings.Repeat("─", self.c.Contexts().Normal.GetView().InnerWidth()) + "\n"
}
}
@ -236,37 +227,6 @@ func (self *BranchesController) GetOnRenderToMain() func() {
}
}
func stateText(state string) string {
var icon, label string
switch state {
case "OPEN":
icon, label = " ", "Open"
case "CLOSED":
icon, label = " ", "Closed"
case "MERGED":
icon, label = " ", "Merged"
case "DRAFT":
icon, label = " ", "Draft"
default:
return ""
}
if icons.IsIconEnabled() {
return icon + label
}
return label
}
func coloredStateText(state string) string {
if icons.IsIconEnabled() {
return fmt.Sprintf("%s%s%s",
presentation.WithPrColor(state, "", false),
presentation.WithPrColor(state, color.RGB(0xFF, 0xFF, 0xFF, false).Sprint(stateText(state)), true),
presentation.WithPrColor(state, "", false))
}
return presentation.WithPrColor(state, stateText(state), false)
}
func (self *BranchesController) viewUpstreamOptions(selectedBranch *models.Branch) error {
upstream := lo.Ternary(selectedBranch.RemoteBranchStoredLocally(),
selectedBranch.ShortUpstreamRefName(),

View file

@ -287,6 +287,47 @@ func WithPrColor(state string, text string, isBg bool) string {
}
}
func FormatPullRequestHeader(pr *models.GithubPullRequest) string {
icon := lo.Ternary(icons.IsIconEnabled(), icons.IconForRemoteUrl(pr.Url)+" ", "")
return style.PrintHyperlink(fmt.Sprintf("%s%s %s %s\n",
icon,
coloredPullRequestStateText(pr.State),
pr.Title,
style.FgCyan.Sprintf("#%d", pr.Number)),
pr.Url)
}
func pullRequestStateText(state string) string {
var icon, label string
switch state {
case "OPEN":
icon, label = " ", "Open"
case "CLOSED":
icon, label = " ", "Closed"
case "MERGED":
icon, label = " ", "Merged"
case "DRAFT":
icon, label = " ", "Draft"
default:
return ""
}
if icons.IsIconEnabled() {
return icon + label
}
return label
}
func coloredPullRequestStateText(state string) string {
if icons.IsIconEnabled() {
return fmt.Sprintf("%s%s%s",
WithPrColor(state, "", false),
WithPrColor(state, color.RGB(0xFF, 0xFF, 0xFF, false).Sprint(pullRequestStateText(state)), true),
WithPrColor(state, "", false))
}
return WithPrColor(state, pullRequestStateText(state), false)
}
func ShouldShowPrForBranch(pr *models.GithubPullRequest, branchName string, userConfig *config.UserConfig) bool {
if !lo.Contains(userConfig.Git.MainBranches, branchName) {
return true

View file

@ -10,6 +10,7 @@ import (
"github.com/jesseduffield/lazygit/pkg/commands/models"
"github.com/jesseduffield/lazygit/pkg/common"
"github.com/jesseduffield/lazygit/pkg/gui/presentation/icons"
"github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
"github.com/samber/lo"
"github.com/stretchr/testify/assert"
@ -22,6 +23,25 @@ func makeAtomic(v int32) *atomic.Int32 {
return &result
}
func TestFormatPullRequestHeader(t *testing.T) {
oldColorLevel := color.ForceSetColorLevel(terminfo.ColorLevelNone)
defer color.ForceSetColorLevel(oldColorLevel)
icons.SetNerdFontsVersion("")
pr := &models.GithubPullRequest{
Title: "Improve checks",
Number: 5871,
State: "OPEN",
Url: "https://github.com/jesseduffield/lazygit/pull/5871",
}
numberText := style.FgCyan.Sprint("#5871")
actual := FormatPullRequestHeader(pr)
expected := style.PrintHyperlink("Open Improve checks "+numberText+"\n", pr.Url)
assert.Equal(t, expected, actual)
}
func Test_getBranchDisplayStrings(t *testing.T) {
scenarios := []struct {
branch *models.Branch