summaryrefslogtreecommitdiffstats
path: root/pkg/gui/options_map.go
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2024-01-02 12:19:31 +1100
committerJesse Duffield <jessedduffield@gmail.com>2024-01-28 08:33:13 +1100
commit0f9d9e13d12d37ab419efccc5c217422fb67a765 (patch)
tree35fc5bdc4473da8a6750ee621e270b9e595520c9 /pkg/gui/options_map.go
parentc07b3fad64ca71bc1873bcc1bb9e2256c05d4df0 (diff)
Show mode-specific keybinding suggestions
As part of making lazygit more discoverable, there are certain keys which you almost certainly need to press when you're in a given mode e.g. 'v' to paste commits when cherry-picking. This commit prominently shows these keybinding suggestions alongside the others in the option view. I'm using the same colours for these keybindings as is associated with the mode elsewhere e.g. yellow for rebasing and cyan for cherry-picking. The cherry-picking one is a bit weird because we also use cyan text to show loaders and app status at the bottom left so it may be confusing, but I haven't personally found it awkward from having tested it out myself. Previously we would render these options whenever a new context was activated, but now that we need to re-render options whenever a mode changes, I'm instead rendering them on each screen re-render (i.e. in the layout function). Given how cheap it is to render this text, I think it's fine performance-wise.
Diffstat (limited to 'pkg/gui/options_map.go')
-rw-r--r--pkg/gui/options_map.go157
1 files changed, 106 insertions, 51 deletions
diff --git a/pkg/gui/options_map.go b/pkg/gui/options_map.go
index a2f1496bc..01bb3e212 100644
--- a/pkg/gui/options_map.go
+++ b/pkg/gui/options_map.go
@@ -4,9 +4,13 @@ import (
"fmt"
"strings"
+ "github.com/jesseduffield/lazygit/pkg/gui/context"
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
+ "github.com/jesseduffield/lazygit/pkg/gui/style"
"github.com/jesseduffield/lazygit/pkg/gui/types"
+ "github.com/jesseduffield/lazygit/pkg/theme"
+ "github.com/jesseduffield/lazygit/pkg/utils"
"github.com/samber/lo"
)
@@ -14,30 +18,89 @@ type OptionsMapMgr struct {
c *helpers.HelperCommon
}
-func (gui *Gui) renderContextOptionsMap(c types.Context) {
+func (gui *Gui) renderContextOptionsMap() {
// In demos, we render our own content to this view
if gui.integrationTest != nil && gui.integrationTest.IsDemo() {
return
}
mgr := OptionsMapMgr{c: gui.c}
- mgr.renderContextOptionsMap(c)
+ mgr.renderContextOptionsMap()
}
-// render the options available for the current context at the bottom of the screen
-func (self *OptionsMapMgr) renderContextOptionsMap(c types.Context) {
- bindingsToDisplay := lo.Filter(c.GetKeybindings(self.c.KeybindingsOpts()), func(binding *types.Binding, _ int) bool {
- return binding.Display
+// Render the options available for the current context at the bottom of the screen
+// STYLE GUIDE: we use the default options fg color for most keybindings. We can
+// only use a different color if we're in a specific mode where the user is likely
+// to want to press that key. For example, when in cherry-picking mode, we
+// want to prominently show the keybinding for pasting commits.
+func (self *OptionsMapMgr) renderContextOptionsMap() {
+ currentContext := self.c.CurrentContext()
+
+ currentContextBindings := currentContext.GetKeybindings(self.c.KeybindingsOpts())
+ globalBindings := self.c.Contexts().Global.GetKeybindings(self.c.KeybindingsOpts())
+
+ allBindings := append(currentContextBindings, globalBindings...)
+
+ bindingsToDisplay := lo.Filter(allBindings, func(binding *types.Binding, _ int) bool {
+ return binding.DisplayOnScreen && !binding.IsDisabled()
+ })
+
+ optionsMap := lo.Map(bindingsToDisplay, func(binding *types.Binding, _ int) bindingInfo {
+ displayStyle := theme.OptionsFgColor
+ if binding.DisplayStyle != nil {
+ displayStyle = *binding.DisplayStyle
+ }
+
+ description := binding.Description
+ if binding.ShortDescription != "" {
+ description = binding.ShortDescription
+ }
+
+ return bindingInfo{
+ key: keybindings.LabelFromKey(binding.Key),
+ description: description,
+ style: displayStyle,
+ }
})
- var optionsMap []bindingInfo
- if len(bindingsToDisplay) == 0 {
- optionsMap = self.globalOptions()
- } else {
- optionsMap = lo.Map(bindingsToDisplay, func(binding *types.Binding, _ int) bindingInfo {
- return bindingInfo{
- key: keybindings.LabelFromKey(binding.Key),
- description: binding.Description,
- }
+ // Mode-specific local keybindings
+ if currentContext.GetKey() == context.LOCAL_COMMITS_CONTEXT_KEY {
+ if self.c.Modes().CherryPicking.Active() {
+ optionsMap = utils.Prepend(optionsMap, bindingInfo{
+ key: keybindings.Label(self.c.KeybindingsOpts().Config.Commits.PasteCommits),
+ description: self.c.Tr.PasteCommits,
+ style: style.FgCyan,
+ })
+ }
+
+ if self.c.Model().BisectInfo.Started() {
+ optionsMap = utils.Prepend(optionsMap, bindingInfo{
+ key: keybindings.Label(self.c.KeybindingsOpts().Config.Commits.ViewBisectOptions),
+ description: self.c.Tr.ViewBisectOptions,
+ style: style.FgGreen,
+ })
+ }
+ }
+
+ // Mode-specific global keybindings
+ if self.c.Model().WorkingTreeStateAtLastCommitRefresh.IsRebasing() {
+ optionsMap = utils.Prepend(optionsMap, bindingInfo{
+ key: keybindings.Label(self.c.KeybindingsOpts().Config.Universal.CreateRebaseOptionsMenu),
+ description: self.c.Tr.ViewRebaseOptions,
+ style: style.FgYellow,
+ })
+ } else if self.c.Model().WorkingTreeStateAtLastCommitRefresh.IsMerging() {
+ optionsMap = utils.Prepend(optionsMap, bindingInfo{
+ key: keybindings.Label(self.c.KeybindingsOpts().Config.Universal.CreateRebaseOptionsMenu),
+ description: self.c.Tr.ViewMergeOptions,
+ style: style.FgYellow,
+ })
+ }
+
+ if self.c.Git().Patch.PatchBuilder.Active() {
+ optionsMap = utils.Prepend(optionsMap, bindingInfo{
+ key: keybindings.Label(self.c.KeybindingsOpts().Config.Universal.CreatePatchOptionsMenu),
+ description: self.c.Tr.ViewPatchOptions,
+ style: style.FgYellow,
})
}
@@ -45,49 +108,41 @@ func (self *OptionsMapMgr) renderContextOptionsMap(c types.Context) {
}
func (self *OptionsMapMgr) formatBindingInfos(bindingInfos []bindingInfo) string {
- return strings.Join(
- lo.Map(bindingInfos, func(bindingInfo bindingInfo, _ int) string {
- return fmt.Sprintf("%s: %s", bindingInfo.key, bindingInfo.description)
- }),
- ", ")
+ width := self.c.Views().Options.Width() - 4 // -4 for the padding
+ var builder strings.Builder
+ ellipsis := "…"
+ separator := " | "
+
+ length := 0
+
+ for i, info := range bindingInfos {
+ plainText := fmt.Sprintf("%s: %s", info.description, info.key)
+
+ // Check if adding the next formatted string exceeds the available width
+ if i > 0 && length+len(separator)+len(plainText) > width {
+ builder.WriteString(theme.OptionsFgColor.Sprint(separator + ellipsis))
+ break
+ }
+
+ formatted := info.style.Sprintf(plainText)
+
+ if i > 0 {
+ builder.WriteString(theme.OptionsFgColor.Sprint(separator))
+ length += len(separator)
+ }
+ builder.WriteString(formatted)
+ length += len(plainText)
+ }
+
+ return builder.String()
}
func (self *OptionsMapMgr) renderOptions(options string) {
self.c.SetViewContent(self.c.Views().Options, options)
}
-func (self *OptionsMapMgr) globalOptions() []bindingInfo {
- keybindingConfig := self.c.UserConfig.Keybinding
-
- return []bindingInfo{
- {
- key: fmt.Sprintf("%s/%s", keybindings.Label(keybindingConfig.Universal.ScrollUpMain), keybindings.Label(keybindingConfig.Universal.ScrollDownMain)),
- description: self.c.Tr.Scroll,
- },
- {
- key: keybindings.Label(keybindingConfig.Universal.Return),
- description: self.c.Tr.Cancel,
- },
- {
- key: keybindings.Label(keybindingConfig.Universal.Quit),
- description: self.c.Tr.Quit,
- },
- {
- key: keybindings.Label(keybindingConfig.Universal.OptionMenuAlt1),
- description: self.c.Tr.Keybindings,
- },
- {
- key: fmt.Sprintf("%s-%s", keybindings.Label(keybindingConfig.Universal.JumpToBlock[0]), keybindings.Label(keybindingConfig.Universal.JumpToBlock[len(keybindingConfig.Universal.JumpToBlock)-1])),
- description: self.c.Tr.Jump,
- },
- {
- key: fmt.Sprintf("%s/%s", keybindings.Label(keybindingConfig.Universal.ScrollLeft), keybindings.Label(keybindingConfig.Universal.ScrollRight)),
- description: self.c.Tr.ScrollLeftRight,
- },
- }
-}
-
type bindingInfo struct {
key string
description string
+ style style.TextStyle
}