diff --git a/pkg/commands/models/branch.go b/pkg/commands/models/branch.go index 5fc887f87..c5fcfdaed 100644 --- a/pkg/commands/models/branch.go +++ b/pkg/commands/models/branch.go @@ -65,6 +65,10 @@ func (b *Branch) ID() string { return b.RefName() } +func (b *Branch) URN() string { + return "branch-" + b.ID() +} + func (b *Branch) Description() string { return b.RefName() } diff --git a/pkg/gui/context/branches_context.go b/pkg/gui/context/branches_context.go index ac1fae52c..68324d020 100644 --- a/pkg/gui/context/branches_context.go +++ b/pkg/gui/context/branches_context.go @@ -27,6 +27,7 @@ func NewBranchesContext(c *ContextCommon) *BranchesContext { getDisplayStrings := func(_ int, _ int) [][]string { return presentation.GetBranchListDisplayStrings( viewModel.GetItems(), + c.State().GetItemOperation, c.State().GetRepoState().GetScreenMode() != types.SCREEN_NORMAL, c.Modes().Diffing.Ref, c.Tr, diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index 4f8ebdbf8..407dc135a 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -563,14 +563,7 @@ func (self *BranchesController) fastForward(branch *models.Branch) error { action := self.c.Tr.Actions.FastForwardBranch - message := utils.ResolvePlaceholderString( - self.c.Tr.FastForwarding, - map[string]string{ - "branch": branch.Name, - }, - ) - - return self.c.WithWaitingStatus(message, func(task gocui.Task) error { + return self.c.WithInlineStatus(branch, types.ItemOperationFastForwarding, context.LOCAL_BRANCHES_CONTEXT_KEY, func(task gocui.Task) error { worktree, ok := self.worktreeForBranch(branch) if ok { self.c.LogAction(action) diff --git a/pkg/gui/controllers/helpers/refresh_helper.go b/pkg/gui/controllers/helpers/refresh_helper.go index f04b102e4..bec0a10e1 100644 --- a/pkg/gui/controllers/helpers/refresh_helper.go +++ b/pkg/gui/controllers/helpers/refresh_helper.go @@ -678,7 +678,7 @@ func (self *RefreshHelper) refreshStatus() { repoName := self.c.Git().RepoPaths.RepoName() - status := presentation.FormatStatus(repoName, currentBranch, linkedWorktreeName, workingTreeState, self.c.Tr) + status := presentation.FormatStatus(repoName, currentBranch, types.ItemOperationNone, linkedWorktreeName, workingTreeState, self.c.Tr) self.c.SetViewContent(self.c.Views().Status, status) } diff --git a/pkg/gui/controllers/status_controller.go b/pkg/gui/controllers/status_controller.go index 8344dfe76..2a186670b 100644 --- a/pkg/gui/controllers/status_controller.go +++ b/pkg/gui/controllers/status_controller.go @@ -106,7 +106,7 @@ func (self *StatusController) onClick() error { } cx, _ := self.c.Views().Status.Cursor() - upstreamStatus := presentation.BranchStatus(currentBranch, self.c.Tr) + upstreamStatus := presentation.BranchStatus(currentBranch, types.ItemOperationNone, self.c.Tr) repoName := self.c.Git().RepoPaths.RepoName() workingTreeState := self.c.Git().Status.WorkingTreeState() switch workingTreeState { diff --git a/pkg/gui/controllers/sync_controller.go b/pkg/gui/controllers/sync_controller.go index a77d047a6..46d553a84 100644 --- a/pkg/gui/controllers/sync_controller.go +++ b/pkg/gui/controllers/sync_controller.go @@ -7,6 +7,7 @@ import ( "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands/git_commands" "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -73,13 +74,13 @@ func (self *SyncController) push(currentBranch *models.Branch) error { if currentBranch.IsTrackingRemote() { opts := pushOpts{} if currentBranch.HasCommitsToPull() { - return self.requestToForcePush(opts) + return self.requestToForcePush(currentBranch, opts) } else { - return self.pushAux(opts) + return self.pushAux(currentBranch, opts) } } else { if self.c.Git().Config.GetPushToCurrent() { - return self.pushAux(pushOpts{setUpstream: true}) + return self.pushAux(currentBranch, pushOpts{setUpstream: true}) } else { return self.c.Helpers().Upstream.PromptForUpstreamWithInitialContent(currentBranch, func(upstream string) error { upstreamRemote, upstreamBranch, err := self.c.Helpers().Upstream.ParseUpstream(upstream) @@ -87,7 +88,7 @@ func (self *SyncController) push(currentBranch *models.Branch) error { return self.c.Error(err) } - return self.pushAux(pushOpts{ + return self.pushAux(currentBranch, pushOpts{ setUpstream: true, upstreamRemote: upstreamRemote, upstreamBranch: upstreamBranch, @@ -107,11 +108,11 @@ func (self *SyncController) pull(currentBranch *models.Branch) error { return self.c.Error(err) } - return self.PullAux(PullFilesOptions{Action: action}) + return self.PullAux(currentBranch, PullFilesOptions{Action: action}) }) } - return self.PullAux(PullFilesOptions{Action: action}) + return self.PullAux(currentBranch, PullFilesOptions{Action: action}) } func (self *SyncController) setCurrentBranchUpstream(upstream string) error { @@ -139,8 +140,8 @@ type PullFilesOptions struct { Action string } -func (self *SyncController) PullAux(opts PullFilesOptions) error { - return self.c.WithWaitingStatus(self.c.Tr.PullingStatus, func(task gocui.Task) error { +func (self *SyncController) PullAux(currentBranch *models.Branch, opts PullFilesOptions) error { + return self.c.WithInlineStatus(currentBranch, types.ItemOperationPulling, context.LOCAL_BRANCHES_CONTEXT_KEY, func(task gocui.Task) error { return self.pullWithLock(task, opts) }) } @@ -167,8 +168,8 @@ type pushOpts struct { setUpstream bool } -func (self *SyncController) pushAux(opts pushOpts) error { - return self.c.WithWaitingStatus(self.c.Tr.PushingStatus, func(task gocui.Task) error { +func (self *SyncController) pushAux(currentBranch *models.Branch, opts pushOpts) error { + return self.c.WithInlineStatus(currentBranch, types.ItemOperationPushing, context.LOCAL_BRANCHES_CONTEXT_KEY, func(task gocui.Task) error { self.c.LogAction(self.c.Tr.Actions.Push) err := self.c.Git().Sync.Push( task, @@ -192,18 +193,18 @@ func (self *SyncController) pushAux(opts pushOpts) error { newOpts := opts newOpts.force = true - return self.pushAux(newOpts) + return self.pushAux(currentBranch, newOpts) }, }) return nil } - _ = self.c.Error(err) + return err } return self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC}) }) } -func (self *SyncController) requestToForcePush(opts pushOpts) error { +func (self *SyncController) requestToForcePush(currentBranch *models.Branch, opts pushOpts) error { forcePushDisabled := self.c.UserConfig.Git.DisableForcePushing if forcePushDisabled { return self.c.ErrorMsg(self.c.Tr.ForcePushDisabled) @@ -214,7 +215,7 @@ func (self *SyncController) requestToForcePush(opts pushOpts) error { Prompt: self.forcePushPrompt(), HandleConfirm: func() error { opts.force = true - return self.pushAux(opts) + return self.pushAux(currentBranch, opts) }, }) } diff --git a/pkg/gui/presentation/branches.go b/pkg/gui/presentation/branches.go index 6d4620238..bd027ca62 100644 --- a/pkg/gui/presentation/branches.go +++ b/pkg/gui/presentation/branches.go @@ -9,6 +9,7 @@ import ( "github.com/jesseduffield/lazygit/pkg/config" "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/i18n" "github.com/jesseduffield/lazygit/pkg/theme" "github.com/jesseduffield/lazygit/pkg/utils" @@ -19,6 +20,7 @@ var branchPrefixColorCache = make(map[string]style.TextStyle) func GetBranchListDisplayStrings( branches []*models.Branch, + getItemOperation func(item types.HasUrn) types.ItemOperation, fullDescription bool, diffName string, tr *i18n.TranslationSet, @@ -27,13 +29,14 @@ func GetBranchListDisplayStrings( ) [][]string { return lo.Map(branches, func(branch *models.Branch, _ int) []string { diffed := branch.Name == diffName - return getBranchDisplayStrings(branch, fullDescription, diffed, tr, userConfig, worktrees) + return getBranchDisplayStrings(branch, getItemOperation(branch), fullDescription, diffed, tr, userConfig, worktrees) }) } // getBranchDisplayStrings returns the display string of branch func getBranchDisplayStrings( b *models.Branch, + itemOperation types.ItemOperation, fullDescription bool, diffed bool, tr *i18n.TranslationSet, @@ -51,7 +54,7 @@ func getBranchDisplayStrings( } coloredName := nameTextStyle.Sprint(displayName) - branchStatus := utils.WithPadding(ColoredBranchStatus(b, tr), 2, utils.AlignLeft) + branchStatus := utils.WithPadding(ColoredBranchStatus(b, itemOperation, tr), 2, utils.AlignLeft) if git_commands.CheckedOutByOtherWorktree(b, worktrees) { worktreeIcon := lo.Ternary(icons.IsIconEnabled(), icons.LINKED_WORKTREE_ICON, fmt.Sprintf("(%s)", tr.LcWorktree)) coloredName = fmt.Sprintf("%s %s", coloredName, style.FgDefault.Sprint(worktreeIcon)) @@ -109,9 +112,11 @@ func GetBranchTextStyle(name string) style.TextStyle { } } -func ColoredBranchStatus(branch *models.Branch, tr *i18n.TranslationSet) string { +func ColoredBranchStatus(branch *models.Branch, itemOperation types.ItemOperation, tr *i18n.TranslationSet) string { colour := style.FgYellow - if branch.UpstreamGone { + if itemOperation != types.ItemOperationNone { + colour = style.FgCyan + } else if branch.UpstreamGone { colour = style.FgRed } else if branch.MatchesUpstream() { colour = style.FgGreen @@ -119,10 +124,15 @@ func ColoredBranchStatus(branch *models.Branch, tr *i18n.TranslationSet) string colour = style.FgMagenta } - return colour.Sprint(BranchStatus(branch, tr)) + return colour.Sprint(BranchStatus(branch, itemOperation, tr)) } -func BranchStatus(branch *models.Branch, tr *i18n.TranslationSet) string { +func BranchStatus(branch *models.Branch, itemOperation types.ItemOperation, tr *i18n.TranslationSet) string { + itemOperationStr := itemOperationToString(itemOperation, tr) + if itemOperationStr != "" { + return itemOperationStr + " " + utils.Loader() + } + if !branch.IsTrackingRemote() { return "" } diff --git a/pkg/gui/presentation/item_operations.go b/pkg/gui/presentation/item_operations.go new file mode 100644 index 000000000..afa48da4f --- /dev/null +++ b/pkg/gui/presentation/item_operations.go @@ -0,0 +1,23 @@ +package presentation + +import ( + "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/i18n" +) + +func itemOperationToString(itemOperation types.ItemOperation, tr *i18n.TranslationSet) string { + switch itemOperation { + case types.ItemOperationNone: + return "" + case types.ItemOperationPushing: + return tr.PushingStatus + case types.ItemOperationPulling: + return tr.PullingStatus + case types.ItemOperationFastForwarding: + return tr.FastForwarding + case types.ItemOperationDeleting: + return tr.DeletingStatus + } + + return "" +} diff --git a/pkg/gui/presentation/status.go b/pkg/gui/presentation/status.go index f70210c27..7bf81948f 100644 --- a/pkg/gui/presentation/status.go +++ b/pkg/gui/presentation/status.go @@ -7,14 +7,15 @@ import ( "github.com/jesseduffield/lazygit/pkg/commands/types/enums" "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/i18n" ) -func FormatStatus(repoName string, currentBranch *models.Branch, linkedWorktreeName string, workingTreeState enums.RebaseMode, tr *i18n.TranslationSet) string { +func FormatStatus(repoName string, currentBranch *models.Branch, itemOperation types.ItemOperation, linkedWorktreeName string, workingTreeState enums.RebaseMode, tr *i18n.TranslationSet) string { status := "" if currentBranch.IsRealBranch() { - status += ColoredBranchStatus(currentBranch, tr) + " " + status += ColoredBranchStatus(currentBranch, itemOperation, tr) + " " } if workingTreeState != enums.REBASE_MODE_NONE { diff --git a/pkg/i18n/chinese.go b/pkg/i18n/chinese.go index ddfeb7254..234d470db 100644 --- a/pkg/i18n/chinese.go +++ b/pkg/i18n/chinese.go @@ -169,7 +169,7 @@ func chineseTranslationSet() TranslationSet { ToggleStagingPanel: `切换到其他面板`, ReturnToFilesPanel: `返回文件面板`, FastForward: `从上游快进此分支`, - FastForwarding: "抓取并快进 {{.branch}} ...", + FastForwarding: "抓取并快进", FoundConflictsTitle: "自动合并失败", ViewMergeRebaseOptions: "查看 合并/变基 选项", NotMergingOrRebasing: "您目前既不进行变基也不进行合并", diff --git a/pkg/i18n/dutch.go b/pkg/i18n/dutch.go index 83ef02698..7abfaa437 100644 --- a/pkg/i18n/dutch.go +++ b/pkg/i18n/dutch.go @@ -134,7 +134,7 @@ func dutchTranslationSet() TranslationSet { ToggleStagingPanel: `Ga naar een ander paneel`, ReturnToFilesPanel: `Ga terug naar het bestanden paneel`, FastForward: `Fast-forward deze branch vanaf zijn upstream`, - FastForwarding: "Fast-forwarding {{.branch}} ...", + FastForwarding: "Fast-forwarding", FoundConflictsTitle: "Conflicten!", ViewMergeRebaseOptions: "Bekijk merge/rebase opties", NotMergingOrRebasing: "Je bent momenteel niet aan het rebasen of mergen", diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 15deab925..0ffeccdbc 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -980,7 +980,7 @@ func EnglishTranslationSet() TranslationSet { ToggleStagingPanel: `Switch to other panel (staged/unstaged changes)`, ReturnToFilesPanel: `Return to files panel`, FastForward: `Fast-forward this branch from its upstream`, - FastForwarding: "Fast-forwarding {{.branch}}", + FastForwarding: "Fast-forwarding", FoundConflictsTitle: "Conflicts!", ViewConflictsMenuItem: "View conflicts", AbortMenuItem: "Abort the %s", diff --git a/pkg/i18n/korean.go b/pkg/i18n/korean.go index e33f74866..d6b7793a0 100644 --- a/pkg/i18n/korean.go +++ b/pkg/i18n/korean.go @@ -170,7 +170,7 @@ func koreanTranslationSet() TranslationSet { ToggleStagingPanel: `패널 전환`, ReturnToFilesPanel: `파일 목록으로 돌아가기`, FastForward: `Fast-forward this branch from its upstream`, - FastForwarding: "Fast-forwarding {{.branch}} ...", + FastForwarding: "Fast-forwarding", FoundConflictsTitle: "Auto-merge failed", ViewMergeRebaseOptions: "View merge/rebase options", NotMergingOrRebasing: "You are currently neither rebasing nor merging", diff --git a/pkg/i18n/russian.go b/pkg/i18n/russian.go index 9a4b727e0..3332f72cd 100644 --- a/pkg/i18n/russian.go +++ b/pkg/i18n/russian.go @@ -201,7 +201,7 @@ func RussianTranslationSet() TranslationSet { ToggleStagingPanel: `Переключиться на другую панель (проиндексированные/непроиндексированные изменения)`, ReturnToFilesPanel: `Вернуться к панели файлов`, FastForward: `Перемотать эту ветку вперёд из её upstream-ветки`, - FastForwarding: "Получить изменения и перемотать вперёд {{.branch}} ...", + FastForwarding: "Получить изменения и перемотать вперёд", FoundConflictsTitle: "Конфликты!", ViewConflictsMenuItem: "Просмотр конфликтов", AbortMenuItem: "Прервать %s", diff --git a/pkg/i18n/traditional_chinese.go b/pkg/i18n/traditional_chinese.go index ae95f71e8..703c6667c 100644 --- a/pkg/i18n/traditional_chinese.go +++ b/pkg/i18n/traditional_chinese.go @@ -234,7 +234,7 @@ func traditionalChineseTranslationSet() TranslationSet { ToggleStagingPanel: `切換至另一個面板 (已預存/未預存更改)`, ReturnToFilesPanel: `返回檔案面板`, FastForward: `從上游快進此分支`, - FastForwarding: "{{.branch}} 的擷取和快進中...", + FastForwarding: "的擷取和快進中", FoundConflictsTitle: "自動合併失敗", ViewMergeRebaseOptions: "查看合併/變基選項", NotMergingOrRebasing: "你當前既不在變基也不在合併中",