1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2025-08-08 22:36:49 +02:00

Optionally pass disabled commands on to next handler

If a DisabledReason has its AllowFurtherDispatching flag set, it is returned as
a ErrKeybindingNotHandled error, instead of shown as a toast right away. This
allows gocui to continue to dispatch the keybinding, and we can unwrap the error
at the other end (in our global ErrorHandler) and display it then.

This allows having keybindings for the same key at the local and global levels,
and they will continue to be dispatched even if the first one returns a
DisabledReason. It is opt-in, so we only use it for cases where we know that a
local and a global handler share the same (default) keybinding.
This commit is contained in:
Stefan Haller
2025-06-01 16:11:20 +02:00
parent 37b118f4fb
commit 3e26be9845
4 changed files with 31 additions and 0 deletions

View File

@ -525,6 +525,10 @@ func (gui *Gui) SetMouseKeybinding(binding *gocui.ViewMouseBinding) error {
func (gui *Gui) callKeybindingHandler(binding *types.Binding) error {
if binding.GetDisabledReason != nil {
if disabledReason := binding.GetDisabledReason(); disabledReason != nil {
if disabledReason.AllowFurtherDispatching {
return &types.ErrKeybindingNotHandled{DisabledReason: disabledReason}
}
if disabledReason.ShowErrorInPanel {
return errors.New(disabledReason.Text)
}

View File

@ -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, &notHandledError) {
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 {

View File

@ -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

View File

@ -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
}