diff --git a/pkg/gui/context.go b/pkg/gui/context.go index 036870a5b..d76747d74 100644 --- a/pkg/gui/context.go +++ b/pkg/gui/context.go @@ -286,7 +286,7 @@ func (gui *Gui) contextTree() ContextTree { }, Merging: SimpleContextNode{ Context: BasicContext{ - OnFocus: gui.refreshMergePanel, + OnFocus: gui.refreshMergePanelWithLock, Kind: MAIN_CONTEXT, ViewName: "main", Key: MAIN_MERGING_CONTEXT_KEY, diff --git a/pkg/gui/files_panel.go b/pkg/gui/files_panel.go index b9477ea1a..b3c180407 100644 --- a/pkg/gui/files_panel.go +++ b/pkg/gui/files_panel.go @@ -73,7 +73,7 @@ func (gui *Gui) selectFile(alreadySelected bool) error { } if node.File != nil && node.File.HasInlineMergeConflicts { - return gui.refreshMergePanel() + return gui.refreshMergePanelWithLock() } cmdStr := gui.GitCommand.WorktreeFileDiffCmdStr(node, false, !node.GetHasUnstagedChanges() && node.GetHasStagedChanges()) diff --git a/pkg/gui/gui.go b/pkg/gui/gui.go index 7c07bbbab..9fbfdb094 100644 --- a/pkg/gui/gui.go +++ b/pkg/gui/gui.go @@ -116,10 +116,11 @@ type lBlPanelState struct { } type mergingPanelState struct { - ConflictIndex int - ConflictTop bool - Conflicts []commands.Conflict - EditHistory *stack.Stack + ConflictIndex int + ConflictTop bool + Conflicts []commands.Conflict + ConflictsMutex sync.Mutex + EditHistory *stack.Stack // UserScrolling tells us if the user has started scrolling through the file themselves // in which case we won't auto-scroll to a conflict. @@ -367,10 +368,11 @@ func (gui *Gui) resetState() { Menu: &menuPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}, OnPress: nil}, Suggestions: &suggestionsPanelState{listPanelState: listPanelState{SelectedLineIdx: 0}}, Merging: &mergingPanelState{ - ConflictIndex: 0, - ConflictTop: true, - Conflicts: []commands.Conflict{}, - EditHistory: stack.New(), + ConflictIndex: 0, + ConflictTop: true, + Conflicts: []commands.Conflict{}, + EditHistory: stack.New(), + ConflictsMutex: sync.Mutex{}, }, }, SideView: nil, diff --git a/pkg/gui/merge_panel.go b/pkg/gui/merge_panel.go index 5ae0ec9b6..2bd1eb6e3 100644 --- a/pkg/gui/merge_panel.go +++ b/pkg/gui/merge_panel.go @@ -79,18 +79,27 @@ func (gui *Gui) takeOverScrolling() { } func (gui *Gui) handleSelectTop(g *gocui.Gui, v *gocui.View) error { + gui.State.Panels.Merging.ConflictsMutex.Lock() + defer gui.State.Panels.Merging.ConflictsMutex.Unlock() + gui.takeOverScrolling() gui.State.Panels.Merging.ConflictTop = true return gui.refreshMergePanel() } func (gui *Gui) handleSelectBottom(g *gocui.Gui, v *gocui.View) error { + gui.State.Panels.Merging.ConflictsMutex.Lock() + defer gui.State.Panels.Merging.ConflictsMutex.Unlock() + gui.takeOverScrolling() gui.State.Panels.Merging.ConflictTop = false return gui.refreshMergePanel() } func (gui *Gui) handleSelectNextConflict(g *gocui.Gui, v *gocui.View) error { + gui.State.Panels.Merging.ConflictsMutex.Lock() + defer gui.State.Panels.Merging.ConflictsMutex.Unlock() + gui.takeOverScrolling() if gui.State.Panels.Merging.ConflictIndex >= len(gui.State.Panels.Merging.Conflicts)-1 { return nil @@ -100,6 +109,9 @@ func (gui *Gui) handleSelectNextConflict(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handleSelectPrevConflict(g *gocui.Gui, v *gocui.View) error { + gui.State.Panels.Merging.ConflictsMutex.Lock() + defer gui.State.Panels.Merging.ConflictsMutex.Unlock() + gui.takeOverScrolling() if gui.State.Panels.Merging.ConflictIndex <= 0 { return nil @@ -172,6 +184,9 @@ func (gui *Gui) handlePopFileSnapshot(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handlePickHunk(g *gocui.Gui, v *gocui.View) error { + gui.State.Panels.Merging.ConflictsMutex.Lock() + defer gui.State.Panels.Merging.ConflictsMutex.Unlock() + gui.takeOverScrolling() conflict := gui.State.Panels.Merging.Conflicts[gui.State.Panels.Merging.ConflictIndex] @@ -198,6 +213,9 @@ func (gui *Gui) handlePickHunk(g *gocui.Gui, v *gocui.View) error { } func (gui *Gui) handlePickBothHunks(g *gocui.Gui, v *gocui.View) error { + gui.State.Panels.Merging.ConflictsMutex.Lock() + defer gui.State.Panels.Merging.ConflictsMutex.Unlock() + gui.takeOverScrolling() conflict := gui.State.Panels.Merging.Conflicts[gui.State.Panels.Merging.ConflictIndex] @@ -211,6 +229,13 @@ func (gui *Gui) handlePickBothHunks(g *gocui.Gui, v *gocui.View) error { return gui.refreshMergePanel() } +func (gui *Gui) refreshMergePanelWithLock() error { + gui.State.Panels.Merging.ConflictsMutex.Lock() + defer gui.State.Panels.Merging.ConflictsMutex.Unlock() + + return gui.refreshMergePanel() +} + func (gui *Gui) refreshMergePanel() error { panelState := gui.State.Panels.Merging cat, err := gui.catSelectedFile()