mirror of
https://github.com/jesseduffield/lazygit.git
synced 2026-09-10 07:36:27 -04:00
Keep a filtering menu navigable whatever the keybindings are
The keys for paging through a menu are ',' and '.' by default, and there is no non-printable alternative for them, so a menu that filters as you type would lose paging altogether as soon as the user typed anything. The same goes for confirming and cancelling if those keys are configured as printable ones. So bind the physical keys for all of it, on top of whatever is configured, and only where they aren't the configured keys anyway. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
fe9b990c4c
commit
2048c7f0a6
|
|
@ -138,6 +138,9 @@ func (gui *Gui) resetHelpersAndControllers() {
|
|||
|
||||
common := controllers.NewControllerCommon(helperCommon, gui)
|
||||
|
||||
listControllerFactory := controllers.NewListControllerFactory(common)
|
||||
menuListController := listControllerFactory.Create(gui.State.Contexts.Menu)
|
||||
|
||||
syncController := controllers.NewSyncController(
|
||||
common,
|
||||
)
|
||||
|
|
@ -156,7 +159,7 @@ func (gui *Gui) resetHelpersAndControllers() {
|
|||
|
||||
remoteBranchesController := controllers.NewRemoteBranchesController(common)
|
||||
|
||||
menuController := controllers.NewMenuController(common)
|
||||
menuController := controllers.NewMenuController(common, menuListController)
|
||||
localCommitsController := controllers.NewLocalCommitsController(common, syncController.HandlePull)
|
||||
tagsController := controllers.NewTagsController(common)
|
||||
filesController := controllers.NewFilesController(
|
||||
|
|
@ -359,6 +362,7 @@ func (gui *Gui) resetHelpersAndControllers() {
|
|||
|
||||
controllers.AttachControllers(gui.State.Contexts.Menu,
|
||||
menuController,
|
||||
menuListController,
|
||||
)
|
||||
|
||||
controllers.AttachControllers(gui.State.Contexts.CommitMessage,
|
||||
|
|
@ -412,8 +416,11 @@ func (gui *Gui) resetHelpersAndControllers() {
|
|||
)
|
||||
|
||||
// this must come last so that we've got our click handlers defined against the context
|
||||
listControllerFactory := controllers.NewListControllerFactory(common)
|
||||
for _, context := range gui.c.Context().AllList() {
|
||||
if context == gui.State.Contexts.Menu {
|
||||
// already attached above, next to the menu controller that delegates to it
|
||||
continue
|
||||
}
|
||||
controllers.AttachControllers(context, listControllerFactory.Create(context))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,20 +1,26 @@
|
|||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/jesseduffield/lazygit/pkg/config"
|
||||
"github.com/jesseduffield/lazygit/pkg/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||
"github.com/samber/lo"
|
||||
)
|
||||
|
||||
type MenuController struct {
|
||||
baseController
|
||||
*ListControllerTrait[*types.MenuItem]
|
||||
c *ControllerCommon
|
||||
// for delegating navigation to, see physicalKeyBindings
|
||||
listController *ListController
|
||||
}
|
||||
|
||||
var _ types.IController = &MenuController{}
|
||||
|
||||
func NewMenuController(
|
||||
c *ControllerCommon,
|
||||
listController *ListController,
|
||||
) *MenuController {
|
||||
return &MenuController{
|
||||
baseController: baseController{},
|
||||
|
|
@ -24,7 +30,8 @@ func NewMenuController(
|
|||
c.Contexts().Menu.GetSelected,
|
||||
c.Contexts().Menu.GetSelectedItems,
|
||||
),
|
||||
c: c,
|
||||
c: c,
|
||||
listController: listController,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -52,6 +59,51 @@ func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
|||
},
|
||||
}
|
||||
|
||||
if self.context().FilterAsYouType() {
|
||||
bindings = append(bindings, self.physicalKeyBindings(opts)...)
|
||||
}
|
||||
|
||||
return bindings
|
||||
}
|
||||
|
||||
// In a menu that filters as you type, the keys configured for driving the menu
|
||||
// may all be printable, and printable keys become filter text once the user
|
||||
// starts typing. These keys can't, so binding them on top guarantees that the
|
||||
// menu stays usable no matter how the keybindings are configured.
|
||||
func (self *MenuController) physicalKeyBindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||
candidates := []struct {
|
||||
key gocui.Key
|
||||
configured config.Keybinding
|
||||
binding *types.Binding
|
||||
}{
|
||||
{
|
||||
key: gocui.NewKeyName(gocui.KeyEnter),
|
||||
configured: opts.Config.Universal.ConfirmMenu,
|
||||
binding: &types.Binding{
|
||||
Handler: self.withItem(self.press),
|
||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||
},
|
||||
},
|
||||
{gocui.NewKeyName(gocui.KeyEsc), opts.Config.Universal.Return, &types.Binding{Handler: self.close}},
|
||||
{gocui.NewKeyName(gocui.KeyArrowUp), opts.Config.Universal.PrevItem, &types.Binding{Handler: self.listController.HandlePrevLine}},
|
||||
{gocui.NewKeyName(gocui.KeyArrowDown), opts.Config.Universal.NextItem, &types.Binding{Handler: self.listController.HandleNextLine}},
|
||||
{gocui.NewKeyName(gocui.KeyPgup), opts.Config.Universal.PrevPage, &types.Binding{Handler: self.listController.HandlePrevPage}},
|
||||
{gocui.NewKeyName(gocui.KeyPgdn), opts.Config.Universal.NextPage, &types.Binding{Handler: self.listController.HandleNextPage}},
|
||||
{gocui.NewKeyName(gocui.KeyHome), opts.Config.Universal.GotoTop, &types.Binding{Handler: self.listController.HandleGotoTop}},
|
||||
{gocui.NewKeyName(gocui.KeyEnd), opts.Config.Universal.GotoBottom, &types.Binding{Handler: self.listController.HandleGotoBottom}},
|
||||
}
|
||||
|
||||
bindings := []*types.Binding{}
|
||||
for _, candidate := range candidates {
|
||||
if lo.Contains(opts.GetKeys(candidate.configured), candidate.key) {
|
||||
// this key is the configured one, so it drives the menu already
|
||||
continue
|
||||
}
|
||||
|
||||
candidate.binding.Keys = []gocui.Key{candidate.key}
|
||||
bindings = append(bindings, candidate.binding)
|
||||
}
|
||||
|
||||
return bindings
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue