mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-05-31 23:19:40 +02:00
Show better keybinding suggestions (#3203)
- **PR Description** This PR's goal is to improve discoverability of keybindings in lazygit. I've have a couple people in real life mention to me that it wasn't obvious what key to press for viewing rebase options, for example. This PR: * shows more keybindings in the options view * shows certain keybindings prominently in certain modes e.g. 'view rebase options: m' when mid-rebase. Before:  After:  - **Please check if the PR fulfills these requirements** * [x] Cheatsheets are up-to-date (run `go generate ./...`) * [x] Code has been formatted (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#code-formatting)) * [x] Tests have been added/updated (see [here](https://github.com/jesseduffield/lazygit/blob/master/pkg/integration/README.md) for the integration test guide) * [x] Text is internationalised (see [here](https://github.com/jesseduffield/lazygit/blob/master/CONTRIBUTING.md#internationalisation)) * [x] Docs (specifically `docs/Config.md`) have been updated if necessary * [x] You've read through your own file changes for silly mistakes etc <!-- Be sure to name your PR with an imperative e.g. 'Add worktrees view' see https://github.com/jesseduffield/lazygit/releases/tag/v0.40.0 for examples -->
This commit is contained in:
commit
cf5d4d4f8e
@ -12,3 +12,11 @@ const (
|
|||||||
REBASE_MODE_REBASING
|
REBASE_MODE_REBASING
|
||||||
REBASE_MODE_MERGING
|
REBASE_MODE_MERGING
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (self RebaseMode) IsMerging() bool {
|
||||||
|
return self == REBASE_MODE_MERGING
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self RebaseMode) IsRebasing() bool {
|
||||||
|
return self == REBASE_MODE_INTERACTIVE || self == REBASE_MODE_NORMAL || self == REBASE_MODE_REBASING
|
||||||
|
}
|
||||||
|
@ -245,8 +245,6 @@ func (self *ContextMgr) ActivateContext(c types.Context, opts types.OnFocusOpts)
|
|||||||
|
|
||||||
self.gui.c.GocuiGui().Cursor = v.Editable
|
self.gui.c.GocuiGui().Cursor = v.Editable
|
||||||
|
|
||||||
self.gui.renderContextOptionsMap(c)
|
|
||||||
|
|
||||||
if err := c.HandleFocus(opts); err != nil {
|
if err := c.HandleFocus(opts); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -20,15 +20,11 @@ func NewListViewModel[T HasID](getModel func() []T) *ListViewModel[T] {
|
|||||||
getModel: getModel,
|
getModel: getModel,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.ListCursor = traits.NewListCursor(self)
|
self.ListCursor = traits.NewListCursor(func() int { return len(getModel()) })
|
||||||
|
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ListViewModel[T]) Len() int {
|
|
||||||
return len(self.getModel())
|
|
||||||
}
|
|
||||||
|
|
||||||
func (self *ListViewModel[T]) GetSelected() T {
|
func (self *ListViewModel[T]) GetSelected() T {
|
||||||
if self.Len() == 0 {
|
if self.Len() == 0 {
|
||||||
return Zero[T]()
|
return Zero[T]()
|
||||||
|
@ -5,10 +5,6 @@ import (
|
|||||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HasLength interface {
|
|
||||||
Len() int
|
|
||||||
}
|
|
||||||
|
|
||||||
type RangeSelectMode int
|
type RangeSelectMode int
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -27,15 +23,17 @@ type ListCursor struct {
|
|||||||
rangeSelectMode RangeSelectMode
|
rangeSelectMode RangeSelectMode
|
||||||
// value is ignored when rangeSelectMode is RangeSelectModeNone
|
// value is ignored when rangeSelectMode is RangeSelectModeNone
|
||||||
rangeStartIdx int
|
rangeStartIdx int
|
||||||
list HasLength
|
// Get the length of the list. We use this to clamp the selection so that
|
||||||
|
// the selected index is always valid
|
||||||
|
getLength func() int
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewListCursor(list HasLength) *ListCursor {
|
func NewListCursor(getLength func() int) *ListCursor {
|
||||||
return &ListCursor{
|
return &ListCursor{
|
||||||
selectedIdx: 0,
|
selectedIdx: 0,
|
||||||
rangeStartIdx: 0,
|
rangeStartIdx: 0,
|
||||||
rangeSelectMode: RangeSelectModeNone,
|
rangeSelectMode: RangeSelectModeNone,
|
||||||
list: list,
|
getLength: getLength,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,8 +79,9 @@ func (self *ListCursor) GetSelectionRangeAndMode() (int, int, RangeSelectMode) {
|
|||||||
|
|
||||||
func (self *ListCursor) clampValue(value int) int {
|
func (self *ListCursor) clampValue(value int) int {
|
||||||
clampedValue := -1
|
clampedValue := -1
|
||||||
if self.list.Len() > 0 {
|
length := self.getLength()
|
||||||
clampedValue = utils.Clamp(value, 0, self.list.Len()-1)
|
if length > 0 {
|
||||||
|
clampedValue = utils.Clamp(value, 0, length-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return clampedValue
|
return clampedValue
|
||||||
@ -114,7 +113,12 @@ func (self *ListCursor) ClampSelection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *ListCursor) Len() int {
|
func (self *ListCursor) Len() int {
|
||||||
return self.list.Len()
|
// The length of the model slice can change at any time, so the selection may
|
||||||
|
// become out of bounds. To reduce the likelihood of this, we clamp the selection
|
||||||
|
// whenever we obtain the length of the model.
|
||||||
|
self.ClampSelection()
|
||||||
|
|
||||||
|
return self.getLength()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *ListCursor) GetRangeStartIdx() (int, bool) {
|
func (self *ListCursor) GetRangeStartIdx() (int, bool) {
|
||||||
|
@ -52,6 +52,7 @@ func (self *BasicCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Checkout,
|
Description: self.c.Tr.Checkout,
|
||||||
Tooltip: self.c.Tr.CheckoutCommitTooltip,
|
Tooltip: self.c.Tr.CheckoutCommitTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.CopyCommitAttributeToClipboard),
|
Key: opts.GetKey(opts.Config.Commits.CopyCommitAttributeToClipboard),
|
||||||
@ -80,6 +81,7 @@ func (self *BasicCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
Description: self.c.Tr.ViewResetOptions,
|
Description: self.c.Tr.ViewResetOptions,
|
||||||
Tooltip: self.c.Tr.ResetTooltip,
|
Tooltip: self.c.Tr.ResetTooltip,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.CherryPickCopy),
|
Key: opts.GetKey(opts.Config.Commits.CherryPickCopy),
|
||||||
@ -91,6 +93,7 @@ func (self *BasicCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
"escape": keybindings.Label(opts.Config.Universal.Return),
|
"escape": keybindings.Label(opts.Config.Universal.Return),
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ResetCherryPick),
|
Key: opts.GetKey(opts.Config.Commits.ResetCherryPick),
|
||||||
|
@ -47,14 +47,16 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||||||
self.singleItemSelected(),
|
self.singleItemSelected(),
|
||||||
self.notPulling,
|
self.notPulling,
|
||||||
),
|
),
|
||||||
Description: self.c.Tr.Checkout,
|
Description: self.c.Tr.Checkout,
|
||||||
Tooltip: self.c.Tr.CheckoutTooltip,
|
Tooltip: self.c.Tr.CheckoutTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
Handler: self.withItem(self.newBranch),
|
Handler: self.withItem(self.newBranch),
|
||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.NewBranch,
|
Description: self.c.Tr.NewBranch,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.CreatePullRequest),
|
Key: opts.GetKey(opts.Config.Branches.CreatePullRequest),
|
||||||
@ -95,6 +97,7 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||||||
Description: self.c.Tr.Delete,
|
Description: self.c.Tr.Delete,
|
||||||
Tooltip: self.c.Tr.BranchDeleteTooltip,
|
Tooltip: self.c.Tr.BranchDeleteTooltip,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
||||||
@ -102,8 +105,9 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||||||
GetDisabledReason: self.require(
|
GetDisabledReason: self.require(
|
||||||
self.singleItemSelected(self.notRebasingOntoSelf),
|
self.singleItemSelected(self.notRebasingOntoSelf),
|
||||||
),
|
),
|
||||||
Description: self.c.Tr.RebaseBranch,
|
Description: self.c.Tr.RebaseBranch,
|
||||||
Tooltip: self.c.Tr.RebaseBranchTooltip,
|
Tooltip: self.c.Tr.RebaseBranchTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
Key: opts.GetKey(opts.Config.Branches.MergeIntoCurrentBranch),
|
||||||
@ -111,6 +115,7 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Merge,
|
Description: self.c.Tr.Merge,
|
||||||
Tooltip: self.c.Tr.MergeBranchTooltip,
|
Tooltip: self.c.Tr.MergeBranchTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.FastForward),
|
Key: opts.GetKey(opts.Config.Branches.FastForward),
|
||||||
@ -136,6 +141,7 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.ViewResetOptions,
|
Description: self.c.Tr.ViewResetOptions,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.RenameBranch),
|
Key: opts.GetKey(opts.Config.Branches.RenameBranch),
|
||||||
@ -151,6 +157,7 @@ func (self *BranchesController) GetKeybindings(opts types.KeybindingsOpts) []*ty
|
|||||||
Tooltip: self.c.Tr.ViewBranchUpstreamOptionsTooltip,
|
Tooltip: self.c.Tr.ViewBranchUpstreamOptionsTooltip,
|
||||||
ShortDescription: self.c.Tr.Upstream,
|
ShortDescription: self.c.Tr.Upstream,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,6 +43,7 @@ func (self *CommitFilesController) GetKeybindings(opts types.KeybindingsOpts) []
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Checkout,
|
Description: self.c.Tr.Checkout,
|
||||||
Tooltip: self.c.Tr.CheckoutCommitFileTooltip,
|
Tooltip: self.c.Tr.CheckoutCommitFileTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
@ -50,6 +51,7 @@ func (self *CommitFilesController) GetKeybindings(opts types.KeybindingsOpts) []
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Remove,
|
Description: self.c.Tr.Remove,
|
||||||
Tooltip: self.c.Tr.DiscardOldFileChangeTooltip,
|
Tooltip: self.c.Tr.DiscardOldFileChangeTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
||||||
@ -64,6 +66,7 @@ func (self *CommitFilesController) GetKeybindings(opts types.KeybindingsOpts) []
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Edit,
|
Description: self.c.Tr.Edit,
|
||||||
Tooltip: self.c.Tr.EditFileTooltip,
|
Tooltip: self.c.Tr.EditFileTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenDiffTool),
|
Key: opts.GetKey(opts.Config.Universal.OpenDiffTool),
|
||||||
@ -79,6 +82,7 @@ func (self *CommitFilesController) GetKeybindings(opts types.KeybindingsOpts) []
|
|||||||
Tooltip: utils.ResolvePlaceholderString(self.c.Tr.ToggleAddToPatchTooltip,
|
Tooltip: utils.ResolvePlaceholderString(self.c.Tr.ToggleAddToPatchTooltip,
|
||||||
map[string]string{"doc": constants.Links.Docs.CustomPatchDemo},
|
map[string]string{"doc": constants.Links.Docs.CustomPatchDemo},
|
||||||
),
|
),
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.ToggleStagedAll),
|
Key: opts.GetKey(opts.Config.Files.ToggleStagedAll),
|
||||||
|
@ -24,16 +24,16 @@ func NewConfirmationController(
|
|||||||
func (self *ConfirmationController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *ConfirmationController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
||||||
Handler: func() error { return self.context().State.OnConfirm() },
|
Handler: func() error { return self.context().State.OnConfirm() },
|
||||||
Description: self.c.Tr.Confirm,
|
Description: self.c.Tr.Confirm,
|
||||||
Display: true,
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Return),
|
Key: opts.GetKey(opts.Config.Universal.Return),
|
||||||
Handler: func() error { return self.context().State.OnClose() },
|
Handler: func() error { return self.context().State.OnClose() },
|
||||||
Description: self.c.Tr.CloseCancel,
|
Description: self.c.Tr.CloseCancel,
|
||||||
Display: true,
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
|
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
|
||||||
|
@ -43,6 +43,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
GetDisabledReason: self.require(self.itemsSelected()),
|
GetDisabledReason: self.require(self.itemsSelected()),
|
||||||
Description: self.c.Tr.Stage,
|
Description: self.c.Tr.Stage,
|
||||||
Tooltip: self.c.Tr.StageTooltip,
|
Tooltip: self.c.Tr.StageTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.OpenStatusFilter),
|
Key: opts.GetKey(opts.Config.Files.OpenStatusFilter),
|
||||||
@ -56,10 +57,11 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.CommitChanges),
|
Key: opts.GetKey(opts.Config.Files.CommitChanges),
|
||||||
Handler: self.c.Helpers().WorkingTree.HandleCommitPress,
|
Handler: self.c.Helpers().WorkingTree.HandleCommitPress,
|
||||||
Description: self.c.Tr.Commit,
|
Description: self.c.Tr.Commit,
|
||||||
Tooltip: self.c.Tr.CommitTooltip,
|
Tooltip: self.c.Tr.CommitTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.CommitChangesWithoutHook),
|
Key: opts.GetKey(opts.Config.Files.CommitChangesWithoutHook),
|
||||||
@ -88,6 +90,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Edit,
|
Description: self.c.Tr.Edit,
|
||||||
Tooltip: self.c.Tr.EditFileTooltip,
|
Tooltip: self.c.Tr.EditFileTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
||||||
@ -109,10 +112,11 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
Description: self.c.Tr.RefreshFiles,
|
Description: self.c.Tr.RefreshFiles,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.StashAllChanges),
|
Key: opts.GetKey(opts.Config.Files.StashAllChanges),
|
||||||
Handler: self.stash,
|
Handler: self.stash,
|
||||||
Description: self.c.Tr.Stash,
|
Description: self.c.Tr.Stash,
|
||||||
Tooltip: self.c.Tr.StashTooltip,
|
Tooltip: self.c.Tr.StashTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.ViewStashOptions),
|
Key: opts.GetKey(opts.Config.Files.ViewStashOptions),
|
||||||
@ -141,6 +145,7 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
Description: self.c.Tr.Discard,
|
Description: self.c.Tr.Discard,
|
||||||
Tooltip: self.c.Tr.DiscardFileChangesTooltip,
|
Tooltip: self.c.Tr.DiscardFileChangesTooltip,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
||||||
@ -149,11 +154,12 @@ func (self *FilesController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.ViewResetOptions),
|
Key: opts.GetKey(opts.Config.Files.ViewResetOptions),
|
||||||
Handler: self.createResetMenu,
|
Handler: self.createResetMenu,
|
||||||
Description: self.c.Tr.Reset,
|
Description: self.c.Tr.Reset,
|
||||||
Tooltip: self.c.Tr.FileResetOptionsTooltip,
|
Tooltip: self.c.Tr.FileResetOptionsTooltip,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.ToggleTreeView),
|
Key: opts.GetKey(opts.Config.Files.ToggleTreeView),
|
||||||
|
@ -72,6 +72,7 @@ func (self *GlobalController) GetKeybindings(opts types.KeybindingsOpts) []*type
|
|||||||
Description: self.c.Tr.OpenKeybindingsMenu,
|
Description: self.c.Tr.OpenKeybindingsMenu,
|
||||||
Handler: self.createOptionsMenu,
|
Handler: self.createOptionsMenu,
|
||||||
ShortDescription: self.c.Tr.Keybindings,
|
ShortDescription: self.c.Tr.Keybindings,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
ViewName: "",
|
ViewName: "",
|
||||||
@ -112,10 +113,11 @@ func (self *GlobalController) GetKeybindings(opts types.KeybindingsOpts) []*type
|
|||||||
Handler: self.quitWithoutChangingDirectory,
|
Handler: self.quitWithoutChangingDirectory,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Return),
|
Key: opts.GetKey(opts.Config.Universal.Return),
|
||||||
Modifier: gocui.ModNone,
|
Modifier: gocui.ModNone,
|
||||||
Handler: self.escape,
|
Handler: self.escape,
|
||||||
Description: self.c.Tr.Cancel,
|
Description: self.c.Tr.Cancel,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.ToggleWhitespaceInDiffView),
|
Key: opts.GetKey(opts.Config.Universal.ToggleWhitespaceInDiffView),
|
||||||
|
@ -64,8 +64,9 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
self.canSquashOrFixup,
|
self.canSquashOrFixup,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Description: self.c.Tr.Squash,
|
Description: self.c.Tr.Squash,
|
||||||
Tooltip: self.c.Tr.SquashTooltip,
|
Tooltip: self.c.Tr.SquashTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.MarkCommitAsFixup),
|
Key: opts.GetKey(opts.Config.Commits.MarkCommitAsFixup),
|
||||||
@ -76,8 +77,9 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
self.canSquashOrFixup,
|
self.canSquashOrFixup,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Description: self.c.Tr.Fixup,
|
Description: self.c.Tr.Fixup,
|
||||||
Tooltip: self.c.Tr.FixupTooltip,
|
Tooltip: self.c.Tr.FixupTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.RenameCommit),
|
Key: opts.GetKey(opts.Config.Commits.RenameCommit),
|
||||||
@ -85,9 +87,10 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
GetDisabledReason: self.require(
|
GetDisabledReason: self.require(
|
||||||
self.singleItemSelected(self.rewordEnabled),
|
self.singleItemSelected(self.rewordEnabled),
|
||||||
),
|
),
|
||||||
Description: self.c.Tr.Reword,
|
Description: self.c.Tr.Reword,
|
||||||
Tooltip: self.c.Tr.CommitRewordTooltip,
|
Tooltip: self.c.Tr.CommitRewordTooltip,
|
||||||
OpensMenu: true,
|
DisplayOnScreen: true,
|
||||||
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.RenameCommitWithEditor),
|
Key: opts.GetKey(opts.Config.Commits.RenameCommitWithEditor),
|
||||||
@ -105,8 +108,9 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
self.midRebaseCommandEnabled,
|
self.midRebaseCommandEnabled,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Description: self.c.Tr.DropCommit,
|
Description: self.c.Tr.DropCommit,
|
||||||
Tooltip: self.c.Tr.DropCommitTooltip,
|
Tooltip: self.c.Tr.DropCommitTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(editCommitKey),
|
Key: opts.GetKey(editCommitKey),
|
||||||
@ -118,6 +122,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
Description: self.c.Tr.EditCommit,
|
Description: self.c.Tr.EditCommit,
|
||||||
ShortDescription: self.c.Tr.Edit,
|
ShortDescription: self.c.Tr.Edit,
|
||||||
Tooltip: self.c.Tr.EditCommitTooltip,
|
Tooltip: self.c.Tr.EditCommitTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
// The user-facing description here is 'Start interactive rebase' but internally
|
// The user-facing description here is 'Start interactive rebase' but internally
|
||||||
@ -139,6 +144,14 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
),
|
),
|
||||||
Description: self.c.Tr.Pick,
|
Description: self.c.Tr.Pick,
|
||||||
Tooltip: self.c.Tr.PickCommitTooltip,
|
Tooltip: self.c.Tr.PickCommitTooltip,
|
||||||
|
// Not displaying this because we only want to display it when a TODO commit
|
||||||
|
// is selected. A keybinding is displayed in the options view if Display is true,
|
||||||
|
// and if it's not disabled, but if we disable it whenever a non-TODO commit is
|
||||||
|
// selected, we'll be preventing pulls from happening within the commits view
|
||||||
|
// (given they both use the 'p' key). Some approaches that come to mind:
|
||||||
|
// * Allow a disabled keybinding to conditionally fallback to a global keybinding
|
||||||
|
// * Allow a separate way of deciding whether a keybinding is displayed in the options view
|
||||||
|
DisplayOnScreen: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.CreateFixupCommit),
|
Key: opts.GetKey(opts.Config.Commits.CreateFixupCommit),
|
||||||
@ -221,6 +234,7 @@ func (self *LocalCommitsController) GetKeybindings(opts types.KeybindingsOpts) [
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected(self.canAmend)),
|
GetDisabledReason: self.require(self.singleItemSelected(self.canAmend)),
|
||||||
Description: self.c.Tr.Amend,
|
Description: self.c.Tr.Amend,
|
||||||
Tooltip: self.c.Tr.AmendCommitTooltip,
|
Tooltip: self.c.Tr.AmendCommitTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ResetCommitAuthor),
|
Key: opts.GetKey(opts.Config.Commits.ResetCommitAuthor),
|
||||||
|
@ -42,13 +42,13 @@ func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
|||||||
Handler: self.withItem(self.press),
|
Handler: self.withItem(self.press),
|
||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Execute,
|
Description: self.c.Tr.Execute,
|
||||||
Display: true,
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Return),
|
Key: opts.GetKey(opts.Config.Universal.Return),
|
||||||
Handler: self.close,
|
Handler: self.close,
|
||||||
Description: self.c.Tr.Close,
|
Description: self.c.Tr.Close,
|
||||||
Display: true,
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,50 +28,54 @@ func NewMergeConflictsController(
|
|||||||
func (self *MergeConflictsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *MergeConflictsController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.withRenderAndFocus(self.HandlePickHunk),
|
Handler: self.withRenderAndFocus(self.HandlePickHunk),
|
||||||
Description: self.c.Tr.PickHunk,
|
Description: self.c.Tr.PickHunk,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Main.PickBothHunks),
|
Key: opts.GetKey(opts.Config.Main.PickBothHunks),
|
||||||
Handler: self.withRenderAndFocus(self.HandlePickAllHunks),
|
Handler: self.withRenderAndFocus(self.HandlePickAllHunks),
|
||||||
Description: self.c.Tr.PickAllHunks,
|
Description: self.c.Tr.PickAllHunks,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.PrevItem),
|
Key: opts.GetKey(opts.Config.Universal.PrevItem),
|
||||||
Handler: self.withRenderAndFocus(self.PrevConflictHunk),
|
Handler: self.withRenderAndFocus(self.PrevConflictHunk),
|
||||||
Description: self.c.Tr.SelectPrevHunk,
|
Description: self.c.Tr.SelectPrevHunk,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.NextItem),
|
Key: opts.GetKey(opts.Config.Universal.NextItem),
|
||||||
Handler: self.withRenderAndFocus(self.NextConflictHunk),
|
Handler: self.withRenderAndFocus(self.NextConflictHunk),
|
||||||
Description: self.c.Tr.SelectNextHunk,
|
Description: self.c.Tr.SelectNextHunk,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.PrevBlock),
|
Key: opts.GetKey(opts.Config.Universal.PrevBlock),
|
||||||
Handler: self.withRenderAndFocus(self.PrevConflict),
|
Handler: self.withRenderAndFocus(self.PrevConflict),
|
||||||
Description: self.c.Tr.PrevConflict,
|
Description: self.c.Tr.PrevConflict,
|
||||||
Display: true,
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.NextBlock),
|
Key: opts.GetKey(opts.Config.Universal.NextBlock),
|
||||||
Handler: self.withRenderAndFocus(self.NextConflict),
|
Handler: self.withRenderAndFocus(self.NextConflict),
|
||||||
Description: self.c.Tr.NextConflict,
|
Description: self.c.Tr.NextConflict,
|
||||||
Display: true,
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Undo),
|
Key: opts.GetKey(opts.Config.Universal.Undo),
|
||||||
Handler: self.withRenderAndFocus(self.HandleUndo),
|
Handler: self.withRenderAndFocus(self.HandleUndo),
|
||||||
Description: self.c.Tr.Undo,
|
Description: self.c.Tr.Undo,
|
||||||
Tooltip: self.c.Tr.UndoMergeResolveTooltip,
|
Tooltip: self.c.Tr.UndoMergeResolveTooltip,
|
||||||
Display: true,
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Edit),
|
Key: opts.GetKey(opts.Config.Universal.Edit),
|
||||||
Handler: self.HandleEditFile,
|
Handler: self.HandleEditFile,
|
||||||
Description: self.c.Tr.EditFile,
|
Description: self.c.Tr.EditFile,
|
||||||
Tooltip: self.c.Tr.EditFileTooltip,
|
Tooltip: self.c.Tr.EditFileTooltip,
|
||||||
Display: true,
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
||||||
@ -108,11 +112,11 @@ func (self *MergeConflictsController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
Tag: "navigation",
|
Tag: "navigation",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Files.OpenMergeTool),
|
Key: opts.GetKey(opts.Config.Files.OpenMergeTool),
|
||||||
Handler: self.c.Helpers().WorkingTree.OpenMergeTool,
|
Handler: self.c.Helpers().WorkingTree.OpenMergeTool,
|
||||||
Description: self.c.Tr.OpenMergeTool,
|
Description: self.c.Tr.OpenMergeTool,
|
||||||
Tooltip: self.c.Tr.OpenMergeToolTooltip,
|
Tooltip: self.c.Tr.OpenMergeToolTooltip,
|
||||||
Display: true,
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Return),
|
Key: opts.GetKey(opts.Config.Universal.Return),
|
||||||
|
@ -37,9 +37,10 @@ func (self *PatchBuildingController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
Tooltip: self.c.Tr.EditFileTooltip,
|
Tooltip: self.c.Tr.EditFileTooltip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.ToggleSelectionAndRefresh,
|
Handler: self.ToggleSelectionAndRefresh,
|
||||||
Description: self.c.Tr.ToggleSelectionForPatch,
|
Description: self.c.Tr.ToggleSelectionForPatch,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Return),
|
Key: opts.GetKey(opts.Config.Universal.Return),
|
||||||
|
@ -92,10 +92,11 @@ func (self *PatchExplorerController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
Description: self.c.Tr.ToggleRangeSelect,
|
Description: self.c.Tr.ToggleRangeSelect,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Main.ToggleSelectHunk),
|
Key: opts.GetKey(opts.Config.Main.ToggleSelectHunk),
|
||||||
Handler: self.withRenderAndFocus(self.HandleToggleSelectHunk),
|
Handler: self.withRenderAndFocus(self.HandleToggleSelectHunk),
|
||||||
Description: self.c.Tr.ToggleSelectHunk,
|
Description: self.c.Tr.ToggleSelectHunk,
|
||||||
Tooltip: self.c.Tr.ToggleSelectHunkTooltip,
|
Tooltip: self.c.Tr.ToggleSelectHunkTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Tag: "navigation",
|
Tag: "navigation",
|
||||||
|
@ -41,6 +41,7 @@ func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Checkout,
|
Description: self.c.Tr.Checkout,
|
||||||
Tooltip: self.c.Tr.RemoteBranchCheckoutTooltip,
|
Tooltip: self.c.Tr.RemoteBranchCheckoutTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
@ -54,6 +55,7 @@ func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Merge,
|
Description: self.c.Tr.Merge,
|
||||||
Tooltip: self.c.Tr.MergeBranchTooltip,
|
Tooltip: self.c.Tr.MergeBranchTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
Key: opts.GetKey(opts.Config.Branches.RebaseBranch),
|
||||||
@ -61,6 +63,7 @@ func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.RebaseBranch,
|
Description: self.c.Tr.RebaseBranch,
|
||||||
Tooltip: self.c.Tr.RebaseBranchTooltip,
|
Tooltip: self.c.Tr.RebaseBranchTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
@ -68,6 +71,7 @@ func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Delete,
|
Description: self.c.Tr.Delete,
|
||||||
Tooltip: self.c.Tr.DeleteRemoteBranchTooltip,
|
Tooltip: self.c.Tr.DeleteRemoteBranchTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
|
Key: opts.GetKey(opts.Config.Branches.SetUpstream),
|
||||||
@ -75,6 +79,7 @@ func (self *RemoteBranchesController) GetKeybindings(opts types.KeybindingsOpts)
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.SetAsUpstream,
|
Description: self.c.Tr.SetAsUpstream,
|
||||||
Tooltip: self.c.Tr.SetAsUpstreamTooltip,
|
Tooltip: self.c.Tr.SetAsUpstreamTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.SortOrder),
|
Key: opts.GetKey(opts.Config.Branches.SortOrder),
|
||||||
|
@ -46,11 +46,13 @@ func (self *RemotesController) GetKeybindings(opts types.KeybindingsOpts) []*typ
|
|||||||
Handler: self.withItem(self.enter),
|
Handler: self.withItem(self.enter),
|
||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.ViewBranches,
|
Description: self.c.Tr.ViewBranches,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
Handler: self.add,
|
Handler: self.add,
|
||||||
Description: self.c.Tr.NewRemote,
|
Description: self.c.Tr.NewRemote,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
@ -58,6 +60,7 @@ func (self *RemotesController) GetKeybindings(opts types.KeybindingsOpts) []*typ
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Remove,
|
Description: self.c.Tr.Remove,
|
||||||
Tooltip: self.c.Tr.RemoveRemoteTooltip,
|
Tooltip: self.c.Tr.RemoveRemoteTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Edit),
|
Key: opts.GetKey(opts.Config.Universal.Edit),
|
||||||
@ -65,6 +68,7 @@ func (self *RemotesController) GetKeybindings(opts types.KeybindingsOpts) []*typ
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Edit,
|
Description: self.c.Tr.Edit,
|
||||||
Tooltip: self.c.Tr.EditRemoteTooltip,
|
Tooltip: self.c.Tr.EditRemoteTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.FetchRemote),
|
Key: opts.GetKey(opts.Config.Branches.FetchRemote),
|
||||||
@ -72,6 +76,7 @@ func (self *RemotesController) GetKeybindings(opts types.KeybindingsOpts) []*typ
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Fetch,
|
Description: self.c.Tr.Fetch,
|
||||||
Tooltip: self.c.Tr.FetchRemoteTooltip,
|
Tooltip: self.c.Tr.FetchRemoteTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,16 +40,18 @@ func NewStagingController(
|
|||||||
func (self *StagingController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *StagingController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
return []*types.Binding{
|
return []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
Handler: self.ToggleStaged,
|
Handler: self.ToggleStaged,
|
||||||
Description: self.c.Tr.Stage,
|
Description: self.c.Tr.Stage,
|
||||||
Tooltip: self.c.Tr.StageSelectionTooltip,
|
Tooltip: self.c.Tr.StageSelectionTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
Handler: self.DiscardSelection,
|
Handler: self.DiscardSelection,
|
||||||
Description: self.c.Tr.DiscardSelection,
|
Description: self.c.Tr.DiscardSelection,
|
||||||
Tooltip: self.c.Tr.DiscardSelectionTooltip,
|
Tooltip: self.c.Tr.DiscardSelectionTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
Key: opts.GetKey(opts.Config.Universal.OpenFile),
|
||||||
@ -69,10 +71,11 @@ func (self *StagingController) GetKeybindings(opts types.KeybindingsOpts) []*typ
|
|||||||
Description: self.c.Tr.ReturnToFilesPanel,
|
Description: self.c.Tr.ReturnToFilesPanel,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
|
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
|
||||||
Handler: self.TogglePanel,
|
Handler: self.TogglePanel,
|
||||||
Description: self.c.Tr.ToggleStagingView,
|
Description: self.c.Tr.ToggleStagingView,
|
||||||
Tooltip: self.c.Tr.ToggleStagingViewTooltip,
|
Tooltip: self.c.Tr.ToggleStagingViewTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Main.EditSelectHunk),
|
Key: opts.GetKey(opts.Config.Main.EditSelectHunk),
|
||||||
|
@ -38,6 +38,7 @@ func (self *StashController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Apply,
|
Description: self.c.Tr.Apply,
|
||||||
Tooltip: self.c.Tr.StashApplyTooltip,
|
Tooltip: self.c.Tr.StashApplyTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Stash.PopStash),
|
Key: opts.GetKey(opts.Config.Stash.PopStash),
|
||||||
@ -45,6 +46,7 @@ func (self *StashController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Pop,
|
Description: self.c.Tr.Pop,
|
||||||
Tooltip: self.c.Tr.StashPopTooltip,
|
Tooltip: self.c.Tr.StashPopTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
@ -52,6 +54,7 @@ func (self *StashController) GetKeybindings(opts types.KeybindingsOpts) []*types
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Drop,
|
Description: self.c.Tr.Drop,
|
||||||
Tooltip: self.c.Tr.StashDropTooltip,
|
Tooltip: self.c.Tr.StashDropTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
|
@ -39,20 +39,23 @@ func (self *StatusController) GetKeybindings(opts types.KeybindingsOpts) []*type
|
|||||||
Tooltip: self.c.Tr.OpenFileTooltip,
|
Tooltip: self.c.Tr.OpenFileTooltip,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Edit),
|
Key: opts.GetKey(opts.Config.Universal.Edit),
|
||||||
Handler: self.editConfig,
|
Handler: self.editConfig,
|
||||||
Description: self.c.Tr.EditConfig,
|
Description: self.c.Tr.EditConfig,
|
||||||
Tooltip: self.c.Tr.EditFileTooltip,
|
Tooltip: self.c.Tr.EditFileTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Status.CheckForUpdate),
|
Key: opts.GetKey(opts.Config.Status.CheckForUpdate),
|
||||||
Handler: self.handleCheckForUpdate,
|
Handler: self.handleCheckForUpdate,
|
||||||
Description: self.c.Tr.CheckForUpdate,
|
Description: self.c.Tr.CheckForUpdate,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Status.RecentRepos),
|
Key: opts.GetKey(opts.Config.Status.RecentRepos),
|
||||||
Handler: self.c.Helpers().Repos.CreateRecentReposMenu,
|
Handler: self.c.Helpers().Repos.CreateRecentReposMenu,
|
||||||
Description: self.c.Tr.SwitchRepo,
|
Description: self.c.Tr.SwitchRepo,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Status.AllBranchesLogGraph),
|
Key: opts.GetKey(opts.Config.Status.AllBranchesLogGraph),
|
||||||
|
@ -46,6 +46,7 @@ func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []*
|
|||||||
Description: self.c.Tr.Enter,
|
Description: self.c.Tr.Enter,
|
||||||
Tooltip: utils.ResolvePlaceholderString(self.c.Tr.EnterSubmoduleTooltip,
|
Tooltip: utils.ResolvePlaceholderString(self.c.Tr.EnterSubmoduleTooltip,
|
||||||
map[string]string{"escape": keybindings.Label(opts.Config.Universal.Return)}),
|
map[string]string{"escape": keybindings.Label(opts.Config.Universal.Return)}),
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
@ -58,6 +59,7 @@ func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []*
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Remove,
|
Description: self.c.Tr.Remove,
|
||||||
Tooltip: self.c.Tr.RemoveSubmoduleTooltip,
|
Tooltip: self.c.Tr.RemoveSubmoduleTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Submodules.Update),
|
Key: opts.GetKey(opts.Config.Submodules.Update),
|
||||||
@ -65,11 +67,13 @@ func (self *SubmodulesController) GetKeybindings(opts types.KeybindingsOpts) []*
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Update,
|
Description: self.c.Tr.Update,
|
||||||
Tooltip: self.c.Tr.SubmoduleUpdateTooltip,
|
Tooltip: self.c.Tr.SubmoduleUpdateTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
Handler: self.add,
|
Handler: self.add,
|
||||||
Description: self.c.Tr.NewSubmodule,
|
Description: self.c.Tr.NewSubmodule,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Edit),
|
Key: opts.GetKey(opts.Config.Universal.Edit),
|
||||||
|
@ -39,12 +39,14 @@ func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Checkout,
|
Description: self.c.Tr.Checkout,
|
||||||
Tooltip: self.c.Tr.TagCheckoutTooltip,
|
Tooltip: self.c.Tr.TagCheckoutTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
Handler: self.create,
|
Handler: self.create,
|
||||||
Description: self.c.Tr.NewTag,
|
Description: self.c.Tr.NewTag,
|
||||||
Tooltip: self.c.Tr.NewTagTooltip,
|
Tooltip: self.c.Tr.NewTagTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Remove),
|
Key: opts.GetKey(opts.Config.Universal.Remove),
|
||||||
@ -53,6 +55,7 @@ func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Tooltip: self.c.Tr.TagDeleteTooltip,
|
Tooltip: self.c.Tr.TagDeleteTooltip,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Branches.PushTag),
|
Key: opts.GetKey(opts.Config.Branches.PushTag),
|
||||||
@ -60,6 +63,7 @@ func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.PushTag,
|
Description: self.c.Tr.PushTag,
|
||||||
Tooltip: self.c.Tr.PushTagTooltip,
|
Tooltip: self.c.Tr.PushTagTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
Key: opts.GetKey(opts.Config.Commits.ViewResetOptions),
|
||||||
@ -67,6 +71,7 @@ func (self *TagsController) GetKeybindings(opts types.KeybindingsOpts) []*types.
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Reset,
|
Description: self.c.Tr.Reset,
|
||||||
Tooltip: self.c.Tr.ResetTooltip,
|
Tooltip: self.c.Tr.ResetTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
OpensMenu: true,
|
OpensMenu: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -37,9 +37,10 @@ func NewWorktreesController(
|
|||||||
func (self *WorktreesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
func (self *WorktreesController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
|
||||||
bindings := []*types.Binding{
|
bindings := []*types.Binding{
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.New),
|
Key: opts.GetKey(opts.Config.Universal.New),
|
||||||
Handler: self.add,
|
Handler: self.add,
|
||||||
Description: self.c.Tr.NewWorktree,
|
Description: self.c.Tr.NewWorktree,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Select),
|
Key: opts.GetKey(opts.Config.Universal.Select),
|
||||||
@ -47,6 +48,7 @@ func (self *WorktreesController) GetKeybindings(opts types.KeybindingsOpts) []*t
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Switch,
|
Description: self.c.Tr.Switch,
|
||||||
Tooltip: self.c.Tr.SwitchToWorktreeTooltip,
|
Tooltip: self.c.Tr.SwitchToWorktreeTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
Key: opts.GetKey(opts.Config.Universal.Confirm),
|
||||||
@ -65,6 +67,7 @@ func (self *WorktreesController) GetKeybindings(opts types.KeybindingsOpts) []*t
|
|||||||
GetDisabledReason: self.require(self.singleItemSelected()),
|
GetDisabledReason: self.require(self.singleItemSelected()),
|
||||||
Description: self.c.Tr.Remove,
|
Description: self.c.Tr.Remove,
|
||||||
Tooltip: self.c.Tr.RemoveWorktreeTooltip,
|
Tooltip: self.c.Tr.RemoveWorktreeTooltip,
|
||||||
|
DisplayOnScreen: true,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,8 +22,8 @@ type ICommitFileTreeViewModel interface {
|
|||||||
|
|
||||||
type CommitFileTreeViewModel struct {
|
type CommitFileTreeViewModel struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
ICommitFileTree
|
|
||||||
types.IListCursor
|
types.IListCursor
|
||||||
|
ICommitFileTree
|
||||||
|
|
||||||
// this is e.g. the commit for which we're viewing the files
|
// this is e.g. the commit for which we're viewing the files
|
||||||
ref types.Ref
|
ref types.Ref
|
||||||
@ -37,7 +37,7 @@ var _ ICommitFileTreeViewModel = &CommitFileTreeViewModel{}
|
|||||||
|
|
||||||
func NewCommitFileTreeViewModel(getFiles func() []*models.CommitFile, log *logrus.Entry, showTree bool) *CommitFileTreeViewModel {
|
func NewCommitFileTreeViewModel(getFiles func() []*models.CommitFile, log *logrus.Entry, showTree bool) *CommitFileTreeViewModel {
|
||||||
fileTree := NewCommitFileTree(getFiles, log, showTree)
|
fileTree := NewCommitFileTree(getFiles, log, showTree)
|
||||||
listCursor := traits.NewListCursor(fileTree)
|
listCursor := traits.NewListCursor(fileTree.Len)
|
||||||
return &CommitFileTreeViewModel{
|
return &CommitFileTreeViewModel{
|
||||||
ICommitFileTree: fileTree,
|
ICommitFileTree: fileTree,
|
||||||
IListCursor: listCursor,
|
IListCursor: listCursor,
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
|
|
||||||
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
"github.com/jesseduffield/lazygit/pkg/commands/models"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
"github.com/jesseduffield/lazygit/pkg/gui/types"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
"github.com/sirupsen/logrus"
|
"github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -138,7 +139,8 @@ func (self *FileTree) GetAllItems() []*FileNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *FileTree) Len() int {
|
func (self *FileTree) Len() int {
|
||||||
return self.tree.Size(self.collapsedPaths) - 1 // ignoring root
|
// -1 because we're ignoring the root
|
||||||
|
return utils.Max(self.tree.Size(self.collapsedPaths)-1, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *FileTree) GetItem(index int) types.HasUrn {
|
func (self *FileTree) GetItem(index int) types.HasUrn {
|
||||||
|
@ -21,15 +21,15 @@ type IFileTreeViewModel interface {
|
|||||||
// after the files are refreshed
|
// after the files are refreshed
|
||||||
type FileTreeViewModel struct {
|
type FileTreeViewModel struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
IFileTree
|
|
||||||
types.IListCursor
|
types.IListCursor
|
||||||
|
IFileTree
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ IFileTreeViewModel = &FileTreeViewModel{}
|
var _ IFileTreeViewModel = &FileTreeViewModel{}
|
||||||
|
|
||||||
func NewFileTreeViewModel(getFiles func() []*models.File, log *logrus.Entry, showTree bool) *FileTreeViewModel {
|
func NewFileTreeViewModel(getFiles func() []*models.File, log *logrus.Entry, showTree bool) *FileTreeViewModel {
|
||||||
fileTree := NewFileTree(getFiles, log, showTree)
|
fileTree := NewFileTree(getFiles, log, showTree)
|
||||||
listCursor := traits.NewListCursor(fileTree)
|
listCursor := traits.NewListCursor(fileTree.Len)
|
||||||
return &FileTreeViewModel{
|
return &FileTreeViewModel{
|
||||||
IFileTree: fileTree,
|
IFileTree: fileTree,
|
||||||
IListCursor: listCursor,
|
IListCursor: listCursor,
|
||||||
@ -54,6 +54,10 @@ func (self *FileTreeViewModel) GetSelectedItemId() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *FileTreeViewModel) GetSelectedItems() ([]*FileNode, int, int) {
|
func (self *FileTreeViewModel) GetSelectedItems() ([]*FileNode, int, int) {
|
||||||
|
if self.Len() == 0 {
|
||||||
|
return nil, 0, 0
|
||||||
|
}
|
||||||
|
|
||||||
startIdx, endIdx := self.GetSelectionRange()
|
startIdx, endIdx := self.GetSelectionRange()
|
||||||
|
|
||||||
nodes := []*FileNode{}
|
nodes := []*FileNode{}
|
||||||
|
@ -165,6 +165,8 @@ func (gui *Gui) layout(g *gocui.Gui) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gui.renderContextOptionsMap()
|
||||||
|
|
||||||
outer:
|
outer:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
@ -4,9 +4,13 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/gui/context"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
|
"github.com/jesseduffield/lazygit/pkg/gui/controllers/helpers"
|
||||||
"github.com/jesseduffield/lazygit/pkg/gui/keybindings"
|
"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/gui/types"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/theme"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||||
"github.com/samber/lo"
|
"github.com/samber/lo"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -14,30 +18,89 @@ type OptionsMapMgr struct {
|
|||||||
c *helpers.HelperCommon
|
c *helpers.HelperCommon
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) renderContextOptionsMap(c types.Context) {
|
func (gui *Gui) renderContextOptionsMap() {
|
||||||
// In demos, we render our own content to this view
|
// In demos, we render our own content to this view
|
||||||
if gui.integrationTest != nil && gui.integrationTest.IsDemo() {
|
if gui.integrationTest != nil && gui.integrationTest.IsDemo() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mgr := OptionsMapMgr{c: gui.c}
|
mgr := OptionsMapMgr{c: gui.c}
|
||||||
mgr.renderContextOptionsMap(c)
|
mgr.renderContextOptionsMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
// render the options available for the current context at the bottom of the screen
|
// Render the options available for the current context at the bottom of the screen
|
||||||
func (self *OptionsMapMgr) renderContextOptionsMap(c types.Context) {
|
// STYLE GUIDE: we use the default options fg color for most keybindings. We can
|
||||||
bindingsToDisplay := lo.Filter(c.GetKeybindings(self.c.KeybindingsOpts()), func(binding *types.Binding, _ int) bool {
|
// only use a different color if we're in a specific mode where the user is likely
|
||||||
return binding.Display
|
// 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()
|
||||||
})
|
})
|
||||||
|
|
||||||
var optionsMap []bindingInfo
|
optionsMap := lo.Map(bindingsToDisplay, func(binding *types.Binding, _ int) bindingInfo {
|
||||||
if len(bindingsToDisplay) == 0 {
|
displayStyle := theme.OptionsFgColor
|
||||||
optionsMap = self.globalOptions()
|
if binding.DisplayStyle != nil {
|
||||||
} else {
|
displayStyle = *binding.DisplayStyle
|
||||||
optionsMap = lo.Map(bindingsToDisplay, func(binding *types.Binding, _ int) bindingInfo {
|
}
|
||||||
return bindingInfo{
|
|
||||||
key: keybindings.LabelFromKey(binding.Key),
|
description := binding.Description
|
||||||
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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,49 +108,41 @@ func (self *OptionsMapMgr) renderContextOptionsMap(c types.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *OptionsMapMgr) formatBindingInfos(bindingInfos []bindingInfo) string {
|
func (self *OptionsMapMgr) formatBindingInfos(bindingInfos []bindingInfo) string {
|
||||||
return strings.Join(
|
width := self.c.Views().Options.Width() - 4 // -4 for the padding
|
||||||
lo.Map(bindingInfos, func(bindingInfo bindingInfo, _ int) string {
|
var builder strings.Builder
|
||||||
return fmt.Sprintf("%s: %s", bindingInfo.key, bindingInfo.description)
|
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) {
|
func (self *OptionsMapMgr) renderOptions(options string) {
|
||||||
self.c.SetViewContent(self.c.Views().Options, options)
|
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 {
|
type bindingInfo struct {
|
||||||
key string
|
key string
|
||||||
description string
|
description string
|
||||||
|
style style.TextStyle
|
||||||
}
|
}
|
||||||
|
@ -11,21 +11,25 @@ type Key interface{} // FIXME: find out how to get `gocui.Key | rune`
|
|||||||
// is only handled if the given view has focus, or handled globally if the view
|
// is only handled if the given view has focus, or handled globally if the view
|
||||||
// is ""
|
// is ""
|
||||||
type Binding struct {
|
type Binding struct {
|
||||||
ViewName string
|
ViewName string
|
||||||
Handler func() error
|
Handler func() error
|
||||||
Key Key
|
Key Key
|
||||||
Modifier gocui.Modifier
|
Modifier gocui.Modifier
|
||||||
Description string
|
Description 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
|
ShortDescription string
|
||||||
Alternative string
|
Alternative string
|
||||||
Tag string // e.g. 'navigation'. Used for grouping things in the cheatsheet
|
Tag string // e.g. 'navigation'. Used for grouping things in the cheatsheet
|
||||||
OpensMenu bool
|
OpensMenu bool
|
||||||
|
|
||||||
// If true, the keybinding will appear at the bottom of the screen. If
|
// If true, the keybinding will appear at the bottom of the screen.
|
||||||
// the given view has no bindings with Display: true, the default keybindings
|
// Even if set to true, the keybinding will not be displayed if it is currently
|
||||||
// will be displayed instead.
|
// disabled. We could instead display it with a strikethrough, but there's
|
||||||
// TODO: implement this
|
// limited realestate to show all the keybindings we want, so we're hiding it instead.
|
||||||
Display bool
|
DisplayOnScreen bool
|
||||||
|
// if unset, the binding will be displayed in the default color. Only applies to the keybinding
|
||||||
|
// on-screen, not in the keybindings menu.
|
||||||
DisplayStyle *style.TextStyle
|
DisplayStyle *style.TextStyle
|
||||||
|
|
||||||
// to be displayed if the keybinding is highlighted from within a menu
|
// to be displayed if the keybinding is highlighted from within a menu
|
||||||
@ -39,6 +43,10 @@ type Binding struct {
|
|||||||
GetDisabledReason func() *DisabledReason
|
GetDisabledReason func() *DisabledReason
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (Binding *Binding) IsDisabled() bool {
|
||||||
|
return Binding.GetDisabledReason != nil && Binding.GetDisabledReason() != nil
|
||||||
|
}
|
||||||
|
|
||||||
// A guard is a decorator which checks something before executing a handler
|
// A guard is a decorator which checks something before executing a handler
|
||||||
// and potentially early-exits if some precondition hasn't been met.
|
// and potentially early-exits if some precondition hasn't been met.
|
||||||
type Guard func(func() error) func() error
|
type Guard func(func() error) func() error
|
||||||
|
@ -94,7 +94,6 @@ func (gui *Gui) createAllViews() error {
|
|||||||
(*mapping.viewPtr).SelBgColor = theme.GocuiSelectedLineBgColor
|
(*mapping.viewPtr).SelBgColor = theme.GocuiSelectedLineBgColor
|
||||||
}
|
}
|
||||||
|
|
||||||
gui.Views.Options.FgColor = theme.OptionsColor
|
|
||||||
gui.Views.Options.Frame = false
|
gui.Views.Options.Frame = false
|
||||||
|
|
||||||
gui.Views.SearchPrefix.BgColor = gocui.ColorDefault
|
gui.Views.SearchPrefix.BgColor = gocui.ColorDefault
|
||||||
|
@ -62,3 +62,29 @@ func (self *Common) SelectPatchOption(matcher *TextMatcher) {
|
|||||||
|
|
||||||
self.t.ExpectPopup().Menu().Title(Equals("Patch options")).Select(matcher).Confirm()
|
self.t.ExpectPopup().Menu().Title(Equals("Patch options")).Select(matcher).Confirm()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Common) ResetBisect() {
|
||||||
|
self.t.Views().Commits().
|
||||||
|
Focus().
|
||||||
|
Press(self.t.keys.Commits.ViewBisectOptions).
|
||||||
|
Tap(func() {
|
||||||
|
self.t.ExpectPopup().Menu().
|
||||||
|
Title(Equals("Bisect")).
|
||||||
|
Select(Contains("Reset bisect")).
|
||||||
|
Confirm()
|
||||||
|
|
||||||
|
self.t.ExpectPopup().Confirmation().
|
||||||
|
Title(Equals("Reset 'git bisect'")).
|
||||||
|
Content(Contains("Are you sure you want to reset 'git bisect'?")).
|
||||||
|
Confirm()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *Common) ResetCustomPatch() {
|
||||||
|
self.t.GlobalPress(self.t.keys.Universal.CreatePatchOptionsMenu)
|
||||||
|
|
||||||
|
self.t.ExpectPopup().Menu().
|
||||||
|
Title(Equals("Patch options")).
|
||||||
|
Select(Contains("Reset patch")).
|
||||||
|
Confirm()
|
||||||
|
}
|
||||||
|
@ -147,3 +147,7 @@ func (self *Views) Search() *ViewDriver {
|
|||||||
func (self *Views) Tooltip() *ViewDriver {
|
func (self *Views) Tooltip() *ViewDriver {
|
||||||
return self.regularView("tooltip")
|
return self.regularView("tooltip")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *Views) Options() *ViewDriver {
|
||||||
|
return self.regularView("options")
|
||||||
|
}
|
||||||
|
@ -269,6 +269,7 @@ var tests = []*components.IntegrationTest{
|
|||||||
ui.Accordion,
|
ui.Accordion,
|
||||||
ui.DoublePopup,
|
ui.DoublePopup,
|
||||||
ui.EmptyMenu,
|
ui.EmptyMenu,
|
||||||
|
ui.ModeSpecificKeybindingSuggestions,
|
||||||
ui.OpenLinkFailure,
|
ui.OpenLinkFailure,
|
||||||
ui.RangeSelect,
|
ui.RangeSelect,
|
||||||
ui.SwitchTabFromMenu,
|
ui.SwitchTabFromMenu,
|
||||||
|
118
pkg/integration/tests/ui/mode_specific_keybinding_suggestions.go
Normal file
118
pkg/integration/tests/ui/mode_specific_keybinding_suggestions.go
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
package ui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/config"
|
||||||
|
. "github.com/jesseduffield/lazygit/pkg/integration/components"
|
||||||
|
"github.com/jesseduffield/lazygit/pkg/integration/tests/shared"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ModeSpecificKeybindingSuggestions = NewIntegrationTest(NewIntegrationTestArgs{
|
||||||
|
Description: "When in various modes, we should corresponding keybinding suggestions onscreen",
|
||||||
|
ExtraCmdArgs: []string{},
|
||||||
|
Skip: false,
|
||||||
|
SetupConfig: func(config *config.AppConfig) {},
|
||||||
|
SetupRepo: func(shell *Shell) {
|
||||||
|
shell.CreateNCommits(2)
|
||||||
|
shell.NewBranch("base-branch")
|
||||||
|
shared.MergeConflictsSetup(shell)
|
||||||
|
shell.Checkout("base-branch")
|
||||||
|
},
|
||||||
|
Run: func(t *TestDriver, keys config.KeybindingConfig) {
|
||||||
|
rebaseSuggestion := "View rebase options: m"
|
||||||
|
cherryPickSuggestion := "Paste (cherry-pick): V"
|
||||||
|
bisectSuggestion := "View bisect options: b"
|
||||||
|
customPatchSuggestion := "View custom patch options: <c-p>"
|
||||||
|
mergeSuggestion := "View merge options: m"
|
||||||
|
|
||||||
|
t.Views().Commits().
|
||||||
|
Focus().
|
||||||
|
Lines(
|
||||||
|
Contains("commit 02").IsSelected(),
|
||||||
|
Contains("commit 01"),
|
||||||
|
).
|
||||||
|
Tap(func() {
|
||||||
|
// These suggestions are mode-specific so are not shown by default
|
||||||
|
t.Views().Options().Content(
|
||||||
|
DoesNotContain(rebaseSuggestion).
|
||||||
|
DoesNotContain(mergeSuggestion).
|
||||||
|
DoesNotContain(cherryPickSuggestion).
|
||||||
|
DoesNotContain(bisectSuggestion).
|
||||||
|
DoesNotContain(customPatchSuggestion),
|
||||||
|
)
|
||||||
|
}).
|
||||||
|
// Start an interactive rebase
|
||||||
|
Press(keys.Universal.Edit).
|
||||||
|
Tap(func() {
|
||||||
|
// Confirm the rebase suggestion now appears
|
||||||
|
t.Views().Options().Content(Contains(rebaseSuggestion))
|
||||||
|
}).
|
||||||
|
Press(keys.Commits.CherryPickCopy).
|
||||||
|
Tap(func() {
|
||||||
|
// Confirm the cherry pick suggestion now appears
|
||||||
|
t.Views().Options().Content(Contains(cherryPickSuggestion))
|
||||||
|
// Importantly, we show multiple of these suggestions at once
|
||||||
|
t.Views().Options().Content(Contains(rebaseSuggestion))
|
||||||
|
}).
|
||||||
|
// Cancel the cherry pick
|
||||||
|
PressEscape().
|
||||||
|
Tap(func() {
|
||||||
|
t.Views().Options().Content(DoesNotContain(cherryPickSuggestion))
|
||||||
|
}).
|
||||||
|
// Cancel the rebase
|
||||||
|
Tap(func() {
|
||||||
|
t.Common().AbortRebase()
|
||||||
|
|
||||||
|
t.Views().Options().Content(DoesNotContain(rebaseSuggestion))
|
||||||
|
}).
|
||||||
|
Press(keys.Commits.ViewBisectOptions).
|
||||||
|
Tap(func() {
|
||||||
|
t.ExpectPopup().Menu().
|
||||||
|
Title(Equals("Bisect")).
|
||||||
|
Select(MatchesRegexp("Mark.* as bad")).
|
||||||
|
Confirm()
|
||||||
|
|
||||||
|
t.Views().Options().Content(Contains(bisectSuggestion))
|
||||||
|
|
||||||
|
// Cancel bisect
|
||||||
|
t.Common().ResetBisect()
|
||||||
|
|
||||||
|
t.Views().Options().Content(DoesNotContain(bisectSuggestion))
|
||||||
|
}).
|
||||||
|
// Enter commit files view
|
||||||
|
PressEnter()
|
||||||
|
|
||||||
|
t.Views().CommitFiles().
|
||||||
|
IsFocused().
|
||||||
|
// Add a commit file to the patch
|
||||||
|
Press(keys.Universal.Select).
|
||||||
|
Tap(func() {
|
||||||
|
t.Views().Options().Content(Contains(customPatchSuggestion))
|
||||||
|
|
||||||
|
t.Common().ResetCustomPatch()
|
||||||
|
|
||||||
|
t.Views().Options().Content(DoesNotContain(customPatchSuggestion))
|
||||||
|
})
|
||||||
|
|
||||||
|
// Test merge options suggestion
|
||||||
|
t.Views().Branches().
|
||||||
|
Focus().
|
||||||
|
NavigateToLine(Contains("first-change-branch")).
|
||||||
|
Press(keys.Universal.Select).
|
||||||
|
NavigateToLine(Contains("second-change-branch")).
|
||||||
|
Press(keys.Branches.MergeIntoCurrentBranch).
|
||||||
|
Tap(func() {
|
||||||
|
t.ExpectPopup().Confirmation().
|
||||||
|
Title(Equals("Merge")).
|
||||||
|
Content(Contains("Are you sure you want to merge")).
|
||||||
|
Confirm()
|
||||||
|
|
||||||
|
t.Common().AcknowledgeConflicts()
|
||||||
|
|
||||||
|
t.Views().Options().Content(Contains(mergeSuggestion))
|
||||||
|
|
||||||
|
t.Common().AbortMerge()
|
||||||
|
|
||||||
|
t.Views().Options().Content(DoesNotContain(mergeSuggestion))
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
Loading…
x
Reference in New Issue
Block a user