Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion pkg/gui/controllers/global_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (self *GlobalController) GetKeybindings(opts types.KeybindingsOpts) []*type
},
{
Key: opts.GetKey(opts.Config.Universal.Refresh),
Handler: opts.Guards.NoPopupPanel(self.refresh),
Handler: self.refreshAllowPopupAutoClose,
Description: self.c.Tr.Refresh,
Tooltip: self.c.Tr.RefreshTooltip,
},
Expand Down Expand Up @@ -172,6 +172,22 @@ func (self *GlobalController) refresh() error {
return nil
}

func (self *GlobalController) refreshAllowPopupAutoClose() error {
if self.c.Helpers().Confirmation.IsPopupPanelFocused() && !self.canRefreshWithPopup() {
return nil
}

return self.refresh()
}

func (self *GlobalController) canRefreshWithPopup() bool {
self.c.Mutexes().PopupMutex.Lock()
defer self.c.Mutexes().PopupMutex.Unlock()

popupOpts := self.c.State().GetRepoState().GetCurrentPopupOpts()
return popupOpts != nil && popupOpts.AutoCloseCondition != types.PopupAutoCloseNone
}

func (self *GlobalController) nextScreenMode() error {
return (&ScreenModeActions{c: self.c}).Next()
}
Expand Down
10 changes: 6 additions & 4 deletions pkg/gui/controllers/helpers/merge_and_rebase_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,9 @@ func (self *MergeAndRebaseHelper) AbortMergeOrRebaseWithConfirm() error {
// PromptToContinueRebase asks the user if they want to continue the rebase/merge that's in progress
func (self *MergeAndRebaseHelper) PromptToContinueRebase() error {
self.c.Confirm(types.ConfirmOpts{
Title: self.c.Tr.Continue,
Prompt: fmt.Sprintf(self.c.Tr.ConflictsResolved, self.c.Git().Status.WorkingTreeState().CommandName()),
Title: self.c.Tr.Continue,
Prompt: fmt.Sprintf(self.c.Tr.ConflictsResolved, self.c.Git().Status.WorkingTreeState().CommandName()),
AutoCloseCondition: types.PopupAutoCloseWorkingTreeStateNone,
HandleConfirm: func() error {
// By the time we get here, we might have unstaged changes again,
// e.g. if the user had to fix build errors after resolving the
Expand All @@ -240,8 +241,9 @@ func (self *MergeAndRebaseHelper) PromptToContinueRebase() error {
root := self.c.Contexts().Files.FileTreeViewModel.GetRoot()
if root.GetHasUnstagedChanges() {
self.c.Confirm(types.ConfirmOpts{
Title: self.c.Tr.Continue,
Prompt: self.c.Tr.UnstagedFilesAfterConflictsResolved,
Title: self.c.Tr.Continue,
Prompt: self.c.Tr.UnstagedFilesAfterConflictsResolved,
AutoCloseCondition: types.PopupAutoCloseWorkingTreeStateNone,
HandleConfirm: func() error {
self.c.LogAction(self.c.Tr.Actions.StageAllFiles)
if err := self.c.Git().WorkingTree.StageAll(true); err != nil {
Expand Down
35 changes: 34 additions & 1 deletion pkg/gui/controllers/helpers/refresh_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,8 @@ func (self *RefreshHelper) refreshStateFiles() error {
}
}

if self.c.Git().Status.WorkingTreeState().Any() && conflictFileCount == 0 && prevConflictFileCount > 0 {
workingTreeState := self.c.Git().Status.WorkingTreeState()
if workingTreeState.Any() && conflictFileCount == 0 && prevConflictFileCount > 0 {
self.c.OnUIThread(func() error { return self.mergeAndRebaseHelper.PromptToContinueRebase() })
}

Expand All @@ -600,6 +601,37 @@ func (self *RefreshHelper) refreshStateFiles() error {
return nil
}

func (self *RefreshHelper) autoClosePopupIfNeeded(workingTreeState models.WorkingTreeState) {
if !workingTreeState.None() {
return
}

if !self.shouldAutoClosePopup(types.PopupAutoCloseWorkingTreeStateNone) {
return
}

self.c.OnUIThread(func() error {
if !self.shouldAutoClosePopup(types.PopupAutoCloseWorkingTreeStateNone) {
return nil
}
if self.c.Context().IsCurrent(self.c.Contexts().Confirmation) {
return self.c.Contexts().Confirmation.State.OnClose()
}
if self.c.Context().IsCurrent(self.c.Contexts().Prompt) {
return self.c.Contexts().Prompt.State.OnClose()
}
return nil
})
}

func (self *RefreshHelper) shouldAutoClosePopup(condition types.PopupAutoCloseCondition) bool {
self.c.Mutexes().PopupMutex.Lock()
defer self.c.Mutexes().PopupMutex.Unlock()

popupOpts := self.c.State().GetRepoState().GetCurrentPopupOpts()
return popupOpts != nil && popupOpts.AutoCloseCondition == condition
}

// the reflogs panel is the only panel where we cache data, in that we only
// load entries that have been created since we last ran the call. This means
// we need to be more careful with how we use this, and to ensure we're emptying
Expand Down Expand Up @@ -712,6 +744,7 @@ func (self *RefreshHelper) refreshStatus() {
}

workingTreeState := self.c.Git().Status.WorkingTreeState()
self.autoClosePopupIfNeeded(workingTreeState)
linkedWorktreeName := self.worktreeHelper.GetLinkedWorktreeName()

repoName := self.c.Git().RepoPaths.RepoName()
Expand Down
16 changes: 6 additions & 10 deletions pkg/gui/popup/popup_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,21 +108,17 @@ func (self *PopupHandler) Alert(title string, message string) {

func (self *PopupHandler) Confirm(opts types.ConfirmOpts) {
self.createPopupPanelFn(context.Background(), types.CreatePopupPanelOpts{
Title: opts.Title,
Prompt: opts.Prompt,
HandleConfirm: opts.HandleConfirm,
HandleClose: opts.HandleClose,
Title: opts.Title,
Prompt: opts.Prompt,
HandleConfirm: opts.HandleConfirm,
HandleClose: opts.HandleClose,
AutoCloseCondition: opts.AutoCloseCondition,
})
}

func (self *PopupHandler) ConfirmIf(condition bool, opts types.ConfirmOpts) error {
if condition {
self.createPopupPanelFn(context.Background(), types.CreatePopupPanelOpts{
Title: opts.Title,
Prompt: opts.Prompt,
HandleConfirm: opts.HandleConfirm,
HandleClose: opts.HandleClose,
})
self.Confirm(opts)
return nil
}

Expand Down
9 changes: 9 additions & 0 deletions pkg/gui/types/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ const (
ToastKindError
)

type PopupAutoCloseCondition int

const (
PopupAutoCloseNone PopupAutoCloseCondition = iota
PopupAutoCloseWorkingTreeStateNone
)

type CreateMenuOptions struct {
Title string
Prompt string // a message that will be displayed above the menu options
Expand All @@ -168,6 +175,7 @@ type CreatePopupPanelOpts struct {
HandleConfirmPrompt func(string) error
HandleClose func() error
HandleDeleteSuggestion func(int) error
AutoCloseCondition PopupAutoCloseCondition

FindSuggestionsFunc func(string) []*Suggestion
Mask bool
Expand All @@ -184,6 +192,7 @@ type ConfirmOpts struct {
FindSuggestionsFunc func(string) []*Suggestion
Editable bool
Mask bool
AutoCloseCondition PopupAutoCloseCondition
}

type PromptOpts struct {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package branch

import (
"github.com/jesseduffield/lazygit/pkg/config"
. "github.com/jesseduffield/lazygit/pkg/integration/components"
"github.com/jesseduffield/lazygit/pkg/integration/tests/shared"
)

var RebaseConflictsResolvedExternally = NewIntegrationTest(NewIntegrationTestArgs{
Description: "Resolve conflicts and continue rebase externally, verify popup auto-dismisses.",
ExtraCmdArgs: []string{},
Skip: false,
SetupConfig: func(config *config.AppConfig) {
config.GetUserConfig().Git.LocalBranchSortOrder = "recency"
},
SetupRepo: func(shell *Shell) {
shared.MergeConflictsSetup(shell)
},
Run: func(t *TestDriver, keys config.KeybindingConfig) {
t.Views().Branches().
Focus().
Lines(
Contains("first-change-branch"),
Contains("second-change-branch"),
Contains("original-branch"),
).
SelectNextItem().
Press(keys.Branches.RebaseBranch)

t.ExpectPopup().Menu().
Title(Equals("Rebase 'first-change-branch'")).
Select(Contains("Simple rebase")).
Confirm()

t.Common().AcknowledgeConflicts()

t.Views().Files().
IsFocused().
Tap(func() {
t.Shell().UpdateFile("file", shared.FirstChangeFileContent)
t.Shell().GitAdd("file")
}).
Press(keys.Universal.Refresh)

t.ExpectPopup().Confirmation().
Title(Equals("Continue")).
Content(Contains("All merge conflicts resolved. Continue the rebase?"))

t.Shell().RunCommandWithEnv([]string{"git", "rebase", "--continue"}, []string{
"GIT_EDITOR=true",
"GIT_SEQUENCE_EDITOR=true",
"EDITOR=true",
"VISUAL=true",
"GIT_TERMINAL_PROMPT=0",
})

t.GlobalPress(keys.Universal.Refresh)
t.Wait(500) // Allow time for the refresh to complete and the popup to auto-close

t.Views().Files().IsFocused()
t.Views().Information().Content(DoesNotContain("Rebasing"))
},
})
1 change: 1 addition & 0 deletions pkg/integration/tests/test_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ var tests = []*components.IntegrationTest{
branch.RebaseAndDrop,
branch.RebaseCancelOnConflict,
branch.RebaseConflictsFixBuildErrors,
branch.RebaseConflictsResolvedExternally,
branch.RebaseCopiedBranch,
branch.RebaseDoesNotAutosquash,
branch.RebaseFromMarkedBase,
Expand Down
Loading