From badb089a864fd6ae385bc53a7f89c8f13d1d8ee2 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 7 Jun 2026 15:49:25 +0200 Subject: [PATCH 1/6] Add a "just check" command --- justfile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/justfile b/justfile index 034a25b4d..36e8ee3d6 100644 --- a/justfile +++ b/justfile @@ -46,6 +46,10 @@ e2e-tui *args: e2e-all: go test pkg/integration/clients/*.go +# Run some tests on the current commit, similar to what CI does. +check: + ./scripts/check_commit.sh + bump-gocui: scripts/bump_gocui.sh From 9739a433551c54b457d84531f935e75fb94586ec Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 7 Jun 2026 15:32:22 +0200 Subject: [PATCH 2/6] Terminate tooltip text with a full stop This is our general convention for tooltips, it was just forgotten here. --- docs-master/keybindings/Keybindings_en.md | 2 +- docs-master/keybindings/Keybindings_ja.md | 2 +- docs-master/keybindings/Keybindings_ko.md | 2 +- docs-master/keybindings/Keybindings_nl.md | 2 +- docs-master/keybindings/Keybindings_pl.md | 2 +- docs-master/keybindings/Keybindings_pt.md | 2 +- docs-master/keybindings/Keybindings_ru.md | 2 +- docs-master/keybindings/Keybindings_zh-TW.md | 2 +- pkg/i18n/english.go | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs-master/keybindings/Keybindings_en.md b/docs-master/keybindings/Keybindings_en.md index d63058d82..d9970b0c5 100644 --- a/docs-master/keybindings/Keybindings_en.md +++ b/docs-master/keybindings/Keybindings_en.md @@ -22,7 +22,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` R `` | Refresh | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. | | `` + `` | Next screen mode (normal/half/fullscreen) | | | `` _ `` | Prev screen mode | | -| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers | +| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | | `` `` | Cancel | | | `` ? `` | Open keybindings menu | | | `` `` | View filter options | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/docs-master/keybindings/Keybindings_ja.md b/docs-master/keybindings/Keybindings_ja.md index d9b87d747..f9e06c00c 100644 --- a/docs-master/keybindings/Keybindings_ja.md +++ b/docs-master/keybindings/Keybindings_ja.md @@ -22,7 +22,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` R `` | 更新 | Gitの状態を更新します(`git status`、`git branch`などをバックグラウンドで実行してパネルの内容を更新します)。これは`git fetch`を実行しません。 | | `` + `` | 次の画面モード(通常/半分/全画面) | | | `` _ `` | 前の画面モード | | -| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers | +| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | | `` `` | キャンセル | | | `` ? `` | キーバインディングメニューを開く | | | `` `` | フィルターオプションを表示 | コミットログのフィルタリングオプションを表示し、フィルタに一致するコミットのみを表示します。 | diff --git a/docs-master/keybindings/Keybindings_ko.md b/docs-master/keybindings/Keybindings_ko.md index 089543c5f..d97537d2c 100644 --- a/docs-master/keybindings/Keybindings_ko.md +++ b/docs-master/keybindings/Keybindings_ko.md @@ -22,7 +22,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` R `` | 새로고침 | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. | | `` + `` | 다음 스크린 모드 (normal/half/fullscreen) | | | `` _ `` | 이전 스크린 모드 | | -| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers | +| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | | `` `` | 취소 | | | `` ? `` | 매뉴 열기 | | | `` `` | View filter-by-path options | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/docs-master/keybindings/Keybindings_nl.md b/docs-master/keybindings/Keybindings_nl.md index 1715c597e..bb5b19671 100644 --- a/docs-master/keybindings/Keybindings_nl.md +++ b/docs-master/keybindings/Keybindings_nl.md @@ -22,7 +22,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` R `` | Verversen | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. | | `` + `` | Volgende scherm modus (normaal/half/groot) | | | `` _ `` | Vorige scherm modus | | -| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers | +| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | | `` `` | Annuleren | | | `` ? `` | Open menu | | | `` `` | Bekijk scoping opties | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/docs-master/keybindings/Keybindings_pl.md b/docs-master/keybindings/Keybindings_pl.md index b032a6606..404a6fa37 100644 --- a/docs-master/keybindings/Keybindings_pl.md +++ b/docs-master/keybindings/Keybindings_pl.md @@ -22,7 +22,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` R `` | Odśwież | Odśwież stan git (tj. uruchom `git status`, `git branch`, itp. w tle, aby zaktualizować zawartość paneli). To nie uruchamia `git fetch`. | | `` + `` | Następny tryb ekranu (normalny/półpełny/pełnoekranowy) | | | `` _ `` | Poprzedni tryb ekranu | | -| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers | +| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | | `` `` | Anuluj | | | `` ? `` | Otwórz menu przypisań klawiszy | | | `` `` | Pokaż opcje filtrowania | Pokaż opcje filtrowania dziennika commitów, tak aby pokazywane były tylko commity pasujące do filtra. | diff --git a/docs-master/keybindings/Keybindings_pt.md b/docs-master/keybindings/Keybindings_pt.md index c19619191..bfe59c7d5 100644 --- a/docs-master/keybindings/Keybindings_pt.md +++ b/docs-master/keybindings/Keybindings_pt.md @@ -22,7 +22,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` R `` | Atualizar | Atualize o estado do git (ou seja, execute `git status`, `git branch`, etc em segundo plano para atualizar o conteúdo de painéis). Isso não executa `git fetch`. | | `` + `` | Modo de tela seguinte (normal/metade/tela cheia) | | | `` _ `` | Modo de tela anterior | | -| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers | +| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | | `` `` | Cancelar | | | `` ? `` | Abrir o menu de atalhos do teclado | | | `` `` | Ver opções de filtro | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/docs-master/keybindings/Keybindings_ru.md b/docs-master/keybindings/Keybindings_ru.md index c802678b3..344c37884 100644 --- a/docs-master/keybindings/Keybindings_ru.md +++ b/docs-master/keybindings/Keybindings_ru.md @@ -22,7 +22,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` R `` | Обновить | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. | | `` + `` | Следующий режим экрана (нормальный/полуэкранный/полноэкранный) | | | `` _ `` | Предыдущий режим экрана | | -| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers | +| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | | `` `` | Отменить | | | `` ? `` | Открыть меню | | | `` `` | Просмотреть параметры фильтрации по пути | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/docs-master/keybindings/Keybindings_zh-TW.md b/docs-master/keybindings/Keybindings_zh-TW.md index d6526b5b2..dcbb95b22 100644 --- a/docs-master/keybindings/Keybindings_zh-TW.md +++ b/docs-master/keybindings/Keybindings_zh-TW.md @@ -22,7 +22,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` R `` | 重新整理 | Refresh the git state (i.e. run `git status`, `git branch`, etc in background to update the contents of panels). This does not run `git fetch`. | | `` + `` | 下一個螢幕模式(常規/半螢幕/全螢幕) | | | `` _ `` | 上一個螢幕模式 | | -| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers | +| `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | | `` `` | 取消 | | | `` ? `` | 開啟選單 | | | `` `` | 檢視篩選路徑選項 | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index d112c0379..ef996a198 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -1737,7 +1737,7 @@ func EnglishTranslationSet() *TranslationSet { NextScreenMode: "Next screen mode (normal/half/fullscreen)", PrevScreenMode: "Prev screen mode", CyclePagers: "Cycle pagers", - CyclePagersTooltip: "Choose the next pager in the list of configured pagers", + CyclePagersTooltip: "Choose the next pager in the list of configured pagers.", CyclePagersDisabledReason: "No other pagers configured", StartSearch: "Search the current view by text", StartFilter: "Filter the current view by text", From 81420ce36204f5c4ff3764a330bfce1dddbe0634 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 7 Jun 2026 14:08:02 +0200 Subject: [PATCH 3/6] Reject pager entries that combine multiple diff mechanisms A pager (GIT_PAGER) formats the diff git produces, while externalDiffCommand and useExternalDiffGitConfig change how git produces the diff in the first place. They are different pipeline stages, not alternatives, so combining them on one entry just pipes one through the other and produces garbled output (e.g. delta trying to parse difftastic's side-by-side output as a unified diff). The two external mechanisms likewise conflict, with the explicit command silently shadowing the git config one. Treat all three as mutually exclusive and reject configs that set more than one on the same entry. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs-master/Config.md | 3 +++ docs-master/Custom_Pagers.md | 4 ++- pkg/config/user_config.go | 2 ++ pkg/config/user_config_validation.go | 27 ++++++++++++++++++++ pkg/config/user_config_validation_test.go | 31 +++++++++++++++++++++++ schema-master/config.json | 2 +- 6 files changed, 67 insertions(+), 2 deletions(-) diff --git a/docs-master/Config.md b/docs-master/Config.md index 9f7921821..6de2ad978 100644 --- a/docs-master/Config.md +++ b/docs-master/Config.md @@ -361,6 +361,9 @@ git: # # https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver. # useExternalDiffGitConfig: false # + # 'pager', 'externalDiffCommand', and 'useExternalDiffGitConfig' are mutually + # exclusive; set at most one per entry. + # # See https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md # for more information. pagers: [] diff --git a/docs-master/Custom_Pagers.md b/docs-master/Custom_Pagers.md index 903928d46..0bfffe7dc 100644 --- a/docs-master/Custom_Pagers.md +++ b/docs-master/Custom_Pagers.md @@ -71,7 +71,7 @@ git: - externalDiffCommand: difft --color=always ``` -The `colorArg` and `pager` options are not used in this case. +The `colorArg` option is not used in this case. You can add whatever extra arguments you prefer for your difftool; for instance @@ -91,6 +91,8 @@ git: This can be useful if you also want to use it for diffs on the command line, and it also has the advantage that you can configure it per file type in `.gitattributes`; see https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver. +`pager`, `externalDiffCommand`, and `useExternalDiffGitConfig` are alternative ways of producing the diff, so a pager entry may use at most one of them. + ## Emulating custom pagers on Windows There is a trick to emulate custom pagers on Windows using a Powershell script configured as an external diff command. It's not perfect, but certainly better than nothing. To do this, save the following script as `lazygit-pager.ps1` at a convenient place on your disk: diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index cac87ec91..acadc8e80 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -275,6 +275,8 @@ type GitConfig struct { // # https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver. // useExternalDiffGitConfig: false // + // 'pager', 'externalDiffCommand', and 'useExternalDiffGitConfig' are mutually exclusive; set at most one per entry. + // // See https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md for more information. Pagers []PagingConfig `yaml:"pagers"` // Config relating to committing diff --git a/pkg/config/user_config_validation.go b/pkg/config/user_config_validation.go index 163fc61c4..109b3f1d0 100644 --- a/pkg/config/user_config_validation.go +++ b/pkg/config/user_config_validation.go @@ -46,6 +46,9 @@ func (config *UserConfig) Validate() error { []string{"always", "never", "when-maximised"}); err != nil { return err } + if err := validatePagers(config.Git.Pagers); err != nil { + return err + } if err := validateKeybindings(config.Keybinding); err != nil { return err } @@ -71,6 +74,30 @@ func validateSpinner(spinner SpinnerConfig) error { return nil } +// validatePagers rejects pager entries that combine more than one diff +// mechanism. A pager (GIT_PAGER) formats the diff that git produces, whereas +// externalDiffCommand and useExternalDiffGitConfig change how git produces the +// diff in the first place; piping one through the other almost always yields +// garbled output, so we treat the three as mutually exclusive. +func validatePagers(pagers []PagingConfig) error { + for i, pager := range pagers { + count := 0 + if pager.Pager != "" { + count++ + } + if pager.ExternalDiffCommand != "" { + count++ + } + if pager.UseExternalDiffGitConfig { + count++ + } + if count > 1 { + return fmt.Errorf("git.pagers[%d]: at most one of 'pager', 'externalDiffCommand', and 'useExternalDiffGitConfig' may be set; they are mutually exclusive", i) + } + } + return nil +} + func validateEnum(name string, value string, allowedValues []string) error { if slices.Contains(allowedValues, value) { return nil diff --git a/pkg/config/user_config_validation_test.go b/pkg/config/user_config_validation_test.go index bb2d2580f..26c9b7145 100644 --- a/pkg/config/user_config_validation_test.go +++ b/pkg/config/user_config_validation_test.go @@ -323,3 +323,34 @@ func TestUserConfigValidate_spinnerFrames(t *testing.T) { }) } } + +func TestUserConfigValidate_pagers(t *testing.T) { + scenarios := []struct { + name string + pager PagingConfig + valid bool + }{ + {name: "empty", pager: PagingConfig{}, valid: true}, + {name: "pager only", pager: PagingConfig{Pager: "delta"}, valid: true}, + {name: "external diff command only", pager: PagingConfig{ExternalDiffCommand: "difft"}, valid: true}, + {name: "git config external diff only", pager: PagingConfig{UseExternalDiffGitConfig: true}, valid: true}, + {name: "pager and external diff command", pager: PagingConfig{Pager: "delta", ExternalDiffCommand: "difft"}, valid: false}, + {name: "pager and git config external diff", pager: PagingConfig{Pager: "delta", UseExternalDiffGitConfig: true}, valid: false}, + {name: "both external diff mechanisms", pager: PagingConfig{ExternalDiffCommand: "difft", UseExternalDiffGitConfig: true}, valid: false}, + {name: "all three", pager: PagingConfig{Pager: "delta", ExternalDiffCommand: "difft", UseExternalDiffGitConfig: true}, valid: false}, + } + + for _, s := range scenarios { + t.Run(s.name, func(t *testing.T) { + config := GetDefaultConfig() + config.Git.Pagers = []PagingConfig{s.pager} + err := config.Validate() + + if s.valid { + assert.NoError(t, err) + } else { + assert.Error(t, err) + } + }) + } +} diff --git a/schema-master/config.json b/schema-master/config.json index 2e968ba8f..9042986aa 100644 --- a/schema-master/config.json +++ b/schema-master/config.json @@ -321,7 +321,7 @@ "$ref": "#/$defs/PagingConfig" }, "type": "array", - "description": "Array of pagers. Each entry has the following format:\n\n # Value of the --color arg in the git diff command. Some pagers want\n # this to be set to 'always' and some want it set to 'never'\n colorArg: \"always\"\n\n # e.g.\n # diff-so-fancy\n # delta --dark --paging=never\n # ydiff -p cat -s --wrap --width={{columnWidth}}\n pager: \"\"\n\n # e.g. 'difft --color=always'\n externalDiffCommand: \"\"\n\n # If true, Lazygit will use git's `diff.external` config for paging.\n # The advantage over `externalDiffCommand` is that this can be\n # configured per file type in .gitattributes; see\n # https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver.\n useExternalDiffGitConfig: false\n\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md for more information." + "description": "Array of pagers. Each entry has the following format:\n\n # Value of the --color arg in the git diff command. Some pagers want\n # this to be set to 'always' and some want it set to 'never'\n colorArg: \"always\"\n\n # e.g.\n # diff-so-fancy\n # delta --dark --paging=never\n # ydiff -p cat -s --wrap --width={{columnWidth}}\n pager: \"\"\n\n # e.g. 'difft --color=always'\n externalDiffCommand: \"\"\n\n # If true, Lazygit will use git's `diff.external` config for paging.\n # The advantage over `externalDiffCommand` is that this can be\n # configured per file type in .gitattributes; see\n # https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver.\n useExternalDiffGitConfig: false\n\n'pager', 'externalDiffCommand', and 'useExternalDiffGitConfig' are mutually exclusive; set at most one per entry.\n\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md for more information." }, "commit": { "$ref": "#/$defs/CommitConfig", From 6316094d581f6501ca4a1980e32f94aadf3288df Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 7 Jun 2026 11:37:02 +0200 Subject: [PATCH 4/6] Show pager name in the cycle-pager toast, and let users name pagers When cycling pagers, "Selected pager 2 of 3" gives no clue which pager you landed on; with several configured you have to remember the order. Include the pager's name in the toast instead. The name is normally derived from the first word of the pager command, but that isn't always enough: two entries can share a command but differ in options (e.g. "delta" and "delta --side-by-side"), and an entry may have no command at all (the default entry, or when using useExternalDiffGitConfig). So add an optional `name` field that overrides the derived name. The message was also hardcoded in English; localize it while we're here. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs-master/Config.md | 5 +++ pkg/config/pager_config.go | 39 ++++++++++++++++ pkg/config/pager_config_test.go | 57 ++++++++++++++++++++++++ pkg/config/user_config.go | 7 +++ pkg/gui/controllers/global_controller.go | 20 +++++++-- pkg/i18n/english.go | 6 +++ schema-master/config.json | 6 ++- 7 files changed, 136 insertions(+), 4 deletions(-) create mode 100644 pkg/config/pager_config_test.go diff --git a/docs-master/Config.md b/docs-master/Config.md index 6de2ad978..07942c659 100644 --- a/docs-master/Config.md +++ b/docs-master/Config.md @@ -342,6 +342,11 @@ gui: git: # Array of pagers. Each entry has the following format: # + # # A name for the pager, shown in the notification when cycling pagers. + # # If not set, the name is derived from the first word of the pager + # # command (or of the external diff command). + # name: "" + # # # Value of the --color arg in the git diff command. Some pagers want # # this to be set to 'always' and some want it set to 'never' # colorArg: "always" diff --git a/pkg/config/pager_config.go b/pkg/config/pager_config.go index e721da0e8..1b562ccd7 100644 --- a/pkg/config/pager_config.go +++ b/pkg/config/pager_config.go @@ -2,6 +2,7 @@ package config import ( "strconv" + "strings" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -80,3 +81,41 @@ func (self *PagerConfig) CyclePagers() { func (self *PagerConfig) CurrentPagerIndex() (int, int) { return self.pagerIndex, len(self.getUserConfig().Git.Pagers) } + +// CurrentPagerName returns a name for the current pager, suitable for showing +// to the user. It returns an empty string if no name can be derived; callers +// should substitute a localized fallback in that case. +func (self *PagerConfig) CurrentPagerName() string { + currentPagerConfig := self.currentPagerConfig() + if currentPagerConfig == nil { + return "" + } + return currentPagerConfig.displayName() +} + +// CurrentPagerUsesGitConfigDiff reports whether the current pager defers to +// git's own external diff config. Such an entry has no name we can derive (the +// actual command may even vary per file via .gitattributes), so callers show a +// generic label rather than treating it like the default no-pager entry. +func (self *PagerConfig) CurrentPagerUsesGitConfigDiff() bool { + currentPagerConfig := self.currentPagerConfig() + return currentPagerConfig != nil && currentPagerConfig.UseExternalDiffGitConfig +} + +func (self *PagingConfig) displayName() string { + if self.Name != "" { + return self.Name + } + if word := firstWord(string(self.Pager)); word != "" { + return word + } + return firstWord(self.ExternalDiffCommand) +} + +func firstWord(command string) string { + fields := strings.Fields(command) + if len(fields) == 0 { + return "" + } + return fields[0] +} diff --git a/pkg/config/pager_config_test.go b/pkg/config/pager_config_test.go new file mode 100644 index 000000000..e2618d5bd --- /dev/null +++ b/pkg/config/pager_config_test.go @@ -0,0 +1,57 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestCurrentPagerName(t *testing.T) { + scenarios := []struct { + name string + pager PagingConfig + expected string + }{ + { + name: "explicit name takes precedence over the command", + pager: PagingConfig{Name: "delta side-by-side", Pager: "delta --side-by-side"}, + expected: "delta side-by-side", + }, + { + name: "derived from the first word of the pager command", + pager: PagingConfig{Pager: "delta --side-by-side"}, + expected: "delta", + }, + { + name: "surrounding whitespace in the command is ignored", + pager: PagingConfig{Pager: " diff-so-fancy "}, + expected: "diff-so-fancy", + }, + { + name: "falls back to the external diff command when there is no pager", + pager: PagingConfig{ExternalDiffCommand: "difft --color=always"}, + expected: "difft", + }, + { + name: "no name can be derived", + pager: PagingConfig{UseExternalDiffGitConfig: true}, + expected: "", + }, + } + + for _, s := range scenarios { + t.Run(s.name, func(t *testing.T) { + userConfig := &UserConfig{} + userConfig.Git.Pagers = []PagingConfig{s.pager} + config := NewPagerConfig(func() *UserConfig { return userConfig }) + + assert.Equal(t, s.expected, config.CurrentPagerName()) + }) + } +} + +func TestCurrentPagerNameWithoutPagers(t *testing.T) { + config := NewPagerConfig(func() *UserConfig { return &UserConfig{} }) + + assert.Equal(t, "", config.CurrentPagerName()) +} diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index acadc8e80..aa2d945d6 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -256,6 +256,11 @@ type GitConfig struct { // Array of pagers. Each entry has the following format: // [dev] The following documentation is duplicated from the PagingConfig struct below. // + // # A name for the pager, shown in the notification when cycling pagers. + // # If not set, the name is derived from the first word of the pager + // # command (or of the external diff command). + // name: "" + // // # Value of the --color arg in the git diff command. Some pagers want // # this to be set to 'always' and some want it set to 'never' // colorArg: "always" @@ -347,6 +352,8 @@ func (PagerType) JSONSchemaExtend(schema *jsonschema.Schema) { // [dev] This documentation is duplicated in the GitConfig struct. If you make changes here, make them there too. type PagingConfig struct { + // A name for the pager, shown in the notification when cycling pagers. If not set, the name is derived from the first word of the pager command (or of the external diff command). + Name string `yaml:"name"` // Value of the --color arg in the git diff command. Some pagers want this to be set to 'always' and some want it set to 'never' ColorArg string `yaml:"colorArg" jsonschema:"enum=always,enum=never"` // e.g. diff --git a/pkg/gui/controllers/global_controller.go b/pkg/gui/controllers/global_controller.go index d2ca28c60..7879ab7ac 100644 --- a/pkg/gui/controllers/global_controller.go +++ b/pkg/gui/controllers/global_controller.go @@ -1,10 +1,11 @@ package controllers import ( - "fmt" + "strconv" "github.com/jesseduffield/lazygit/pkg/gui/context" "github.com/jesseduffield/lazygit/pkg/gui/types" + "github.com/jesseduffield/lazygit/pkg/utils" ) type GlobalController struct { @@ -166,8 +167,21 @@ func (self *GlobalController) cyclePagers() error { currentSide.HandleRenderToMain() } - current, total := self.c.State().GetPagerConfig().CurrentPagerIndex() - self.c.Toast(fmt.Sprintf("Selected pager %d of %d", current+1, total)) + pagerConfig := self.c.State().GetPagerConfig() + current, total := pagerConfig.CurrentPagerIndex() + name := pagerConfig.CurrentPagerName() + if name == "" { + if pagerConfig.CurrentPagerUsesGitConfigDiff() { + name = self.c.Tr.ExternalDiffPagerName + } else { + name = self.c.Tr.DefaultPagerName + } + } + self.c.Toast(utils.ResolvePlaceholderString(self.c.Tr.SelectedPager, map[string]string{ + "name": name, + "current": strconv.Itoa(current + 1), + "total": strconv.Itoa(total), + })) return nil } diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index ef996a198..7ff5137f6 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -608,6 +608,9 @@ type TranslationSet struct { CyclePagers string CyclePagersTooltip string CyclePagersDisabledReason string + SelectedPager string + DefaultPagerName string + ExternalDiffPagerName string StartSearch string StartFilter string SelectRemoteRepository string @@ -1739,6 +1742,9 @@ func EnglishTranslationSet() *TranslationSet { CyclePagers: "Cycle pagers", CyclePagersTooltip: "Choose the next pager in the list of configured pagers.", CyclePagersDisabledReason: "No other pagers configured", + SelectedPager: "Pager: {{.name}} ({{.current}} of {{.total}})", + DefaultPagerName: "(default)", + ExternalDiffPagerName: "(external diff)", StartSearch: "Search the current view by text", StartFilter: "Filter the current view by text", SelectRemoteRepository: "Select base repository for pull requests", diff --git a/schema-master/config.json b/schema-master/config.json index 9042986aa..816c46213 100644 --- a/schema-master/config.json +++ b/schema-master/config.json @@ -321,7 +321,7 @@ "$ref": "#/$defs/PagingConfig" }, "type": "array", - "description": "Array of pagers. Each entry has the following format:\n\n # Value of the --color arg in the git diff command. Some pagers want\n # this to be set to 'always' and some want it set to 'never'\n colorArg: \"always\"\n\n # e.g.\n # diff-so-fancy\n # delta --dark --paging=never\n # ydiff -p cat -s --wrap --width={{columnWidth}}\n pager: \"\"\n\n # e.g. 'difft --color=always'\n externalDiffCommand: \"\"\n\n # If true, Lazygit will use git's `diff.external` config for paging.\n # The advantage over `externalDiffCommand` is that this can be\n # configured per file type in .gitattributes; see\n # https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver.\n useExternalDiffGitConfig: false\n\n'pager', 'externalDiffCommand', and 'useExternalDiffGitConfig' are mutually exclusive; set at most one per entry.\n\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md for more information." + "description": "Array of pagers. Each entry has the following format:\n\n # A name for the pager, shown in the notification when cycling pagers.\n # If not set, the name is derived from the first word of the pager\n # command (or of the external diff command).\n name: \"\"\n\n # Value of the --color arg in the git diff command. Some pagers want\n # this to be set to 'always' and some want it set to 'never'\n colorArg: \"always\"\n\n # e.g.\n # diff-so-fancy\n # delta --dark --paging=never\n # ydiff -p cat -s --wrap --width={{columnWidth}}\n pager: \"\"\n\n # e.g. 'difft --color=always'\n externalDiffCommand: \"\"\n\n # If true, Lazygit will use git's `diff.external` config for paging.\n # The advantage over `externalDiffCommand` is that this can be\n # configured per file type in .gitattributes; see\n # https://git-scm.com/docs/gitattributes#_defining_an_external_diff_driver.\n useExternalDiffGitConfig: false\n\n'pager', 'externalDiffCommand', and 'useExternalDiffGitConfig' are mutually exclusive; set at most one per entry.\n\nSee https://github.com/jesseduffield/lazygit/blob/master/docs/Custom_Pagers.md for more information." }, "commit": { "$ref": "#/$defs/CommitConfig", @@ -3488,6 +3488,10 @@ }, "PagingConfig": { "properties": { + "name": { + "type": "string", + "description": "A name for the pager, shown in the notification when cycling pagers. If not set, the name is derived from the first word of the pager command (or of the external diff command)." + }, "colorArg": { "type": "string", "enum": [ From 5a4247b234050b60a6d75dabae8c8fc361941431 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 7 Jun 2026 11:40:26 +0200 Subject: [PATCH 5/6] Extract onPagerChanged helper from cyclePagers A reverse-cycle handler is about to need the same re-render-and-toast logic. Pull it out first so the behavior change that follows only has to swap the cycle direction. Co-Authored-By: Claude Opus 4.8 (1M context) --- pkg/gui/controllers/global_controller.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pkg/gui/controllers/global_controller.go b/pkg/gui/controllers/global_controller.go index 7879ab7ac..4cd5730af 100644 --- a/pkg/gui/controllers/global_controller.go +++ b/pkg/gui/controllers/global_controller.go @@ -159,6 +159,13 @@ func (self *GlobalController) prevScreenMode() error { func (self *GlobalController) cyclePagers() error { self.c.State().GetPagerConfig().CyclePagers() + self.onPagerChanged() + return nil +} + +// onPagerChanged re-renders the main view so the newly selected pager takes +// effect, and shows a toast naming it. +func (self *GlobalController) onPagerChanged() { currentSide := self.c.Context().CurrentSide() currentKey := self.c.Context().Current().GetKey() if currentSide.GetKey() == currentKey || @@ -182,7 +189,6 @@ func (self *GlobalController) cyclePagers() error { "current": strconv.Itoa(current + 1), "total": strconv.Itoa(total), })) - return nil } func (self *GlobalController) canCyclePagers() *types.DisabledReason { From 8534a05a2ef469e2fe96ae1601c61bfe3b2a0c55 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Sun, 7 Jun 2026 11:48:22 +0200 Subject: [PATCH 6/6] Allow cycling pagers in reverse With more than a couple of pagers, having to cycle forward through all of them to reach the previous one (or to back out of an accidental press of `|`) is tedious. Add a second binding that cycles backward. Co-Authored-By: Claude Opus 4.8 (1M context) --- docs-master/Config.md | 1 + docs-master/keybindings/Keybindings_en.md | 1 + docs-master/keybindings/Keybindings_ja.md | 1 + docs-master/keybindings/Keybindings_ko.md | 1 + docs-master/keybindings/Keybindings_nl.md | 1 + docs-master/keybindings/Keybindings_pl.md | 1 + docs-master/keybindings/Keybindings_pt.md | 1 + docs-master/keybindings/Keybindings_ru.md | 1 + docs-master/keybindings/Keybindings_zh-CN.md | 1 + docs-master/keybindings/Keybindings_zh-TW.md | 1 + pkg/config/pager_config.go | 5 +++ pkg/config/pager_config_test.go | 25 +++++++++++ pkg/config/user_config.go | 2 + pkg/gui/controllers/global_controller.go | 13 ++++++ pkg/i18n/english.go | 4 ++ pkg/integration/tests/diff/cycle_pagers.go | 45 ++++++++++++++++++++ pkg/integration/tests/test_list.go | 1 + schema-master/config.json | 14 ++++++ 18 files changed, 119 insertions(+) create mode 100644 pkg/integration/tests/diff/cycle_pagers.go diff --git a/docs-master/Config.md b/docs-master/Config.md index 07942c659..fa6b3eeac 100644 --- a/docs-master/Config.md +++ b/docs-master/Config.md @@ -675,6 +675,7 @@ keybinding: nextScreenMode: + prevScreenMode: _ cyclePagers: '|' + cyclePagersReverse: \ undo: z redo: Z filteringMenu: diff --git a/docs-master/keybindings/Keybindings_en.md b/docs-master/keybindings/Keybindings_en.md index d9970b0c5..07d4d95a4 100644 --- a/docs-master/keybindings/Keybindings_en.md +++ b/docs-master/keybindings/Keybindings_en.md @@ -23,6 +23,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` + `` | Next screen mode (normal/half/fullscreen) | | | `` _ `` | Prev screen mode | | | `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | +| `` \ `` | Cycle pagers (reverse) | Choose the previous pager in the list of configured pagers. | | `` `` | Cancel | | | `` ? `` | Open keybindings menu | | | `` `` | View filter options | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/docs-master/keybindings/Keybindings_ja.md b/docs-master/keybindings/Keybindings_ja.md index f9e06c00c..5bf6797bd 100644 --- a/docs-master/keybindings/Keybindings_ja.md +++ b/docs-master/keybindings/Keybindings_ja.md @@ -23,6 +23,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` + `` | 次の画面モード(通常/半分/全画面) | | | `` _ `` | 前の画面モード | | | `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | +| `` \ `` | Cycle pagers (reverse) | Choose the previous pager in the list of configured pagers. | | `` `` | キャンセル | | | `` ? `` | キーバインディングメニューを開く | | | `` `` | フィルターオプションを表示 | コミットログのフィルタリングオプションを表示し、フィルタに一致するコミットのみを表示します。 | diff --git a/docs-master/keybindings/Keybindings_ko.md b/docs-master/keybindings/Keybindings_ko.md index d97537d2c..e80515daa 100644 --- a/docs-master/keybindings/Keybindings_ko.md +++ b/docs-master/keybindings/Keybindings_ko.md @@ -23,6 +23,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` + `` | 다음 스크린 모드 (normal/half/fullscreen) | | | `` _ `` | 이전 스크린 모드 | | | `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | +| `` \ `` | Cycle pagers (reverse) | Choose the previous pager in the list of configured pagers. | | `` `` | 취소 | | | `` ? `` | 매뉴 열기 | | | `` `` | View filter-by-path options | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/docs-master/keybindings/Keybindings_nl.md b/docs-master/keybindings/Keybindings_nl.md index bb5b19671..76764eda5 100644 --- a/docs-master/keybindings/Keybindings_nl.md +++ b/docs-master/keybindings/Keybindings_nl.md @@ -23,6 +23,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` + `` | Volgende scherm modus (normaal/half/groot) | | | `` _ `` | Vorige scherm modus | | | `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | +| `` \ `` | Cycle pagers (reverse) | Choose the previous pager in the list of configured pagers. | | `` `` | Annuleren | | | `` ? `` | Open menu | | | `` `` | Bekijk scoping opties | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/docs-master/keybindings/Keybindings_pl.md b/docs-master/keybindings/Keybindings_pl.md index 404a6fa37..aa510a813 100644 --- a/docs-master/keybindings/Keybindings_pl.md +++ b/docs-master/keybindings/Keybindings_pl.md @@ -23,6 +23,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` + `` | Następny tryb ekranu (normalny/półpełny/pełnoekranowy) | | | `` _ `` | Poprzedni tryb ekranu | | | `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | +| `` \ `` | Cycle pagers (reverse) | Choose the previous pager in the list of configured pagers. | | `` `` | Anuluj | | | `` ? `` | Otwórz menu przypisań klawiszy | | | `` `` | Pokaż opcje filtrowania | Pokaż opcje filtrowania dziennika commitów, tak aby pokazywane były tylko commity pasujące do filtra. | diff --git a/docs-master/keybindings/Keybindings_pt.md b/docs-master/keybindings/Keybindings_pt.md index bfe59c7d5..efe0d24ed 100644 --- a/docs-master/keybindings/Keybindings_pt.md +++ b/docs-master/keybindings/Keybindings_pt.md @@ -23,6 +23,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` + `` | Modo de tela seguinte (normal/metade/tela cheia) | | | `` _ `` | Modo de tela anterior | | | `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | +| `` \ `` | Cycle pagers (reverse) | Choose the previous pager in the list of configured pagers. | | `` `` | Cancelar | | | `` ? `` | Abrir o menu de atalhos do teclado | | | `` `` | Ver opções de filtro | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/docs-master/keybindings/Keybindings_ru.md b/docs-master/keybindings/Keybindings_ru.md index 344c37884..1f952ed6b 100644 --- a/docs-master/keybindings/Keybindings_ru.md +++ b/docs-master/keybindings/Keybindings_ru.md @@ -23,6 +23,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` + `` | Следующий режим экрана (нормальный/полуэкранный/полноэкранный) | | | `` _ `` | Предыдущий режим экрана | | | `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | +| `` \ `` | Cycle pagers (reverse) | Choose the previous pager in the list of configured pagers. | | `` `` | Отменить | | | `` ? `` | Открыть меню | | | `` `` | Просмотреть параметры фильтрации по пути | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/docs-master/keybindings/Keybindings_zh-CN.md b/docs-master/keybindings/Keybindings_zh-CN.md index 9cb7d5186..e1dbbe9c6 100644 --- a/docs-master/keybindings/Keybindings_zh-CN.md +++ b/docs-master/keybindings/Keybindings_zh-CN.md @@ -23,6 +23,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` + `` | 下一屏模式(正常/半屏/全屏) | | | `` _ `` | 上一屏模式 | | | `` \| `` | 切换分页器 | 从已配置的分页器列表中选择下一个分页器 | +| `` \ `` | Cycle pagers (reverse) | Choose the previous pager in the list of configured pagers. | | `` `` | 取消 | | | `` ? `` | 打开菜单 | | | `` `` | 查看按路径过滤选项 | 查看用于过滤提交日志的选项,以便仅显示与过滤器匹配的提交。 | diff --git a/docs-master/keybindings/Keybindings_zh-TW.md b/docs-master/keybindings/Keybindings_zh-TW.md index dcbb95b22..bf13db65d 100644 --- a/docs-master/keybindings/Keybindings_zh-TW.md +++ b/docs-master/keybindings/Keybindings_zh-TW.md @@ -23,6 +23,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` + `` | 下一個螢幕模式(常規/半螢幕/全螢幕) | | | `` _ `` | 上一個螢幕模式 | | | `` \| `` | Cycle pagers | Choose the next pager in the list of configured pagers. | +| `` \ `` | Cycle pagers (reverse) | Choose the previous pager in the list of configured pagers. | | `` `` | 取消 | | | `` ? `` | 開啟選單 | | | `` `` | 檢視篩選路徑選項 | View options for filtering the commit log, so that only commits matching the filter are shown. | diff --git a/pkg/config/pager_config.go b/pkg/config/pager_config.go index 1b562ccd7..d243a01b2 100644 --- a/pkg/config/pager_config.go +++ b/pkg/config/pager_config.go @@ -78,6 +78,11 @@ func (self *PagerConfig) CyclePagers() { self.pagerIndex = (self.pagerIndex + 1) % len(self.getUserConfig().Git.Pagers) } +func (self *PagerConfig) CyclePagersBackward() { + n := len(self.getUserConfig().Git.Pagers) + self.pagerIndex = (self.pagerIndex - 1 + n) % n +} + func (self *PagerConfig) CurrentPagerIndex() (int, int) { return self.pagerIndex, len(self.getUserConfig().Git.Pagers) } diff --git a/pkg/config/pager_config_test.go b/pkg/config/pager_config_test.go index e2618d5bd..7267b9228 100644 --- a/pkg/config/pager_config_test.go +++ b/pkg/config/pager_config_test.go @@ -55,3 +55,28 @@ func TestCurrentPagerNameWithoutPagers(t *testing.T) { assert.Equal(t, "", config.CurrentPagerName()) } + +func TestCyclePagers(t *testing.T) { + userConfig := &UserConfig{} + userConfig.Git.Pagers = []PagingConfig{{Name: "a"}, {Name: "b"}, {Name: "c"}} + config := NewPagerConfig(func() *UserConfig { return userConfig }) + + currentIndex := func() int { + index, _ := config.CurrentPagerIndex() + return index + } + + assert.Equal(t, 0, currentIndex()) + + config.CyclePagers() + assert.Equal(t, 1, currentIndex()) + config.CyclePagers() + assert.Equal(t, 2, currentIndex()) + config.CyclePagers() + assert.Equal(t, 0, currentIndex(), "cycling forward past the last pager wraps to the first") + + config.CyclePagersBackward() + assert.Equal(t, 2, currentIndex(), "cycling backward past the first pager wraps to the last") + config.CyclePagersBackward() + assert.Equal(t, 1, currentIndex()) +} diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index aa2d945d6..d1f760ed1 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -511,6 +511,7 @@ type KeybindingUniversalConfig struct { NextScreenMode Keybinding `yaml:"nextScreenMode"` PrevScreenMode Keybinding `yaml:"prevScreenMode"` CyclePagers Keybinding `yaml:"cyclePagers"` + CyclePagersReverse Keybinding `yaml:"cyclePagersReverse"` Undo Keybinding `yaml:"undo"` Redo Keybinding `yaml:"redo"` FilteringMenu Keybinding `yaml:"filteringMenu"` @@ -1019,6 +1020,7 @@ func GetDefaultConfigForPlatform(platform string) *UserConfig { NextScreenMode: Keybinding{"+"}, PrevScreenMode: Keybinding{"_"}, CyclePagers: Keybinding{"|"}, + CyclePagersReverse: Keybinding{"\\"}, Undo: Keybinding{"z"}, Redo: Keybinding{"Z"}, FilteringMenu: Keybinding{""}, diff --git a/pkg/gui/controllers/global_controller.go b/pkg/gui/controllers/global_controller.go index 4cd5730af..fdb2e3153 100644 --- a/pkg/gui/controllers/global_controller.go +++ b/pkg/gui/controllers/global_controller.go @@ -68,6 +68,13 @@ func (self *GlobalController) GetKeybindings(opts types.KeybindingsOpts) []*type Description: self.c.Tr.CyclePagers, Tooltip: self.c.Tr.CyclePagersTooltip, }, + { + Keys: opts.GetKeys(opts.Config.Universal.CyclePagersReverse), + Handler: opts.Guards.NoPopupPanel(self.cyclePagersBackward), + GetDisabledReason: self.canCyclePagers, + Description: self.c.Tr.CyclePagersReverse, + Tooltip: self.c.Tr.CyclePagersReverseTooltip, + }, { Keys: opts.GetKeys(opts.Config.Universal.Return), Handler: self.escape, @@ -163,6 +170,12 @@ func (self *GlobalController) cyclePagers() error { return nil } +func (self *GlobalController) cyclePagersBackward() error { + self.c.State().GetPagerConfig().CyclePagersBackward() + self.onPagerChanged() + return nil +} + // onPagerChanged re-renders the main view so the newly selected pager takes // effect, and shows a toast naming it. func (self *GlobalController) onPagerChanged() { diff --git a/pkg/i18n/english.go b/pkg/i18n/english.go index 7ff5137f6..20d0d5ff6 100644 --- a/pkg/i18n/english.go +++ b/pkg/i18n/english.go @@ -607,6 +607,8 @@ type TranslationSet struct { PrevScreenMode string CyclePagers string CyclePagersTooltip string + CyclePagersReverse string + CyclePagersReverseTooltip string CyclePagersDisabledReason string SelectedPager string DefaultPagerName string @@ -1741,6 +1743,8 @@ func EnglishTranslationSet() *TranslationSet { PrevScreenMode: "Prev screen mode", CyclePagers: "Cycle pagers", CyclePagersTooltip: "Choose the next pager in the list of configured pagers.", + CyclePagersReverse: "Cycle pagers (reverse)", + CyclePagersReverseTooltip: "Choose the previous pager in the list of configured pagers.", CyclePagersDisabledReason: "No other pagers configured", SelectedPager: "Pager: {{.name}} ({{.current}} of {{.total}})", DefaultPagerName: "(default)", diff --git a/pkg/integration/tests/diff/cycle_pagers.go b/pkg/integration/tests/diff/cycle_pagers.go new file mode 100644 index 000000000..2f2da9a5b --- /dev/null +++ b/pkg/integration/tests/diff/cycle_pagers.go @@ -0,0 +1,45 @@ +package diff + +import ( + "github.com/jesseduffield/lazygit/pkg/config" + . "github.com/jesseduffield/lazygit/pkg/integration/components" +) + +var CyclePagers = NewIntegrationTest(NewIntegrationTestArgs{ + Description: "Cycle forwards and backwards through configured pagers", + ExtraCmdArgs: []string{}, + Skip: false, + SetupConfig: func(cfg *config.AppConfig) { + cfg.GetUserConfig().Git.Pagers = []config.PagingConfig{ + // an explicit name overrides the derived one + {Name: "custom name", Pager: "cat"}, + // no name, so it's derived from the first word of the command + {Pager: "cat -n"}, + // neither name nor command, so it falls back to the default label + {}, + } + }, + SetupRepo: func(shell *Shell) { + shell.CreateNCommits(1) + }, + Run: func(t *TestDriver, keys config.KeybindingConfig) { + t.Views().Commits(). + Focus(). + Press(keys.Universal.CyclePagers) + t.ExpectToast(Equals("Pager: cat (2 of 3)")) + + t.Views().Commits().Press(keys.Universal.CyclePagers) + t.ExpectToast(Equals("Pager: (default) (3 of 3)")) + + // cycling forward past the last pager wraps around to the first + t.Views().Commits().Press(keys.Universal.CyclePagers) + t.ExpectToast(Equals("Pager: custom name (1 of 3)")) + + // cycling backward past the first pager wraps around to the last + t.Views().Commits().Press(keys.Universal.CyclePagersReverse) + t.ExpectToast(Equals("Pager: (default) (3 of 3)")) + + t.Views().Commits().Press(keys.Universal.CyclePagersReverse) + t.ExpectToast(Equals("Pager: cat (2 of 3)")) + }, +}) diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go index 0f3a40634..1b264e50d 100644 --- a/pkg/integration/tests/test_list.go +++ b/pkg/integration/tests/test_list.go @@ -210,6 +210,7 @@ var tests = []*components.IntegrationTest{ demo.Undo, demo.WorktreeCreateFromBranches, diff.CopyToClipboard, + diff.CyclePagers, diff.Diff, diff.DiffAndApplyPatch, diff.DiffCommits, diff --git a/schema-master/config.json b/schema-master/config.json index 816c46213..b95c5c980 100644 --- a/schema-master/config.json +++ b/schema-master/config.json @@ -3127,6 +3127,20 @@ ], "default": "|" }, + "cyclePagersReverse": { + "oneOf": [ + { + "type": "string" + }, + { + "items": { + "type": "string" + }, + "type": "array" + } + ], + "default": "\\" + }, "undo": { "oneOf": [ {