Add backward cycling support for all branches log view

This commit implements the ability to cycle backward through different
all branches log visualization modes, complementing the existing forward
cycling functionality. Users can now press 'A' (Shift+a) to cycle in
reverse through the available log graph views, improving navigation
efficiency when they overshoot their desired view.

Changes:
- Added RotateAllBranchesLogIdxBackward() method to BranchCommands for
  backward rotation through log command candidates
- Introduced AllBranchesLogGraphReverse keybinding configuration with
  default key 'A' (uppercase)
- Implemented switchToOrRotateAllBranchesLogsBackward() handler in
  StatusController that mirrors forward cycling logic
- Added English translation for "Show/cycle all branch logs (reverse)"

The implementation uses modulo arithmetic with proper handling of
negative indices to ensure seamless backward cycling through the
available log visualization options.
This commit is contained in:
Zak Siddiqui 2026-03-08 16:49:25 +10:00 committed by Stefan Haller
parent 551f341cf7
commit 7d32e45f73
16 changed files with 71 additions and 10 deletions

View file

@ -666,6 +666,7 @@ keybinding:
checkForUpdate: u
recentRepos: <enter>
allBranchesLogGraph: a
allBranchesLogGraphReverse: A
files:
commitChanges: c
commitChangesWithoutHook: w

View file

@ -353,6 +353,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` u `` | Check for update | |
| `` <enter> `` | Switch to a recent repo | |
| `` a `` | Show/cycle all branch logs | |
| `` A `` | Show/cycle all branch logs (reverse) | |
| `` 0 `` | Focus main view | |
## Sub-commits

View file

@ -185,6 +185,7 @@ _凡例`c-b` はctrl+b、`a-b` はalt+b、`B` はshift+bを意味
| `` u `` | 更新を確認 | |
| `` <enter> `` | 最近のリポジトリをチェックアウト | |
| `` a `` | ブランチログの表示モードを順に切り替え | |
| `` A `` | Show/cycle all branch logs (reverse) | |
| `` 0 `` | メインビューにフォーカス | |
## セカンダリ

View file

@ -243,6 +243,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` u `` | 업데이트 확인 | |
| `` <enter> `` | 최근에 사용한 저장소로 전환 | |
| `` a `` | Show/cycle all branch logs | |
| `` A `` | Show/cycle all branch logs (reverse) | |
| `` 0 `` | Focus main view | |
## 서브모듈

View file

@ -353,6 +353,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` u `` | Check voor updates | |
| `` <enter> `` | Wissel naar een recente repo | |
| `` a `` | Show/cycle all branch logs | |
| `` A `` | Show/cycle all branch logs (reverse) | |
| `` 0 `` | Focus main view | |
## Sub-commits

View file

@ -332,6 +332,7 @@ _Legenda: `<c-b>` oznacza ctrl+b, `<a-b>` oznacza alt+b, `B` oznacza shift+b_
| `` u `` | Sprawdź aktualizacje | |
| `` <enter> `` | Przełącz na ostatnie repozytorium | |
| `` a `` | Show/cycle all branch logs | |
| `` A `` | Show/cycle all branch logs (reverse) | |
| `` 0 `` | Focus main view | |
## Sub-commity

View file

@ -362,6 +362,7 @@ _Legend: `<c-b>` means ctrl+b, `<a-b>` means alt+b, `B` means shift+b_
| `` u `` | Verificar atualização | |
| `` <enter> `` | Mudar para um repositório recente | |
| `` a `` | Mostrar/ciclo todos os logs de filiais | |
| `` A `` | Show/cycle all branch logs (reverse) | |
| `` 0 `` | Focus main view | |
## Sub-commits

View file

@ -319,6 +319,7 @@ _Связки клавиш_
| `` u `` | Проверить обновления | |
| `` <enter> `` | Переключиться на последний репозиторий | |
| `` a `` | Show/cycle all branch logs | |
| `` A `` | Show/cycle all branch logs (reverse) | |
| `` 0 `` | Focus main view | |
## Теги

View file

@ -345,6 +345,7 @@ _图例`<c-b>` 意味着ctrl+b, `<a-b>意味着Alt+b, `B` 意味着shift+b_
| `` u `` | 检查更新 | |
| `` <enter> `` | 切换到最近的仓库 | |
| `` a `` | 显示/循环所有分支日志 | |
| `` A `` | Show/cycle all branch logs (reverse) | |
| `` 0 `` | 聚焦主视图 | |
## 确认面板

View file

@ -374,6 +374,7 @@ _說明`<c-b>` 表示 CtrlB、`<a-b>` 表示 AltB`B`表示 ShiftB
| `` u `` | 檢查更新 | |
| `` <enter> `` | 切換到最近使用的版本庫 | |
| `` a `` | Show/cycle all branch logs | |
| `` A `` | Show/cycle all branch logs (reverse) | |
| `` 0 `` | Focus main view | |
## 確認面板

View file

@ -317,6 +317,12 @@ func (self *BranchCommands) RotateAllBranchesLogIdx() {
self.allBranchesLogCmdIndex = (i + 1) % n
}
func (self *BranchCommands) RotateAllBranchesLogIdxBackward() {
n := len(self.allBranchesLogCandidates())
i := self.allBranchesLogCmdIndex
self.allBranchesLogCmdIndex = (i - 1 + n) % n
}
func (self *BranchCommands) GetAllBranchesLogIdxAndCount() (int, int) {
n := len(self.allBranchesLogCandidates())
i := self.allBranchesLogCmdIndex

View file

@ -493,9 +493,10 @@ type KeybindingUniversalConfig struct {
}
type KeybindingStatusConfig struct {
CheckForUpdate string `yaml:"checkForUpdate"`
RecentRepos string `yaml:"recentRepos"`
AllBranchesLogGraph string `yaml:"allBranchesLogGraph"`
CheckForUpdate string `yaml:"checkForUpdate"`
RecentRepos string `yaml:"recentRepos"`
AllBranchesLogGraph string `yaml:"allBranchesLogGraph"`
AllBranchesLogGraphReverse string `yaml:"allBranchesLogGraphReverse"`
}
type KeybindingFilesConfig struct {
@ -955,9 +956,10 @@ func GetDefaultConfig() *UserConfig {
OpenDiffTool: "<c-t>",
},
Status: KeybindingStatusConfig{
CheckForUpdate: "u",
RecentRepos: "<enter>",
AllBranchesLogGraph: "a",
CheckForUpdate: "u",
RecentRepos: "<enter>",
AllBranchesLogGraph: "a",
AllBranchesLogGraphReverse: "A",
},
Files: KeybindingFilesConfig{
CommitChanges: "c",

View file

@ -63,6 +63,11 @@ func (self *StatusController) GetKeybindings(opts types.KeybindingsOpts) []*type
Handler: func() error { self.switchToOrRotateAllBranchesLogs(); return nil },
Description: self.c.Tr.AllBranchesLogGraph,
},
{
Key: opts.GetKey(opts.Config.Status.AllBranchesLogGraphReverse),
Handler: func() error { self.switchToOrRotateAllBranchesLogsBackward(); return nil },
Description: self.c.Tr.AllBranchesLogGraphReverse,
},
}
return bindings
@ -206,6 +211,18 @@ func (self *StatusController) switchToOrRotateAllBranchesLogs() {
self.showAllBranchLogs()
}
// Switches to the all branches view, or, if already on that view,
// rotates to the previous command in the list, and then renders it.
func (self *StatusController) switchToOrRotateAllBranchesLogsBackward() {
// A bit of a hack to ensure we only rotate to the previous branch log command
// if we currently are looking at a branch log. Otherwise, we should just show
// the current index (if we are coming from the dashboard).
if self.c.Views().Main.Title != self.c.Tr.StatusTitle {
self.c.Git().Branch.RotateAllBranchesLogIdxBackward()
}
self.showAllBranchLogs()
}
func (self *StatusController) showDashboard() {
versionStr := "master"
version, err := types.ParseVersionNumber(self.c.GetConfig().GetVersion())

View file

@ -279,6 +279,7 @@ type TranslationSet struct {
ConfirmQuit string
SwitchRepo string
AllBranchesLogGraph string
AllBranchesLogGraphReverse string
UnsupportedGitService string
CopyPullRequestURL string
NoBranchOnRemote string
@ -1389,6 +1390,7 @@ func EnglishTranslationSet() *TranslationSet {
ConfirmQuit: `Are you sure you want to quit?`,
SwitchRepo: `Switch to a recent repo`,
AllBranchesLogGraph: `Show/cycle all branch logs`,
AllBranchesLogGraphReverse: `Show/cycle all branch logs (reverse)`,
UnsupportedGitService: `Unsupported git service`,
CreatePullRequest: `Create pull request`,
CopyPullRequestURL: `Copy pull request URL to clipboard`,

View file

@ -10,7 +10,11 @@ var LogCmdStatusPanelAllBranchesLog = NewIntegrationTest(NewIntegrationTestArgs{
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {
config.GetUserConfig().Git.AllBranchesLogCmds = []string{`echo "view1"`, `echo "view2"`}
config.GetUserConfig().Git.AllBranchesLogCmds = []string{
`echo "view1"`,
`echo "view2"`,
`echo "view3"`,
}
config.GetUserConfig().Gui.StatusPanelView = "allBranchesLog"
},
SetupRepo: func(shell *Shell) {},
@ -25,14 +29,30 @@ var LogCmdStatusPanelAllBranchesLog = NewIntegrationTest(NewIntegrationTestArgs{
t.Views().Status().
Focus()
t.Views().Main().Content(Contains("view1").DoesNotContain("view2"))
t.Views().Main().Content(Contains("view1"))
t.Views().Status().
Press(keys.Status.AllBranchesLogGraph)
t.Views().Main().Content(Contains("view2").DoesNotContain("view1"))
t.Views().Main().Content(Contains("view2"))
t.Views().Status().
Press(keys.Status.AllBranchesLogGraph)
t.Views().Main().Content(Contains("view1").DoesNotContain("view2"))
t.Views().Main().Content(Contains("view3"))
t.Views().Status().
Press(keys.Status.AllBranchesLogGraph)
t.Views().Main().Content(Contains("view1"))
t.Views().Status().
Press(keys.Status.AllBranchesLogGraphReverse)
t.Views().Main().Content(Contains("view3"))
t.Views().Status().
Press(keys.Status.AllBranchesLogGraphReverse)
t.Views().Main().Content(Contains("view2"))
t.Views().Status().
Press(keys.Status.AllBranchesLogGraphReverse)
t.Views().Main().Content(Contains("view1"))
},
})

View file

@ -1204,6 +1204,10 @@
"allBranchesLogGraph": {
"type": "string",
"default": "a"
},
"allBranchesLogGraphReverse": {
"type": "string",
"default": "A"
}
},
"additionalProperties": false,