summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--pkg/commands/types/enums/enums.go8
-rw-r--r--pkg/gui/context.go2
-rw-r--r--pkg/gui/controllers/confirmation_controller.go16
-rw-r--r--pkg/gui/controllers/global_controller.go10
-rw-r--r--pkg/gui/controllers/menu_controller.go10
-rw-r--r--pkg/gui/controllers/merge_conflicts_controller.go46
-rw-r--r--pkg/gui/layout.go2
-rw-r--r--pkg/gui/options_map.go157
-rw-r--r--pkg/gui/types/keybindings.go28
-rw-r--r--pkg/gui/views.go1
-rw-r--r--pkg/integration/components/common.go26
-rw-r--r--pkg/integration/components/views.go4
-rw-r--r--pkg/integration/tests/test_list.go1
-rw-r--r--pkg/integration/tests/ui/mode_specific_keybinding_suggestions.go118
14 files changed, 325 insertions, 104 deletions
diff --git a/pkg/commands/types/enums/enums.go b/pkg/commands/types/enums/enums.go
index 7e8a81798..68a29d8f0 100644
--- a/pkg/commands/types/enums/enums.go
+++ b/pkg/commands/types/enums/enums.go
@@ -12,3 +12,11 @@ const (
REBASE_MODE_REBASING
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
+}
diff --git a/pkg/gui/context.go b/pkg/gui/context.go
index d845265a3..be5a720e3 100644
--- a/pkg/gui/context.go
+++ b/pkg/gui/context.go
@@ -245,8 +245,6 @@ func (self *ContextMgr) ActivateContext(c types.Context, opts types.OnFocusOpts)
self.gui.c.GocuiGui().Cursor = v.Editable
- self.gui.renderContextOptionsMap(c)
-
if err := c.HandleFocus(opts); err != nil {
return err
}
diff --git a/pkg/gui/controllers/confirmation_controller.go b/pkg/gui/controllers/confirmation_controller.go
index 164af19ec..aa5617fa8 100644
--- a/pkg/gui/controllers/confirmation_controller.go
+++ b/pkg/gui/controllers/confirmation_controller.go
@@ -24,16 +24,16 @@ func NewConfirmationController(
func (self *ConfirmationController) GetKeybindings(opts types.KeybindingsOpts) []*types.Binding {
bindings := []*types.Binding{
{
- Key: opts.GetKey(opts.Config.Universal.Confirm),
- Handler: func() error { return self.context().State.OnConfirm() },
- Description: self.c.Tr.Confirm,
- Display: true,
+ Key: opts.GetKey(opts.Config.Universal.Confirm),
+ Handler: func() error { return self.context().State.OnConfirm() },
+ Description: self.c.Tr.Confirm,
+ DisplayOnScreen: true,
},
{
- Key: opts.GetKey(opts.Config.Universal.Return),
- Handler: func() error { return self.context().State.OnClose() },
- Description: self.c.Tr.CloseCancel,
- Display: true,
+ Key: opts.GetKey(opts.Config.Universal.Return),
+ Handler: func() error { return self.context().State.OnClose() },
+ Description: self.c.Tr.CloseCancel,
+ DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.TogglePanel),
diff --git a/pkg/gui/controllers/global_controller.go b/pkg/gui/controllers/global_controller.go
index ba02ac26a..548c8461e 100644
--- a/pkg/gui/controllers/global_controller.go
+++ b/pkg/gui/controllers/global_controller.go
@@ -72,6 +72,7 @@ func (self *GlobalController) GetKeybindings(opts types.KeybindingsOpts) []*type
Description: self.c.Tr.OpenKeybindingsMenu,
Handler: self.createOptionsMenu,
ShortDescription: self.c.Tr.Keybindings,
+ DisplayOnScreen: true,
},
{
ViewName: "",
@@ -112,10 +113,11 @@ func (self *GlobalController) GetKeybindings(opts types.KeybindingsOpts) []*type
Handler: self.quitWithoutChangingDirectory,
},
{
- Key: opts.GetKey(opts.Config.Universal.Return),
- Modifier: gocui.ModNone,
- Handler: self.escape,
- Description: self.c.Tr.Cancel,
+ Key: opts.GetKey(opts.Config.Universal.Return),
+ Modifier: gocui.ModNone,
+ Handler: self.escape,
+ Description: self.c.Tr.Cancel,
+ DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.ToggleWhitespaceInDiffView),
diff --git a/pkg/gui/controllers/menu_controller.go b/pkg/gui/controllers/menu_controller.go
index a64189138..ddd0b2c18 100644
--- a/pkg/gui/controllers/menu_controller.go
+++ b/pkg/gui/controllers/menu_controller.go
@@ -42,13 +42,13 @@ func (self *MenuController) GetKeybindings(opts types.KeybindingsOpts) []*types.
Handler: self.withItem(self.press),
GetDisabledReason: self.require(self.singleItemSelected()),
Description: self.c.Tr.Execute,
- Display: true,
+ DisplayOnScreen: true,
},
{
- Key: opts.GetKey(opts.Config.Universal.Return),
- Handler: self.close,
- Description: self.c.Tr.Close,
- Display: true,
+ Key: opts.GetKey(opts.Config.Universal.Return),
+ Handler: self.close,
+ Description: self.c.Tr.Close,
+ DisplayOnScreen: true,
},
}
diff --git a/pkg/gui/controllers/merge_conflicts_controller.go b/pkg/gui/controllers/merge_conflicts_controller.go
index e0d4cae06..03ca4a10b 100644
--- a/pkg/gui/controllers/merge_conflicts_controller.go
+++ b/pkg/gui/controllers/merge_conflicts_controller.go
@@ -48,30 +48,30 @@ func (self *MergeConflictsController) GetKeybindings(opts types.KeybindingsOpts)
Description: self.c.Tr.SelectNextHunk,
},
{
- Key: opts.GetKey(opts.Config.Universal.PrevBlock),
- Handler: self.withRenderAndFocus(self.PrevConflict),
- Description: self.c.Tr.PrevConflict,
- Display: true,
+ Key: opts.GetKey(opts.Config.Universal.PrevBlock),
+ Handler: self.withRenderAndFocus(self.PrevConflict),
+ Description: self.c.Tr.PrevConflict,
+ DisplayOnScreen: true,
},
{
- Key: opts.GetKey(opts.Config.Universal.NextBlock),
- Handler: self.withRenderAndFocus(self.NextConflict),
- Description: self.c.Tr.NextConflict,
- Display: true,
+ Key: opts.GetKey(opts.Config.Universal.NextBlock),
+ Handler: self.withRenderAndFocus(self.NextConflict),
+ Description: self.c.Tr.NextConflict,
+ DisplayOnScreen: true,
},
{
- Key: opts.GetKey(opts.Config.Universal.Undo),
- Handler: self.withRenderAndFocus(self.HandleUndo),
- Description: self.c.Tr.Undo,
- Tooltip: self.c.Tr.UndoMergeResolveTooltip,
- Display: true,
+ Key: opts.GetKey(opts.Config.Universal.Undo),
+ Handler: self.withRenderAndFocus(self.HandleUndo),
+ Description: self.c.Tr.Undo,
+ Tooltip: self.c.Tr.UndoMergeResolveTooltip,
+ DisplayOnScreen: true,
},
{
- Key: opts.GetKey(opts.Config.Universal.Edit),
- Handler: self.HandleEditFile,
- Description: self.c.Tr.EditFile,
- Tooltip: self.c.Tr.EditFileTooltip,
- Display: true,
+ Key: opts.GetKey(opts.Config.Universal.Edit),
+ Handler: self.HandleEditFile,
+ Description: self.c.Tr.EditFile,
+ Tooltip: self.c.Tr.EditFileTooltip,
+ DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.OpenFile),
@@ -108,11 +108,11 @@ func (self *MergeConflictsController) GetKeybindings(opts types.KeybindingsOpts)
Tag: "navigation",
},
{
- Key: opts.GetKey(opts.Config.Files.OpenMergeTool),
- Handler: self.c.Helpers().WorkingTree.OpenMergeTool,
- Description: self.c.Tr.OpenMergeTool,
- Tooltip: self.c.Tr.OpenMergeToolTooltip,
- Display: true,
+ Key: opts.GetKey(opts.Config.Files.OpenMergeTool),
+ Handler: self.c.Helpers().WorkingTree.OpenMergeTool,
+ Description: self.c.Tr.OpenMergeTool,
+ Tooltip: self.c.Tr.OpenMergeToolTooltip,
+ DisplayOnScreen: true,
},
{
Key: opts.GetKey(opts.Config.Universal.Return),
diff --git a/pkg/gui/layout.go b/pkg/gui/layout.go
index 02c74b023..823dfe994 100644
--- a/pkg/gui/layout.go
+++ b/pkg/gui/layout.go
@@ -165,6 +165,8 @@ func (gui *Gui) layout(g *gocui.Gui) error {
return err
}
+ gui.renderContextOptionsMap()
+
outer:
for {
select {
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
}
diff --git a/pkg/gui/types/keybindings.go b/pkg/gui/types/keybindings.go
index 7d2c19bd4..db21e7bc9 100644
--- a/pkg/gui/types/keybindings.go
+++ b/pkg/gui/types/keybindings.go
@@ -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 ""
type Binding struct {
- ViewName string
- Handler func() error
- Key Key
- Modifier gocui.Modifier
- Description string
+ ViewName string
+ Handler func() error
+ Key Key
+ Modifier gocui.Modifier
+ 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
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. If
- // the given view has no bindings with Display: true, the default keybindings
- // will be displayed instead.
- // TODO: implement this
- Display 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
+ // disabled. We could instead display it with a strikethrough, but there's
+ // limited realestate to show all the keybindings we want, so we're hiding it instead.
+ 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
// to be displayed if the keybinding is highlighted from within a menu
@@ -39,6 +43,10 @@ type Binding struct {
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
// and potentially early-exits if some precondition hasn't been met.
type Guard func(func() error) func() error
diff --git a/pkg/gui/views.go b/pkg/gui/views.go
index be279c9d4..13caa9c7f 100644
--- a/pkg/gui/views.go
+++ b/pkg/gui/views.go
@@ -94,7 +94,6 @@ func (gui *Gui) createAllViews() error {
(*mapping.viewPtr).SelBgColor = theme.GocuiSelectedLineBgColor
}
- gui.Views.Options.FgColor = theme.OptionsColor
gui.Views.Options.Frame = false
gui.Views.SearchPrefix.BgColor = gocui.ColorDefault
diff --git a/pkg/integration/components/common.go b/pkg/integration/components/common.go
index 4f7cd9754..2033a9442 100644
--- a/pkg/integration/components/common.go
+++ b/pkg/integration/components/common.go
@@ -62,3 +62,29 @@ func (self *Common) SelectPatchOption(matcher *TextMatcher) {
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()
+}
diff --git a/pkg/integration/components/views.go b/pkg/integration/components/views.go
index edb2b85b6..873aca650 100644
--- a/pkg/integration/components/views.go
+++ b/pkg/integration/components/views.go
@@ -147,3 +147,7 @@ func (self *Views) Search() *ViewDriver {
func (self *Views) Tooltip() *ViewDriver {
return self.regularView("tooltip")
}
+
+func (self *Views) Options() *ViewDriver {
+ return self.regularView("options")
+}
diff --git a/pkg/integration/tests/test_list.go b/pkg/integration/tests/test_list.go
index 2406b2f78..f4693faef 100644
--- a/pkg/integration/tests/test_list.go
+++ b/pkg/integration/tests/test_list.go
@@ -269,6 +269,7 @@ var tests = []*components.IntegrationTest{
ui.Accordion,
ui.DoublePopup,
ui.EmptyMenu,
+ ui.ModeSpecificKeybindingSuggestions,
ui.OpenLinkFailure,
ui.RangeSelect,
ui.SwitchTabFromMenu,
diff --git a/pkg/integration/tests/ui/mode_specific_keybinding_suggestions.go b/pkg/integration/tests/ui/mode_specific_keybinding_suggestions.go
new file mode 100644
index 000000000..f11e5fd27
--- /dev/null
+++ b/pkg/integration/tests/ui/mode_specific_keybinding_suggestions.go
@@ -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))
+ })
+ },
+})