From 75afa099e9d57209359aa63f43368e62110dff61 Mon Sep 17 00:00:00 2001 From: Stefan Haller Date: Mon, 28 Jul 2025 14:53:49 +0200 Subject: [PATCH] Add support for dynamic binding descriptions --- pkg/gui/controllers/options_menu_action.go | 6 ++--- pkg/gui/types/keybindings.go | 26 ++++++++++++++++++---- 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/pkg/gui/controllers/options_menu_action.go b/pkg/gui/controllers/options_menu_action.go index 863111a2f..f295a19f4 100644 --- a/pkg/gui/controllers/options_menu_action.go +++ b/pkg/gui/controllers/options_menu_action.go @@ -25,7 +25,7 @@ func (self *OptionsMenuAction) Call() error { } return &types.MenuItem{ OpensMenu: binding.OpensMenu, - Label: binding.Description, + Label: binding.GetDescription(), OnPress: func() error { if binding.Handler == nil { return nil @@ -60,7 +60,7 @@ func (self *OptionsMenuAction) getBindings(context types.Context) ([]*types.Bind bindings, _ := self.c.GetInitialKeybindingsWithCustomCommands() for _, binding := range bindings { - if binding.Description != "" { + if binding.GetDescription() != "" { if binding.ViewName == "" || binding.Tag == "global" { bindingsGlobal = append(bindingsGlobal, binding) } else if binding.ViewName == context.GetViewName() { @@ -80,6 +80,6 @@ func (self *OptionsMenuAction) getBindings(context types.Context) ([]*types.Bind // handler in the keybinding struct. func uniqueBindings(bindings []*types.Binding) []*types.Binding { return lo.UniqBy(bindings, func(binding *types.Binding) string { - return binding.Description + return binding.GetDescription() }) } diff --git a/pkg/gui/types/keybindings.go b/pkg/gui/types/keybindings.go index 0276500ab..ac3ce049d 100644 --- a/pkg/gui/types/keybindings.go +++ b/pkg/gui/types/keybindings.go @@ -16,12 +16,20 @@ type Binding struct { Key Key Modifier gocui.Modifier Description string + // DescriptionFunc is used instead of Description if non-nil, and is useful for dynamic + // descriptions that change depending on context. Important: this must not be an expensive call. + // Note that you should still provide a generic, non-dynamic description in the Description field, + // as this is used in the cheatsheet. + DescriptionFunc func() string // If defined, this is used in place of Description when showing the keybinding // in the options view at the bottom left of the screen. ShortDescription string - Alternative string - Tag string // e.g. 'navigation'. Used for grouping things in the cheatsheet - OpensMenu bool + // ShortDescriptionFunc is used instead of ShortDescription if non-nil, and is useful for dynamic + // descriptions that change depending on context. Important: this must not be an expensive call. + ShortDescriptionFunc func() string + Alternative string + Tag string // e.g. 'navigation'. Used for grouping things in the cheatsheet + OpensMenu bool // If true, the keybinding will appear at the bottom of the screen. // Even if set to true, the keybinding will not be displayed if it is currently @@ -47,11 +55,21 @@ func (b *Binding) IsDisabled() bool { return b.GetDisabledReason != nil && b.GetDisabledReason() != nil } +func (b *Binding) GetDescription() string { + if b.DescriptionFunc != nil { + return b.DescriptionFunc() + } + return b.Description +} + func (b *Binding) GetShortDescription() string { + if b.ShortDescriptionFunc != nil { + return b.ShortDescriptionFunc() + } if b.ShortDescription != "" { return b.ShortDescription } - return b.Description + return b.GetDescription() } // A guard is a decorator which checks something before executing a handler