mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-06-15 00:15:32 +02:00
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.
This commit is contained in:
2
go.mod
2
go.mod
@ -15,7 +15,7 @@ require (
|
||||
github.com/integrii/flaggy v1.4.0
|
||||
github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c
|
||||
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20250529123049-319bd37ff248
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20250605111917-fc5387961412
|
||||
github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
|
||||
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e
|
||||
|
4
go.sum
4
go.sum
@ -194,8 +194,8 @@ github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c h1:tC2Paiis
|
||||
github.com/jesseduffield/generics v0.0.0-20250517122708-b0b4a53a6f5c/go.mod h1:F2fEBk0ddf6ixrBrJjY7phfQ3hL9rXG0uSjvwYe50bE=
|
||||
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd h1:ViKj6qth8FgcIWizn9KiACWwPemWSymx62OPN0tHT+Q=
|
||||
github.com/jesseduffield/go-git/v5 v5.14.1-0.20250407170251-e1a013310ccd/go.mod h1:lRhCiBr6XjQrvcQVa+UYsy/99d3wMXn/a0nSQlhnhlA=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20250529123049-319bd37ff248 h1:kFWTUOjkyuerq8L74MyTnpBvrBxPR4T5GpkOv/gr6/o=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20250529123049-319bd37ff248/go.mod h1:sLIyZ2J42R6idGdtemZzsiR3xY5EF0KsvYEGh3dQv3s=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20250605111917-fc5387961412 h1:8z1CpdCy9nzdj47lSLbDbCVmR5MgXsknYsuuHpzYk5M=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20250605111917-fc5387961412/go.mod h1:sLIyZ2J42R6idGdtemZzsiR3xY5EF0KsvYEGh3dQv3s=
|
||||
github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a h1:UDeJ3EBk04bXDLOPvuqM3on8HvyJfISw0+UMqW+0a4g=
|
||||
github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a/go.mod h1:FSWDLKT0NQpntbDd1H3lbz51fhCVlMzy/J0S6nM727Q=
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY=
|
||||
|
@ -144,14 +144,6 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
||||
),
|
||||
Description: self.c.Tr.Pick,
|
||||
Tooltip: self.c.Tr.PickCommitTooltip,
|
||||
// Not displaying this because we only want to display it when a TODO commit
|
||||
// is selected. A keybinding is displayed in the options view if Display is true,
|
||||
// and if it's not disabled, but if we disable it whenever a non-TODO commit is
|
||||
// selected, we'll be preventing pulls from happening within the commits view
|
||||
// (given they both use the 'p' key). Some approaches that come to mind:
|
||||
// * Allow a disabled keybinding to conditionally fallback to a global keybinding
|
||||
// * Allow a separate way of deciding whether a keybinding is displayed in the options view
|
||||
DisplayOnScreen: false,
|
||||
},
|
||||
{
|
||||
Key: opts.GetKey(opts.Config.Commits.CreateFixupCommit),
|
||||
@ -623,9 +615,7 @@ func (self *LocalCommitsController) pick(selectedCommits []*models.Commit) error
|
||||
return self.updateTodos(todo.Pick, selectedCommits)
|
||||
}
|
||||
|
||||
// at this point we aren't actually rebasing so we will interpret this as an
|
||||
// attempt to pull. We might revoke this later after enabling configurable keybindings
|
||||
return self.pullFiles()
|
||||
panic("should be disabled when not rebasing")
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) interactiveRebase(action todo.TodoCommand, startIdx int, endIdx int) error {
|
||||
@ -1476,8 +1466,7 @@ func (self *LocalCommitsController) pickEnabled(selectedCommits []*models.Commit
|
||||
}
|
||||
|
||||
if !self.isRebasing() {
|
||||
// if not rebasing, we're going to do a pull so we don't care about the selection
|
||||
return nil
|
||||
return &types.DisabledReason{Text: self.c.Tr.PickIsOnlyAllowedDuringRebase, AllowFurtherDispatching: true}
|
||||
}
|
||||
|
||||
return self.midRebaseCommandEnabled(selectedCommits, startIdx, endIdx)
|
||||
|
@ -523,19 +523,22 @@ func (gui *Gui) SetMouseKeybinding(binding *gocui.ViewMouseBinding) error {
|
||||
}
|
||||
|
||||
func (gui *Gui) callKeybindingHandler(binding *types.Binding) error {
|
||||
var disabledReason *types.DisabledReason
|
||||
if binding.GetDisabledReason != nil {
|
||||
disabledReason = binding.GetDisabledReason()
|
||||
}
|
||||
if disabledReason != nil {
|
||||
if disabledReason.ShowErrorInPanel {
|
||||
return errors.New(disabledReason.Text)
|
||||
}
|
||||
if disabledReason := binding.GetDisabledReason(); disabledReason != nil {
|
||||
if disabledReason.AllowFurtherDispatching {
|
||||
return &types.ErrKeybindingNotHandled{DisabledReason: disabledReason}
|
||||
}
|
||||
|
||||
if len(disabledReason.Text) > 0 {
|
||||
gui.c.ErrorToast(gui.Tr.DisabledMenuItemPrefix + disabledReason.Text)
|
||||
if disabledReason.ShowErrorInPanel {
|
||||
return errors.New(disabledReason.Text)
|
||||
}
|
||||
|
||||
if len(disabledReason.Text) > 0 {
|
||||
gui.c.ErrorToast(gui.Tr.DisabledMenuItemPrefix + disabledReason.Text)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
return binding.Handler()
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/samber/lo"
|
||||
@ -121,7 +123,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
}
|
||||
|
||||
_, err := setViewFromDimensions(context)
|
||||
if err != nil && !gocui.IsUnknownView(err) {
|
||||
if err != nil && !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -134,7 +136,7 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
||||
|
||||
for _, context := range gui.transientContexts() {
|
||||
view, err := gui.g.View(context.GetViewName())
|
||||
if err != nil && !gocui.IsUnknownView(err) {
|
||||
if err != nil && !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
view.Visible = gui.helpers.Window.GetViewNameForWindow(context.GetWindowName()) == context.GetViewName()
|
||||
|
@ -2,6 +2,7 @@ package popup
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
@ -80,6 +81,16 @@ func (self *PopupHandler) WithWaitingStatusSync(message string, f func() error)
|
||||
}
|
||||
|
||||
func (self *PopupHandler) ErrorHandler(err error) error {
|
||||
var notHandledError *types.ErrKeybindingNotHandled
|
||||
if errors.As(err, ¬HandledError) {
|
||||
if !notHandledError.DisabledReason.ShowErrorInPanel {
|
||||
if msg := notHandledError.DisabledReason.Text; len(msg) > 0 {
|
||||
self.ErrorToast(self.Tr.DisabledMenuItemPrefix + msg)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Need to set bold here explicitly; otherwise it gets cancelled by the red colouring.
|
||||
coloredMessage := style.FgRed.SetBold().Sprint(strings.TrimSpace(err.Error()))
|
||||
if err := self.onErrorFn(); err != nil {
|
||||
|
@ -202,6 +202,10 @@ type DisabledReason struct {
|
||||
// error panel instead. This is useful if the text is very long, or if it is
|
||||
// important enough to show it more prominently, or both.
|
||||
ShowErrorInPanel bool
|
||||
|
||||
// If true, the keybinding dispatch mechanism will continue to look for
|
||||
// other handlers for the keypress.
|
||||
AllowFurtherDispatching bool
|
||||
}
|
||||
|
||||
type MenuWidget int
|
||||
|
@ -55,3 +55,15 @@ type KeybindingGuards struct {
|
||||
OutsideFilterMode Guard
|
||||
NoPopupPanel Guard
|
||||
}
|
||||
|
||||
type ErrKeybindingNotHandled struct {
|
||||
DisabledReason *DisabledReason
|
||||
}
|
||||
|
||||
func (e ErrKeybindingNotHandled) Error() string {
|
||||
return e.DisabledReason.Text
|
||||
}
|
||||
|
||||
func (e ErrKeybindingNotHandled) Unwrap() error {
|
||||
return gocui.ErrKeybindingNotHandled
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package gui
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
@ -78,7 +79,7 @@ func (gui *Gui) createAllViews() error {
|
||||
var err error
|
||||
for _, mapping := range gui.orderedViewNameMappings() {
|
||||
*mapping.viewPtr, err = gui.prepareView(mapping.name)
|
||||
if err != nil && !gocui.IsUnknownView(err) {
|
||||
if err != nil && !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -369,6 +369,7 @@ type TranslationSet struct {
|
||||
RewordNotSupported string
|
||||
ChangingThisActionIsNotAllowed string
|
||||
NotAllowedMidCherryPickOrRevert string
|
||||
PickIsOnlyAllowedDuringRebase string
|
||||
DroppingMergeRequiresSingleSelection string
|
||||
CherryPickCopy string
|
||||
CherryPickCopyTooltip string
|
||||
@ -1459,6 +1460,7 @@ func EnglishTranslationSet() *TranslationSet {
|
||||
RewordNotSupported: "Rewording commits while interactively rebasing is not currently supported",
|
||||
ChangingThisActionIsNotAllowed: "Changing this kind of rebase todo entry is not allowed",
|
||||
NotAllowedMidCherryPickOrRevert: "This action is not allowed while cherry-picking or reverting",
|
||||
PickIsOnlyAllowedDuringRebase: "This action is only allowed while rebasing",
|
||||
DroppingMergeRequiresSingleSelection: "Dropping a merge commit requires a single selected item",
|
||||
CherryPickCopy: "Copy (cherry-pick)",
|
||||
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.",
|
||||
|
@ -1,6 +1,7 @@
|
||||
package clients
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
@ -314,7 +315,7 @@ func (self *app) layout(g *gocui.Gui) error {
|
||||
g.FgColor = gocui.ColorGreen
|
||||
listView, err := g.SetView("list", 0, 0, maxX-1, maxY-descriptionViewHeight-keybindingsViewHeight-editorViewHeight-1, 0)
|
||||
if err != nil {
|
||||
if !gocui.IsUnknownView(err) {
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -334,7 +335,7 @@ func (self *app) layout(g *gocui.Gui) error {
|
||||
|
||||
descriptionView, err := g.SetViewBeneath("description", "list", descriptionViewHeight)
|
||||
if err != nil {
|
||||
if !gocui.IsUnknownView(err) {
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
descriptionView.Title = "Test description"
|
||||
@ -344,7 +345,7 @@ func (self *app) layout(g *gocui.Gui) error {
|
||||
|
||||
keybindingsView, err := g.SetViewBeneath("keybindings", "description", keybindingsViewHeight)
|
||||
if err != nil {
|
||||
if !gocui.IsUnknownView(err) {
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
keybindingsView.Title = "Keybindings"
|
||||
@ -355,7 +356,7 @@ func (self *app) layout(g *gocui.Gui) error {
|
||||
|
||||
editorView, err := g.SetViewBeneath("editor", "keybindings", editorViewHeight)
|
||||
if err != nil {
|
||||
if !gocui.IsUnknownView(err) {
|
||||
if !errors.Is(err, gocui.ErrUnknownView) {
|
||||
return err
|
||||
}
|
||||
|
||||
|
36
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
36
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
@ -786,7 +786,7 @@ func (g *Gui) MainLoop() error {
|
||||
}
|
||||
|
||||
func (g *Gui) handleError(err error) error {
|
||||
if err != nil && !IsQuit(err) && g.ErrorHandler != nil {
|
||||
if err != nil && !standardErrors.Is(err, ErrQuit) && g.ErrorHandler != nil {
|
||||
return g.ErrorHandler(err)
|
||||
}
|
||||
|
||||
@ -1498,6 +1498,8 @@ func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) error {
|
||||
}
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
for _, kb := range g.keybindings {
|
||||
if kb.handler == nil {
|
||||
continue
|
||||
@ -1506,13 +1508,13 @@ func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) error {
|
||||
continue
|
||||
}
|
||||
if g.matchView(v, kb) {
|
||||
err := g.execKeybinding(v, kb)
|
||||
if IsKeybindingNotHandled(err) {
|
||||
matchingParentViewKb = nil
|
||||
break
|
||||
} else {
|
||||
err = g.execKeybinding(v, kb)
|
||||
if !errors.Is(err, ErrKeybindingNotHandled) {
|
||||
return err
|
||||
}
|
||||
|
||||
matchingParentViewKb = nil
|
||||
break
|
||||
}
|
||||
if v != nil && g.matchView(v.ParentView, kb) {
|
||||
matchingParentViewKb = kb
|
||||
@ -1522,8 +1524,8 @@ func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) error {
|
||||
}
|
||||
}
|
||||
if matchingParentViewKb != nil {
|
||||
err := g.execKeybinding(v.ParentView, matchingParentViewKb)
|
||||
if !IsKeybindingNotHandled(err) {
|
||||
err = g.execKeybinding(v.ParentView, matchingParentViewKb)
|
||||
if !errors.Is(err, ErrKeybindingNotHandled) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -1536,9 +1538,9 @@ func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) error {
|
||||
}
|
||||
|
||||
if globalKb != nil {
|
||||
return g.execKeybinding(v, globalKb)
|
||||
err = g.execKeybinding(v, globalKb)
|
||||
}
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
// execKeybinding executes a given keybinding
|
||||
@ -1602,20 +1604,6 @@ func (g *Gui) isBlacklisted(k Key) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsUnknownView reports whether the contents of an error is "unknown view".
|
||||
func IsUnknownView(err error) bool {
|
||||
return err != nil && err.Error() == ErrUnknownView.Error()
|
||||
}
|
||||
|
||||
// IsQuit reports whether the contents of an error is "quit".
|
||||
func IsQuit(err error) bool {
|
||||
return err != nil && err.Error() == ErrQuit.Error()
|
||||
}
|
||||
|
||||
func IsKeybindingNotHandled(err error) bool {
|
||||
return err != nil && err.Error() == ErrKeybindingNotHandled.Error()
|
||||
}
|
||||
|
||||
func (g *Gui) Suspend() error {
|
||||
g.suspendedMutex.Lock()
|
||||
defer g.suspendedMutex.Unlock()
|
||||
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -227,7 +227,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
|
||||
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
|
||||
github.com/jesseduffield/go-git/v5/utils/sync
|
||||
github.com/jesseduffield/go-git/v5/utils/trace
|
||||
# github.com/jesseduffield/gocui v0.3.1-0.20250529123049-319bd37ff248
|
||||
# github.com/jesseduffield/gocui v0.3.1-0.20250605111917-fc5387961412
|
||||
## explicit; go 1.12
|
||||
github.com/jesseduffield/gocui
|
||||
# github.com/jesseduffield/kill v0.0.0-20250101124109-e216ddbe133a
|
||||
|
Reference in New Issue
Block a user