From 022d24cb79589f3a6933c1a0b2103c87c21731ca Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 4 May 2026 09:03:15 +0200 Subject: [PATCH] Fold legacy quit-alt1 into the multi-key quit binding Now that quit accepts multiple keys, the historical quit-alt1 field is redundant: existing configs that set it should keep working without the user having to migrate, but the lazygit code shouldn't have to register the alt binding separately. Add a merge step that runs after the user config is loaded (and from NewDummyAppConfig, which the cheatsheet generator and integration tests go through) folding the alt value into the main key list. Mark QuitAlt1 deprecated so it disappears from the generated Config.md example, while staying in the JSON schema with a description so editors can still steer users toward the new form. Note that instead of marking the alt config as deprecated, we could have added a migrator that changes users' config files and gets rid of the alt config for good. I decided not to do that, because this would render the config file invalid for older versions of lazygit, which would then refuse to start; and that's annoying when bisecting bugs. We'll keep the deprecated configs in the code for a year or so, and then add the migrator. The next commit will fold the remaining ~15 -alt-style fields the same way; the helper is shaped to keep that mechanical. --- docs-master/Config.md | 3 +- 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-CN.md | 2 +- docs-master/keybindings/Keybindings_zh-TW.md | 2 +- pkg/config/app_config.go | 1 + pkg/config/dummies.go | 4 +- pkg/config/keybinding.go | 6 +++ pkg/config/keybinding_test.go | 53 ++++++++++++++++++++ pkg/config/user_config.go | 11 +++- pkg/gui/controllers/global_controller.go | 4 -- pkg/jsonschema/generate.go | 1 + schema-master/config.json | 6 ++- 18 files changed, 89 insertions(+), 18 deletions(-) diff --git a/docs-master/Config.md b/docs-master/Config.md index 4e9a4617a..dd0a7dd11 100644 --- a/docs-master/Config.md +++ b/docs-master/Config.md @@ -597,8 +597,7 @@ promptToReturnFromSubprocess: true # for the syntax. keybinding: universal: - quit: q - quit-alt1: + quit: [q, ] suspendApp: return: quitWithoutChangingDirectory: Q diff --git a/docs-master/keybindings/Keybindings_en.md b/docs-master/keybindings/Keybindings_en.md index 74dbcc97d..8191c6b8b 100644 --- a/docs-master/keybindings/Keybindings_en.md +++ b/docs-master/keybindings/Keybindings_en.md @@ -28,7 +28,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` `` | View filter options | View options for filtering the commit log, so that only commits matching the filter are shown. | | `` W `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | -| `` q `` | Quit | | +| `` q, `` | Quit | | | `` `` | Suspend the application | | | `` `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | Undo | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. | diff --git a/docs-master/keybindings/Keybindings_ja.md b/docs-master/keybindings/Keybindings_ja.md index f06f1a0bf..0d51ebe7f 100644 --- a/docs-master/keybindings/Keybindings_ja.md +++ b/docs-master/keybindings/Keybindings_ja.md @@ -28,7 +28,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` `` | フィルターオプションを表示 | コミットログのフィルタリングオプションを表示し、フィルタに一致するコミットのみを表示します。 | | `` W `` | 差分オプションを表示 | 2つのrefの差分に関連するオプションを表示します(例:選択したrefとの差分表示、差分を取るrefの入力、差分方向の反転など)。 | | `` `` | 差分オプションを表示 | 2つのrefの差分に関連するオプションを表示します(例:選択したrefとの差分表示、差分を取るrefの入力、差分方向の反転など)。 | -| `` q `` | 終了 | | +| `` q, `` | 終了 | | | `` `` | Suspend the application | | | `` `` | 空白表示の切り替え | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | 元に戻す | 最後のgitコマンドを元に戻すために実行するgitコマンドを決定するためにreflogが使用されます。これにはワーキングツリーへの変更は含まれません。コミットのみが考慮されます。 | diff --git a/docs-master/keybindings/Keybindings_ko.md b/docs-master/keybindings/Keybindings_ko.md index 2b96d0aa8..d183f82de 100644 --- a/docs-master/keybindings/Keybindings_ko.md +++ b/docs-master/keybindings/Keybindings_ko.md @@ -28,7 +28,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` `` | View filter-by-path options | View options for filtering the commit log, so that only commits matching the filter are shown. | | `` W `` | Diff 메뉴 열기 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` `` | Diff 메뉴 열기 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | -| `` q `` | 종료 | | +| `` q, `` | 종료 | | | `` `` | Suspend the application | | | `` `` | 공백문자를 Diff 뷰에서 표시 여부 전환 | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | 되돌리기 (reflog) (실험적) | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. | diff --git a/docs-master/keybindings/Keybindings_nl.md b/docs-master/keybindings/Keybindings_nl.md index f048e2a2c..8b01ad9da 100644 --- a/docs-master/keybindings/Keybindings_nl.md +++ b/docs-master/keybindings/Keybindings_nl.md @@ -28,7 +28,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` `` | Bekijk scoping opties | View options for filtering the commit log, so that only commits matching the filter are shown. | | `` W `` | Open diff menu | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` `` | Open diff menu | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | -| `` q `` | Quit | | +| `` q, `` | Quit | | | `` `` | Suspend the application | | | `` `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | Ongedaan maken (via reflog) (experimenteel) | The reflog will be used to determine what git command to run to undo the last git command. This does not include changes to the working tree; only commits are taken into consideration. | diff --git a/docs-master/keybindings/Keybindings_pl.md b/docs-master/keybindings/Keybindings_pl.md index fcde7bfb4..36d3c58a2 100644 --- a/docs-master/keybindings/Keybindings_pl.md +++ b/docs-master/keybindings/Keybindings_pl.md @@ -28,7 +28,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` `` | Pokaż opcje filtrowania | Pokaż opcje filtrowania dziennika commitów, tak aby pokazywane były tylko commity pasujące do filtra. | | `` W `` | Pokaż opcje różnicowania | Pokaż opcje dotyczące różnicowania dwóch refów, np. różnicowanie względem wybranego refa, wprowadzanie refa do różnicowania i odwracanie kierunku różnic. | | `` `` | Pokaż opcje różnicowania | Pokaż opcje dotyczące różnicowania dwóch refów, np. różnicowanie względem wybranego refa, wprowadzanie refa do różnicowania i odwracanie kierunku różnic. | -| `` q `` | Wyjdź | | +| `` q, `` | Wyjdź | | | `` `` | Suspend the application | | | `` `` | Przełącz białe znaki | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | Cofnij | Dziennik reflog zostanie użyty do określenia, jakie polecenie git należy uruchomić, aby cofnąć ostatnie polecenie git. Nie obejmuje to zmian w drzewie roboczym; brane są pod uwagę tylko commity. | diff --git a/docs-master/keybindings/Keybindings_pt.md b/docs-master/keybindings/Keybindings_pt.md index 1aacc5722..17835d1a4 100644 --- a/docs-master/keybindings/Keybindings_pt.md +++ b/docs-master/keybindings/Keybindings_pt.md @@ -28,7 +28,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` `` | Ver opções de filtro | View options for filtering the commit log, so that only commits matching the filter are shown. | | `` W `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` `` | View diffing options | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | -| `` q `` | Sair | | +| `` q, `` | Sair | | | `` `` | Suspender a aplicação | | | `` `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | Desfazer | O reflog será usado para determinar qual comando git para executar para desfazer o último comando git. Isto não inclui mudanças na árvore de trabalho; apenas compromissos são tidos em consideração. | diff --git a/docs-master/keybindings/Keybindings_ru.md b/docs-master/keybindings/Keybindings_ru.md index 0dcb6753e..538a05ef0 100644 --- a/docs-master/keybindings/Keybindings_ru.md +++ b/docs-master/keybindings/Keybindings_ru.md @@ -28,7 +28,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` `` | Просмотреть параметры фильтрации по пути | View options for filtering the commit log, so that only commits matching the filter are shown. | | `` W `` | Открыть меню сравнении | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` `` | Открыть меню сравнении | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | -| `` q `` | Выйти | | +| `` q, `` | Выйти | | | `` `` | Suspend the application | | | `` `` | Переключить отображение изменении пробелов в просмотрщике сравнении | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | Отменить (через reflog) (экспериментальный) | Журнал ссылок (reflog) будет использоваться для определения того, какую команду git запустить, чтобы отменить последнюю команду git. Сюда не входят изменения в рабочем дереве; учитываются только коммиты. | diff --git a/docs-master/keybindings/Keybindings_zh-CN.md b/docs-master/keybindings/Keybindings_zh-CN.md index d78572f1b..b144b08cd 100644 --- a/docs-master/keybindings/Keybindings_zh-CN.md +++ b/docs-master/keybindings/Keybindings_zh-CN.md @@ -28,7 +28,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` `` | 查看按路径过滤选项 | 查看用于过滤提交日志的选项,以便仅显示与过滤器匹配的提交。 | | `` W `` | 打开 diff 菜单 | 查看与比较两个引用相关的选项,例如与选定的 ref 进行比较,输入要比较的 ref,然后反转比较方向。 | | `` `` | 打开 diff 菜单 | 查看与比较两个引用相关的选项,例如与选定的 ref 进行比较,输入要比较的 ref,然后反转比较方向。 | -| `` q `` | 退出 | | +| `` q, `` | 退出 | | | `` `` | 挂起应用程序 | | | `` `` | 切换是否在差异视图中显示空白字符差异 | 切换是否在差异视图中显示空白字符更改。

默认值可在配置文件中通过键 'git.ignoreWhitespaceInDiffView' 更改。 | | `` z `` | 撤销 | Reflog将用于确定运行哪个git命令来撤消最后一个git命令。这并不包括对工作树的更改,只考虑提交。 | diff --git a/docs-master/keybindings/Keybindings_zh-TW.md b/docs-master/keybindings/Keybindings_zh-TW.md index 70294eab9..5e7892bd9 100644 --- a/docs-master/keybindings/Keybindings_zh-TW.md +++ b/docs-master/keybindings/Keybindings_zh-TW.md @@ -28,7 +28,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct | `` `` | 檢視篩選路徑選項 | View options for filtering the commit log, so that only commits matching the filter are shown. | | `` W `` | 開啟差異比較選單 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | | `` `` | 開啟差異比較選單 | View options relating to diffing two refs e.g. diffing against selected ref, entering ref to diff against, and reversing the diff direction. | -| `` q `` | 結束 | | +| `` q, `` | 結束 | | | `` `` | Suspend the application | | | `` `` | 切換是否在差異檢視中顯示空格變更 | Toggle whether or not whitespace changes are shown in the diff view.

The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. | | `` z `` | 復原 | 將使用 reflog 確任 git 指令以復原。這不包括工作區更改;只考慮提交。 | diff --git a/pkg/config/app_config.go b/pkg/config/app_config.go index 27ee38c0b..e7267158a 100644 --- a/pkg/config/app_config.go +++ b/pkg/config/app_config.go @@ -203,6 +203,7 @@ func loadUserConfig(configFiles []*ConfigFile, base *UserConfig, isGuiInitialize } } + base.Keybinding.MergeLegacyAltKeybindings() return base, nil } diff --git a/pkg/config/dummies.go b/pkg/config/dummies.go index 06c8755a6..5bc349fa0 100644 --- a/pkg/config/dummies.go +++ b/pkg/config/dummies.go @@ -6,11 +6,13 @@ import ( // NewDummyAppConfig creates a new dummy AppConfig for testing func NewDummyAppConfig() *AppConfig { + userConfig := GetDefaultConfig() + userConfig.Keybinding.MergeLegacyAltKeybindings() appConfig := &AppConfig{ name: "lazygit", version: "unversioned", debug: false, - userConfig: GetDefaultConfig(), + userConfig: userConfig, appState: &AppState{}, } _ = yaml.Unmarshal([]byte{}, appConfig.appState) diff --git a/pkg/config/keybinding.go b/pkg/config/keybinding.go index f552707e5..905bc2bd7 100644 --- a/pkg/config/keybinding.go +++ b/pkg/config/keybinding.go @@ -84,3 +84,9 @@ func (Keybinding) JSONSchema() *jsonschema.Schema { }, } } + +// mergeLegacyAlt folds a deprecated `*Alt*` field into the corresponding +// multi-key main field. +func mergeLegacyAlt(main *Keybinding, alt Keybinding) { + *main = lo.Union(*main, alt) +} diff --git a/pkg/config/keybinding_test.go b/pkg/config/keybinding_test.go index a0bff786c..be9f15acb 100644 --- a/pkg/config/keybinding_test.go +++ b/pkg/config/keybinding_test.go @@ -135,6 +135,59 @@ func TestKeybindingMarshalJSON(t *testing.T) { } } +func TestMergeLegacyAltKeybindings(t *testing.T) { + scenarios := []struct { + name string + quit Keybinding + quitAlt1 Keybinding + expected Keybinding + }{ + { + name: "alt is folded into main", + quit: Keybinding{"q"}, + quitAlt1: Keybinding{""}, + expected: Keybinding{"q", ""}, + }, + { + name: "alt is not appended if already present", + quit: Keybinding{"q", ""}, + quitAlt1: Keybinding{""}, + expected: Keybinding{"q", ""}, + }, + { + name: "empty alt is ignored", + quit: Keybinding{"q"}, + quitAlt1: nil, + expected: Keybinding{"q"}, + }, + { + name: "user-supplied multi-key main is preserved", + quit: Keybinding{"q", ""}, + quitAlt1: Keybinding{""}, + expected: Keybinding{"q", "", ""}, + }, + { + name: "multi-key alt is folded element by element", + quit: Keybinding{"q"}, + quitAlt1: Keybinding{"", ""}, + expected: Keybinding{"q", "", ""}, + }, + } + + for _, s := range scenarios { + t.Run(s.name, func(t *testing.T) { + cfg := KeybindingConfig{ + Universal: KeybindingUniversalConfig{ + Quit: s.quit, + QuitAlt1: s.quitAlt1, + }, + } + cfg.MergeLegacyAltKeybindings() + assert.Equal(t, s.expected, cfg.Universal.Quit) + }) + } +} + func TestKeybindingYAMLRoundTrip(t *testing.T) { scenarios := []Keybinding{ {"q"}, diff --git a/pkg/config/user_config.go b/pkg/config/user_config.go index 6461ece75..a5525804d 100644 --- a/pkg/config/user_config.go +++ b/pkg/config/user_config.go @@ -423,7 +423,8 @@ type KeybindingConfig struct { // damn looks like we have some inconsistencies here with -alt and -alt1 type KeybindingUniversalConfig struct { - Quit Keybinding `yaml:"quit"` + Quit Keybinding `yaml:"quit"` + // Deprecated: add the key to `quit` instead. QuitAlt1 Keybinding `yaml:"quit-alt1"` SuspendApp Keybinding `yaml:"suspendApp"` Return Keybinding `yaml:"return"` @@ -769,6 +770,14 @@ type IconProperties struct { Color string `yaml:"color"` } +// MergeLegacyAltKeybindings folds deprecated `*Alt*` fields into their +// corresponding multi-key main field. New code should treat the main field +// as the single source of truth; the alt fields will be removed in a future +// release. +func (c *KeybindingConfig) MergeLegacyAltKeybindings() { + mergeLegacyAlt(&c.Universal.Quit, c.Universal.QuitAlt1) +} + func GetDefaultConfig() *UserConfig { // This is only for tests; we don't want to use the test runner's host platform in that case, // but always use the fallback bindings diff --git a/pkg/gui/controllers/global_controller.go b/pkg/gui/controllers/global_controller.go index 5528e10e7..8e5013a55 100644 --- a/pkg/gui/controllers/global_controller.go +++ b/pkg/gui/controllers/global_controller.go @@ -111,10 +111,6 @@ func (self *GlobalController) GetKeybindings(opts types.KeybindingsOpts) []*type Description: self.c.Tr.Quit, Handler: self.quit, }, - { - Keys: opts.GetKeys(opts.Config.Universal.QuitAlt1), - Handler: self.quit, - }, { Keys: opts.GetKeys(opts.Config.Universal.QuitWithoutChangingDirectory), Handler: self.quitWithoutChangingDirectory, diff --git a/pkg/jsonschema/generate.go b/pkg/jsonschema/generate.go index 414756b50..dc5045025 100644 --- a/pkg/jsonschema/generate.go +++ b/pkg/jsonschema/generate.go @@ -60,6 +60,7 @@ func customReflect(v *config.UserConfig) *jsonschema.Schema { schema := r.Reflect(v) inlineKeybindingRefs(schema) defaultConfig := config.GetDefaultConfig() + defaultConfig.Keybinding.MergeLegacyAltKeybindings() userConfigSchema := schema.Definitions["UserConfig"] defaultValue := reflect.ValueOf(defaultConfig).Elem() diff --git a/schema-master/config.json b/schema-master/config.json index 1f6e9e7d8..a33e20f2d 100644 --- a/schema-master/config.json +++ b/schema-master/config.json @@ -2125,7 +2125,10 @@ "type": "array" } ], - "default": "q" + "default": [ + "q", + "\u003cctrl+c\u003e" + ] }, "quit-alt1": { "oneOf": [ @@ -2139,6 +2142,7 @@ "type": "array" } ], + "description": "Deprecated: add the key to `quit` instead.", "default": "\u003cctrl+c\u003e" }, "suspendApp": {