Add a keybinding for toggling mouse capture at runtime (%)

Some terminals provide a modifier key that bypasses mouse capture so
that text can be selected with the mouse and copied to the clipboard
(option in iTerm, shift in Ghostty), but others don't (e.g. the
terminals built into VS Code and Zed). In those, selecting text
requires setting gui.mouseEvents to false in the config file and back
again afterwards, which is inconvenient.

Add a global keybinding (% by default) that toggles mouse capture on
the fly. Like the whitespace toggle, it flips the in-memory config
value, so the toggled state lasts until the config file is changed and
reloaded.

The key needs to be free in every panel, and % is; as a plain rune it
also arrives reliably in every terminal on all platforms, and it can't
fire while typing in a text prompt, since editors consume plain runes.
An alt-based binding would have been more mnemonic, but doesn't reach
lazygit in the built-in terminals of VS Code and Zed on macOS (the
very terminals that need this feature) unless the option key is
configured to act as meta; and a ctrl-based binding would burn one of
the few remaining free ctrl keys, which are better saved for future
features that get used more frequently.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Stefan Haller
2026-07-10 17:21:18 +02:00
co-authored by Claude Fable 5
parent a61727cd5e
commit e81cfdba33
16 changed files with 80 additions and 1 deletions
+3
View File
@@ -73,6 +73,8 @@ gui:
# If true, capture mouse events.
# When mouse events are captured, it's a little harder to select text: e.g.
# requiring you to hold the option key when on macOS.
# Mouse capture can also be toggled at runtime with the 'toggleMouseCapture'
# keybinding ('%' by default).
mouseEvents: true
# If true, do not show a warning when amending a commit.
@@ -725,6 +727,7 @@ keybinding:
submitEditorText: <enter>
extrasMenu: '@'
toggleWhitespaceInDiffView: <ctrl+w>
toggleMouseCapture: '%'
increaseContextInDiffView: '}'
decreaseContextInDiffView: '{'
increaseRenameSimilarityThreshold: )
@@ -31,6 +31,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
| `` q, <ctrl+c> `` | Quit | |
| `` <ctrl+z> `` | Suspend the application | |
| `` <ctrl+w> `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` % `` | Toggle mouse capture | Toggle whether lazygit captures mouse events. When mouse capture is off, the terminal handles the mouse, so you can select text with it; this is useful in terminals that don't have a modifier key to bypass the capture.<br><br>The default can be changed in the config file with the key 'gui.mouseEvents'. |
| `` <alt+shift+c> `` | Edit config file | Open file in external editor. |
| `` 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. |
| `` Z `` | Redo | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
@@ -31,6 +31,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
| `` q, <ctrl+c> `` | 終了 | |
| `` <ctrl+z> `` | Suspend the application | |
| `` <ctrl+w> `` | 空白表示の切り替え | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` % `` | Toggle mouse capture | Toggle whether lazygit captures mouse events. When mouse capture is off, the terminal handles the mouse, so you can select text with it; this is useful in terminals that don't have a modifier key to bypass the capture.<br><br>The default can be changed in the config file with the key 'gui.mouseEvents'. |
| `` <alt+shift+c> `` | 設定ファイルを編集 | 外部エディタでファイルを開きます。 |
| `` z `` | 元に戻す | 最後のgitコマンドを元に戻すために実行するgitコマンドを決定するためにreflogが使用されます。これにはワーキングツリーへの変更は含まれません。コミットのみが考慮されます。 |
| `` Z `` | やり直す | 最後のgitコマンドをやり直すために実行するgitコマンドを決定するためにreflogが使用されます。これにはワーキングツリーへの変更は含まれません。コミットのみが考慮されます。 |
@@ -31,6 +31,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
| `` q, <ctrl+c> `` | 종료 | |
| `` <ctrl+z> `` | Suspend the application | |
| `` <ctrl+w> `` | 공백문자를 Diff 뷰에서 표시 여부 전환 | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` % `` | Toggle mouse capture | Toggle whether lazygit captures mouse events. When mouse capture is off, the terminal handles the mouse, so you can select text with it; this is useful in terminals that don't have a modifier key to bypass the capture.<br><br>The default can be changed in the config file with the key 'gui.mouseEvents'. |
| `` <alt+shift+c> `` | 설정 파일 수정 | Open file in external editor. |
| `` 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. |
| `` Z `` | 다시 실행 (reflog) (실험적) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
@@ -31,6 +31,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
| `` q, <ctrl+c> `` | Afsluiten | |
| `` <ctrl+z> `` | Pauzeer de applicatie | |
| `` <ctrl+w> `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` % `` | Toggle mouse capture | Toggle whether lazygit captures mouse events. When mouse capture is off, the terminal handles the mouse, so you can select text with it; this is useful in terminals that don't have a modifier key to bypass the capture.<br><br>The default can be changed in the config file with the key 'gui.mouseEvents'. |
| `` <alt+shift+c> `` | Verander config bestand | Open bestand in externe editor. |
| `` 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. |
| `` Z `` | Redo (via reflog) (experimenteel) | The reflog will be used to determine what git command to run to redo the last git command. This does not include changes to the working tree; only commits are taken into consideration. |
@@ -31,6 +31,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
| `` q, <ctrl+c> `` | Wyjdź | |
| `` <ctrl+z> `` | Suspend the application | |
| `` <ctrl+w> `` | Przełącz białe znaki | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` % `` | Toggle mouse capture | Toggle whether lazygit captures mouse events. When mouse capture is off, the terminal handles the mouse, so you can select text with it; this is useful in terminals that don't have a modifier key to bypass the capture.<br><br>The default can be changed in the config file with the key 'gui.mouseEvents'. |
| `` <alt+shift+c> `` | Edytuj plik konfiguracyjny | Otwórz plik w zewnętrznym edytorze. |
| `` 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. |
| `` Z `` | Ponów | Dziennik reflog zostanie użyty do określenia, jakie polecenie git należy uruchomić, aby ponowić ostatnie polecenie git. Nie obejmuje to zmian w drzewie roboczym; brane są pod uwagę tylko commity. |
@@ -31,6 +31,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
| `` q, <ctrl+c> `` | Sair | |
| `` <ctrl+z> `` | Suspender a aplicação | |
| `` <ctrl+w> `` | Toggle whitespace | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` % `` | Toggle mouse capture | Toggle whether lazygit captures mouse events. When mouse capture is off, the terminal handles the mouse, so you can select text with it; this is useful in terminals that don't have a modifier key to bypass the capture.<br><br>The default can be changed in the config file with the key 'gui.mouseEvents'. |
| `` <alt+shift+c> `` | Editar arquivo de configuração | Abrir arquivo no editor externo. |
| `` 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. |
| `` Z `` | Refazer | O reflog será usado para determinar qual comando git para executar para refazer o último comando git. Isto não inclui mudanças na árvore de trabalho; apenas compromissos são tidos em consideração. |
@@ -31,6 +31,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
| `` q, <ctrl+c> `` | Выйти | |
| `` <ctrl+z> `` | Suspend the application | |
| `` <ctrl+w> `` | Переключить отображение изменении пробелов в просмотрщике сравнении | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` % `` | Toggle mouse capture | Toggle whether lazygit captures mouse events. When mouse capture is off, the terminal handles the mouse, so you can select text with it; this is useful in terminals that don't have a modifier key to bypass the capture.<br><br>The default can be changed in the config file with the key 'gui.mouseEvents'. |
| `` <alt+shift+c> `` | Редактировать файл конфигурации | Open file in external editor. |
| `` z `` | Отменить (через reflog) (экспериментальный) | Журнал ссылок (reflog) будет использоваться для определения того, какую команду git запустить, чтобы отменить последнюю команду git. Сюда не входят изменения в рабочем дереве; учитываются только коммиты. |
| `` Z `` | Повторить (через reflog) (экспериментальный) | Журнал ссылок (reflog) будет использоваться для определения того, какую команду git нужно запустить, чтобы повторить последнюю команду git. Сюда не входят изменения в рабочем дереве; учитываются только коммиты. |
@@ -31,6 +31,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
| `` q, <ctrl+c> `` | 退出 | |
| `` <ctrl+z> `` | 挂起应用程序 | |
| `` <ctrl+w> `` | 切换是否在差异视图中显示空白字符差异 | 切换是否在差异视图中显示空白字符更改。<br><br>默认值可在配置文件中通过键 'git.ignoreWhitespaceInDiffView' 更改。 |
| `` % `` | Toggle mouse capture | Toggle whether lazygit captures mouse events. When mouse capture is off, the terminal handles the mouse, so you can select text with it; this is useful in terminals that don't have a modifier key to bypass the capture.<br><br>The default can be changed in the config file with the key 'gui.mouseEvents'. |
| `` <alt+shift+c> `` | 编辑配置文件 | 使用外部编辑器打开文件 |
| `` z `` | 撤销 | Reflog将用于确定运行哪个git命令来撤消最后一个git命令。这并不包括对工作树的更改,只考虑提交。 |
| `` Z `` | 重做 | Reflog将用于确定运行哪个git命令来重做上一个git命令。这并不包括对工作树的更改,只考虑提交。 |
@@ -31,6 +31,7 @@ _This file is auto-generated. To update, make the changes in the pkg/i18n direct
| `` q, <ctrl+c> `` | 結束 | |
| `` <ctrl+z> `` | Suspend the application | |
| `` <ctrl+w> `` | 切換是否在差異檢視中顯示空格變更 | Toggle whether or not whitespace changes are shown in the diff view.<br><br>The default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'. |
| `` % `` | Toggle mouse capture | Toggle whether lazygit captures mouse events. When mouse capture is off, the terminal handles the mouse, so you can select text with it; this is useful in terminals that don't have a modifier key to bypass the capture.<br><br>The default can be changed in the config file with the key 'gui.mouseEvents'. |
| `` <alt+shift+c> `` | 編輯設定檔案 | 使用外部編輯器開啟 |
| `` z `` | 復原 | 將使用 reflog 確任 git 指令以復原。這不包括工作區更改;只考慮提交。 |
| `` Z `` | 取消復原 | 將使用 reflog 確任 git 指令以重作。這不包括工作區更改;只考慮提交。 |
+3
View File
@@ -91,6 +91,7 @@ type GuiConfig struct {
TabWidth int `yaml:"tabWidth" jsonschema:"minimum=1"`
// If true, capture mouse events.
// When mouse events are captured, it's a little harder to select text: e.g. requiring you to hold the option key when on macOS.
// Mouse capture can also be toggled at runtime with the 'toggleMouseCapture' keybinding ('%' by default).
MouseEvents bool `yaml:"mouseEvents"`
// If true, do not show a warning when amending a commit.
SkipAmendWarning bool `yaml:"skipAmendWarning"`
@@ -548,6 +549,7 @@ type KeybindingUniversalConfig struct {
SubmitEditorText Keybinding `yaml:"submitEditorText"`
ExtrasMenu Keybinding `yaml:"extrasMenu"`
ToggleWhitespaceInDiffView Keybinding `yaml:"toggleWhitespaceInDiffView"`
ToggleMouseCapture Keybinding `yaml:"toggleMouseCapture"`
IncreaseContextInDiffView Keybinding `yaml:"increaseContextInDiffView"`
DecreaseContextInDiffView Keybinding `yaml:"decreaseContextInDiffView"`
IncreaseRenameSimilarityThreshold Keybinding `yaml:"increaseRenameSimilarityThreshold"`
@@ -1066,6 +1068,7 @@ func GetDefaultConfigForPlatform(platform string) *UserConfig {
SubmitEditorText: Keybinding{"<enter>"},
ExtrasMenu: Keybinding{"@"},
ToggleWhitespaceInDiffView: Keybinding{"<ctrl+w>"},
ToggleMouseCapture: Keybinding{"%"},
IncreaseContextInDiffView: Keybinding{"}"},
DecreaseContextInDiffView: Keybinding{"{"},
IncreaseRenameSimilarityThreshold: Keybinding{")"},
+20
View File
@@ -136,6 +136,12 @@ func (self *GlobalController) GetKeybindings(opts types.KeybindingsOpts) []*type
Description: self.c.Tr.ToggleWhitespaceInDiffView,
Tooltip: self.c.Tr.ToggleWhitespaceInDiffViewTooltip,
},
{
Keys: opts.GetKeys(opts.Config.Universal.ToggleMouseCapture),
Handler: self.toggleMouseCapture,
Description: self.c.Tr.ToggleMouseCapture,
Tooltip: self.c.Tr.ToggleMouseCaptureTooltip,
},
{
Keys: opts.GetKeys(opts.Config.Universal.EditConfig),
Handler: self.editConfig,
@@ -273,6 +279,20 @@ func (self *GlobalController) toggleWhitespace() error {
return (&ToggleWhitespaceAction{c: self.c}).Call()
}
func (self *GlobalController) toggleMouseCapture() error {
userConfig := self.c.UserConfig()
userConfig.Gui.MouseEvents = !userConfig.Gui.MouseEvents
self.c.GocuiGui().Mouse = userConfig.Gui.MouseEvents
if userConfig.Gui.MouseEvents {
self.c.Toast(self.c.Tr.MouseCaptureEnabled)
} else {
self.c.Toast(self.c.Tr.MouseCaptureDisabled)
}
return nil
}
func (self *GlobalController) editConfig() error {
return (&EditConfigAction{c: self.c}).Call()
}
+8
View File
@@ -779,6 +779,10 @@ type TranslationSet struct {
ToggleWhitespaceInDiffViewTooltip string
IgnoreWhitespaceDiffViewSubTitle string
IgnoreWhitespaceNotSupportedHere string
ToggleMouseCapture string
ToggleMouseCaptureTooltip string
MouseCaptureEnabled string
MouseCaptureDisabled string
IncreaseContextInDiffView string
IncreaseContextInDiffViewTooltip string
DecreaseContextInDiffView string
@@ -1931,6 +1935,10 @@ func EnglishTranslationSet() *TranslationSet {
ToggleWhitespaceInDiffViewTooltip: "Toggle whether or not whitespace changes are shown in the diff view.\n\nThe default can be changed in the config file with the key 'git.ignoreWhitespaceInDiffView'.",
IgnoreWhitespaceDiffViewSubTitle: "(ignoring whitespace)",
IgnoreWhitespaceNotSupportedHere: "Ignoring whitespace is not supported in this view",
ToggleMouseCapture: "Toggle mouse capture",
ToggleMouseCaptureTooltip: "Toggle whether lazygit captures mouse events. When mouse capture is off, the terminal handles the mouse, so you can select text with it; this is useful in terminals that don't have a modifier key to bypass the capture.\n\nThe default can be changed in the config file with the key 'gui.mouseEvents'.",
MouseCaptureEnabled: "Mouse capture enabled",
MouseCaptureDisabled: "Mouse capture disabled",
IncreaseContextInDiffView: "Increase diff context size",
IncreaseContextInDiffViewTooltip: "Increase the amount of the context shown around changes in the diff view.\n\nThe default can be changed in the config file with the key 'git.diffContextSize'.",
DecreaseContextInDiffView: "Decrease diff context size",
@@ -0,0 +1,21 @@
package misc
import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
)
var ToggleMouseCapture = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Toggle mouse capture off and back on with the global keybinding",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {},
SetupRepo: func(shell *Shell) {},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.GlobalPress(keys.Universal.ToggleMouseCapture)
t.ExpectToast(Equals("Mouse capture disabled"))
t.GlobalPress(keys.Universal.ToggleMouseCapture)
t.ExpectToast(Equals("Mouse capture enabled"))
},
})
+1
View File
@@ -347,6 +347,7 @@ var tests = []*components.IntegrationTest{
misc.DirenvUnloadsOnBlockedEnvrc,
misc.InitialOpen,
misc.RecentReposOnLaunch,
misc.ToggleMouseCapture,
patch_building.Apply,
patch_building.ApplyInReverse,
patch_building.ApplyInReverseWithConflict,
+15 -1
View File
@@ -540,7 +540,7 @@
},
"mouseEvents": {
"type": "boolean",
"description": "If true, capture mouse events.\nWhen mouse events are captured, it's a little harder to select text: e.g. requiring you to hold the option key when on macOS.",
"description": "If true, capture mouse events.\nWhen mouse events are captured, it's a little harder to select text: e.g. requiring you to hold the option key when on macOS.\nMouse capture can also be toggled at runtime with the 'toggleMouseCapture' keybinding ('%' by default).",
"default": true
},
"skipAmendWarning": {
@@ -3335,6 +3335,20 @@
],
"default": "\u003cctrl+w\u003e"
},
"toggleMouseCapture": {
"oneOf": [
{
"type": "string"
},
{
"items": {
"type": "string"
},
"type": "array"
}
],
"default": "%"
},
"increaseContextInDiffView": {
"oneOf": [
{