1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
package gui
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"
)
type OptionsMapMgr struct {
c *helpers.HelperCommon
}
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()
}
// 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,
}
})
// 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,
})
}
self.renderOptions(self.formatBindingInfos(optionsMap))
}
func (self *OptionsMapMgr) formatBindingInfos(bindingInfos []bindingInfo) string {
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)
}
type bindingInfo struct {
key string
description string
style style.TextStyle
}
|