Skip to content

Commit aa331e5

Browse files
authored
Fix assigning custom key to pullFiles command in the Commits panel (#4617)
- **PR Description** Improve the dispatching of key bindings so that remapping "pullFiles" to a different key works correctly in the Commits panel. Fixes #4614.
2 parents ac0c3db + c752f35 commit aa331e5

File tree

13 files changed

+71
-58
lines changed

13 files changed

+71
-58
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ require (
1515
github.com/integrii/flaggy v1.4.0
1616
github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c
1717
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd
18-
github.com/jesseduffield/gocui v0.3.1-0.20250529123049-319bd37ff248
18+
github.com/jesseduffield/gocui v0.3.1-0.20250605111917-fc5387961412
1919
github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a
2020
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
2121
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c h1:tC2Paiis
194194
github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c/go.mod h1:F2fEBk0ddf6ixrBrJjY7phfQ3hL9rXG0uSjvwYe50bE=
195195
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd h1:ViKj6qth8FgcIWizn9KiACWwPemWSymx62OPN0tHT+Q=
196196
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd/go.mod h1:lRhCiBr6XjQrvcQVa+UYsy/99d3wMXn/a0nSQlhnhlA=
197-
github.com/jesseduffield/gocui v0.3.1-0.20250529123049-319bd37ff248 h1:kFWTUOjkyuerq8L74MyTnpBvrBxPR4T5GpkOv/gr6/o=
198-
github.com/jesseduffield/gocui v0.3.1-0.20250529123049-319bd37ff248/go.mod h1:sLIyZ2J42R6idGdtemZzsiR3xY5EF0KsvYEGh3dQv3s=
197+
github.com/jesseduffield/gocui v0.3.1-0.20250605111917-fc5387961412 h1:8z1CpdCy9nzdj47lSLbDbCVmR5MgXsknYsuuHpzYk5M=
198+
github.com/jesseduffield/gocui v0.3.1-0.20250605111917-fc5387961412/go.mod h1:sLIyZ2J42R6idGdtemZzsiR3xY5EF0KsvYEGh3dQv3s=
199199
github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a h1:UDeJ3EBk04bXDLOPvuqM3on8HvyJfISw0+UMqW+0a4g=
200200
github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a/go.mod h1:FSWDLKT0NQpntbDd1H3lbz51fhCVlMzy/J0S6nM727Q=
201201
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY=

pkg/gui/controllers/local_commits_controller.go

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -144,14 +144,6 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
144144
),
145145
Description: self.c.Tr.Pick,
146146
Tooltip: self.c.Tr.PickCommitTooltip,
147-
// Not displaying this because we only want to display it when a TODO commit
148-
// is selected. A keybinding is displayed in the options view if Display is true,
149-
// and if it's not disabled, but if we disable it whenever a non-TODO commit is
150-
// selected, we'll be preventing pulls from happening within the commits view
151-
// (given they both use the 'p' key). Some approaches that come to mind:
152-
// * Allow a disabled keybinding to conditionally fallback to a global keybinding
153-
// * Allow a separate way of deciding whether a keybinding is displayed in the options view
154-
DisplayOnScreen: false,
155147
},
156148
{
157149
Key: opts.GetKey(opts.Config.Commits.CreateFixupCommit),
@@ -623,9 +615,7 @@ func (self *LocalCommitsController) pick(selectedCommits []*models.Commit) error
623615
return self.updateTodos(todo.Pick, selectedCommits)
624616
}
625617

626-
// at this point we aren't actually rebasing so we will interpret this as an
627-
// attempt to pull. We might revoke this later after enabling configurable keybindings
628-
return self.pullFiles()
618+
panic("should be disabled when not rebasing")
629619
}
630620

631621
func (self *LocalCommitsController) interactiveRebase(action todo.TodoCommand, startIdx int, endIdx int) error {
@@ -1476,8 +1466,7 @@ func (self *LocalCommitsController) pickEnabled(selectedCommits []*models.Commit
14761466
}
14771467

14781468
if !self.isRebasing() {
1479-
// if not rebasing, we're going to do a pull so we don't care about the selection
1480-
return nil
1469+
return &types.DisabledReason{Text: self.c.Tr.PickIsOnlyAllowedDuringRebase, AllowFurtherDispatching: true}
14811470
}
14821471

14831472
return self.midRebaseCommandEnabled(selectedCommits, startIdx, endIdx)

pkg/gui/keybindings.go

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -523,19 +523,22 @@ func (gui *Gui) SetMouseKeybinding(binding *gocui.ViewMouseBinding) error {
523523
}
524524

525525
func (gui *Gui) callKeybindingHandler(binding *types.Binding) error {
526-
var disabledReason *types.DisabledReason
527526
if binding.GetDisabledReason != nil {
528-
disabledReason = binding.GetDisabledReason()
529-
}
530-
if disabledReason != nil {
531-
if disabledReason.ShowErrorInPanel {
532-
return errors.New(disabledReason.Text)
533-
}
527+
if disabledReason := binding.GetDisabledReason(); disabledReason != nil {
528+
if disabledReason.AllowFurtherDispatching {
529+
return &types.ErrKeybindingNotHandled{DisabledReason: disabledReason}
530+
}
531+
532+
if disabledReason.ShowErrorInPanel {
533+
return errors.New(disabledReason.Text)
534+
}
534535

535-
if len(disabledReason.Text) > 0 {
536-
gui.c.ErrorToast(gui.Tr.DisabledMenuItemPrefix + disabledReason.Text)
536+
if len(disabledReason.Text) > 0 {
537+
gui.c.ErrorToast(gui.Tr.DisabledMenuItemPrefix + disabledReason.Text)
538+
}
539+
return nil
537540
}
538-
return nil
539541
}
542+
540543
return binding.Handler()
541544
}

pkg/gui/layout.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package gui
22

33
import (
4+
"errors"
5+
46
"github.com/jesseduffield/gocui"
57
"github.com/jesseduffield/lazygit/pkg/gui/types"
68
"github.com/samber/lo"
@@ -121,7 +123,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
121123
}
122124

123125
_, err := setViewFromDimensions(context)
124-
if err != nil && !gocui.IsUnknownView(err) {
126+
if err != nil && !errors.Is(err, gocui.ErrUnknownView) {
125127
return err
126128
}
127129
}
@@ -134,7 +136,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
134136

135137
for _, context := range gui.transientContexts() {
136138
view, err := gui.g.View(context.GetViewName())
137-
if err != nil && !gocui.IsUnknownView(err) {
139+
if err != nil && !errors.Is(err, gocui.ErrUnknownView) {
138140
return err
139141
}
140142
view.Visible = gui.helpers.Window.GetViewNameForWindow(context.GetWindowName()) == context.GetViewName()

pkg/gui/popup/popup_handler.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package popup
22

33
import (
44
"context"
5+
"errors"
56
"strings"
67

78
"github.com/jesseduffield/gocui"
@@ -80,6 +81,16 @@ func (self *PopupHandler) WithWaitingStatusSync(message string, f func() error)
8081
}
8182

8283
func (self *PopupHandler) ErrorHandler(err error) error {
84+
var notHandledError *types.ErrKeybindingNotHandled
85+
if errors.As(err, &notHandledError) {
86+
if !notHandledError.DisabledReason.ShowErrorInPanel {
87+
if msg := notHandledError.DisabledReason.Text; len(msg) > 0 {
88+
self.ErrorToast(self.Tr.DisabledMenuItemPrefix + msg)
89+
}
90+
return nil
91+
}
92+
}
93+
8394
// Need to set bold here explicitly; otherwise it gets cancelled by the red colouring.
8495
coloredMessage := style.FgRed.SetBold().Sprint(strings.TrimSpace(err.Error()))
8596
if err := self.onErrorFn(); err != nil {

pkg/gui/types/common.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,10 @@ type DisabledReason struct {
202202
// error panel instead. This is useful if the text is very long, or if it is
203203
// important enough to show it more prominently, or both.
204204
ShowErrorInPanel bool
205+
206+
// If true, the keybinding dispatch mechanism will continue to look for
207+
// other handlers for the keypress.
208+
AllowFurtherDispatching bool
205209
}
206210

207211
type MenuWidget int

pkg/gui/types/keybindings.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,15 @@ type KeybindingGuards struct {
5555
OutsideFilterMode Guard
5656
NoPopupPanel Guard
5757
}
58+
59+
type ErrKeybindingNotHandled struct {
60+
DisabledReason *DisabledReason
61+
}
62+
63+
func (e ErrKeybindingNotHandled) Error() string {
64+
return e.DisabledReason.Text
65+
}
66+
67+
func (e ErrKeybindingNotHandled) Unwrap() error {
68+
return gocui.ErrKeybindingNotHandled
69+
}

pkg/gui/views.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package gui
22

33
import (
4+
"errors"
45
"fmt"
56

67
"github.com/jesseduffield/gocui"
@@ -78,7 +79,7 @@ func (gui *Gui) createAllViews() error {
7879
var err error
7980
for _, mapping := range gui.orderedViewNameMappings() {
8081
*mapping.viewPtr, err = gui.prepareView(mapping.name)
81-
if err != nil && !gocui.IsUnknownView(err) {
82+
if err != nil && !errors.Is(err, gocui.ErrUnknownView) {
8283
return err
8384
}
8485
}

pkg/i18n/english.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ type TranslationSet struct {
369369
RewordNotSupported string
370370
ChangingThisActionIsNotAllowed string
371371
NotAllowedMidCherryPickOrRevert string
372+
PickIsOnlyAllowedDuringRebase string
372373
DroppingMergeRequiresSingleSelection string
373374
CherryPickCopy string
374375
CherryPickCopyTooltip string
@@ -1459,6 +1460,7 @@ func EnglishTranslationSet() *TranslationSet {
14591460
RewordNotSupported: "Rewording commits while interactively rebasing is not currently supported",
14601461
ChangingThisActionIsNotAllowed: "Changing this kind of rebase todo entry is not allowed",
14611462
NotAllowedMidCherryPickOrRevert: "This action is not allowed while cherry-picking or reverting",
1463+
PickIsOnlyAllowedDuringRebase: "This action is only allowed while rebasing",
14621464
DroppingMergeRequiresSingleSelection: "Dropping a merge commit requires a single selected item",
14631465
CherryPickCopy: "Copy (cherry-pick)",
14641466
CherryPickCopyTooltip: "Mark commit as copied. Then, within the local commits view, you can press `{{.paste}}` to paste (cherry-pick) the copied commit(s) into your checked out branch. At any time you can press `{{.escape}}` to cancel the selection.",

pkg/integration/clients/tui.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package clients
22

33
import (
4+
"errors"
45
"fmt"
56
"log"
67
"os"
@@ -314,7 +315,7 @@ func (self *app) layout(g *gocui.Gui) error {
314315
g.FgColor = gocui.ColorGreen
315316
listView, err := g.SetView("list", 0, 0, maxX-1, maxY-descriptionViewHeight-keybindingsViewHeight-editorViewHeight-1, 0)
316317
if err != nil {
317-
if !gocui.IsUnknownView(err) {
318+
if !errors.Is(err, gocui.ErrUnknownView) {
318319
return err
319320
}
320321

@@ -334,7 +335,7 @@ func (self *app) layout(g *gocui.Gui) error {
334335

335336
descriptionView, err := g.SetViewBeneath("description", "list", descriptionViewHeight)
336337
if err != nil {
337-
if !gocui.IsUnknownView(err) {
338+
if !errors.Is(err, gocui.ErrUnknownView) {
338339
return err
339340
}
340341
descriptionView.Title = "Test description"
@@ -344,7 +345,7 @@ func (self *app) layout(g *gocui.Gui) error {
344345

345346
keybindingsView, err := g.SetViewBeneath("keybindings", "description", keybindingsViewHeight)
346347
if err != nil {
347-
if !gocui.IsUnknownView(err) {
348+
if !errors.Is(err, gocui.ErrUnknownView) {
348349
return err
349350
}
350351
keybindingsView.Title = "Keybindings"
@@ -355,7 +356,7 @@ func (self *app) layout(g *gocui.Gui) error {
355356

356357
editorView, err := g.SetViewBeneath("editor", "keybindings", editorViewHeight)
357358
if err != nil {
358-
if !gocui.IsUnknownView(err) {
359+
if !errors.Is(err, gocui.ErrUnknownView) {
359360
return err
360361
}
361362

vendor/github.com/jesseduffield/gocui/gui.go

Lines changed: 12 additions & 24 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/modules.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
227227
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
228228
github.com/jesseduffield/go-git/v5/utils/sync
229229
github.com/jesseduffield/go-git/v5/utils/trace
230-
# github.com/jesseduffield/gocui v0.3.1-0.20250529123049-319bd37ff248
230+
# github.com/jesseduffield/gocui v0.3.1-0.20250605111917-fc5387961412
231231
## explicit; go 1.12
232232
github.com/jesseduffield/gocui
233233
# github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a

0 commit comments

Comments
 (0)