diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/commands/types/enums/enums.go | 8 | ||||
-rw-r--r-- | pkg/gui/context.go | 2 | ||||
-rw-r--r-- | pkg/gui/controllers/confirmation_controller.go | 16 | ||||
-rw-r--r-- | pkg/gui/controllers/global_controller.go | 10 | ||||
-rw-r--r-- | pkg/gui/controllers/menu_controller.go | 10 | ||||
-rw-r--r-- | pkg/gui/controllers/merge_conflicts_controller.go | 46 | ||||
-rw-r--r-- | pkg/gui/layout.go | 2 | ||||
-rw-r--r-- | pkg/gui/options_map.go | 157 | ||||
-rw-r--r-- | pkg/gui/types/keybindings.go | 28 | ||||
-rw-r--r-- | pkg/gui/views.go | 1 | ||||
-rw-r--r-- | pkg/integration/components/common.go | 26 | ||||
-rw-r--r-- | pkg/integration/components/views.go | 4 | ||||
-rw-r--r-- | pkg/integration/tests/test_list.go | 1 | ||||
-rw-r--r-- | pkg/integration/tests/ui/mode_specific_keybinding_suggestions.go | 118 |
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)) + }) + }, +}) |