diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2021-04-18 18:07:10 +1000 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2021-04-18 18:58:09 +1000 |
commit | 98375dc902513a8b0759985a270d8d895cba1199 (patch) | |
tree | cf3d55df66def3da29b03be9985a70ad1eb73435 /pkg/gui/merge_panel.go | |
parent | e73de332a1efcc8f25e5e0f4f9e0a42d7aabb923 (diff) |
refactor merge panel
Diffstat (limited to 'pkg/gui/merge_panel.go')
-rw-r--r-- | pkg/gui/merge_panel.go | 135 |
1 files changed, 49 insertions, 86 deletions
diff --git a/pkg/gui/merge_panel.go b/pkg/gui/merge_panel.go index 0b4e30903..51376ccf8 100644 --- a/pkg/gui/merge_panel.go +++ b/pkg/gui/merge_panel.go @@ -3,14 +3,11 @@ package gui import ( - "bufio" "fmt" "io/ioutil" "math" - "os" "github.com/go-errors/errors" - "github.com/golang-collections/collections/stack" "github.com/jesseduffield/gocui" "github.com/jesseduffield/lazygit/pkg/commands" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" @@ -20,7 +17,7 @@ import ( func (gui *Gui) handleSelectTop() error { return gui.withMergeConflictLock(func() error { gui.takeOverMergeConflictScrolling() - gui.State.Panels.Merging.ConflictTop = true + gui.State.Panels.Merging.SelectTopOption() return gui.refreshMergePanel() }) } @@ -28,7 +25,7 @@ func (gui *Gui) handleSelectTop() error { func (gui *Gui) handleSelectBottom() error { return gui.withMergeConflictLock(func() error { gui.takeOverMergeConflictScrolling() - gui.State.Panels.Merging.ConflictTop = false + gui.State.Panels.Merging.SelectBottomOption() return gui.refreshMergePanel() }) } @@ -36,10 +33,7 @@ func (gui *Gui) handleSelectBottom() error { func (gui *Gui) handleSelectNextConflict() error { return gui.withMergeConflictLock(func() error { gui.takeOverMergeConflictScrolling() - if gui.State.Panels.Merging.ConflictIndex >= len(gui.State.Panels.Merging.Conflicts)-1 { - return nil - } - gui.State.Panels.Merging.ConflictIndex++ + gui.State.Panels.Merging.SelectNextConflict() return gui.refreshMergePanel() }) } @@ -47,32 +41,26 @@ func (gui *Gui) handleSelectNextConflict() error { func (gui *Gui) handleSelectPrevConflict() error { return gui.withMergeConflictLock(func() error { gui.takeOverMergeConflictScrolling() - if gui.State.Panels.Merging.ConflictIndex <= 0 { - return nil - } - gui.State.Panels.Merging.ConflictIndex-- + gui.State.Panels.Merging.SelectPrevConflict() return gui.refreshMergePanel() }) } func (gui *Gui) pushFileSnapshot() error { - gitFile := gui.getSelectedFile() - if gitFile == nil { - return nil - } - content, err := gui.GitCommand.CatFile(gitFile.Name) + content, err := gui.catSelectedFile() if err != nil { return err } - gui.State.Panels.Merging.EditHistory.Push(content) + gui.State.Panels.Merging.PushFileSnapshot(content) return nil } func (gui *Gui) handlePopFileSnapshot() error { - if gui.State.Panels.Merging.EditHistory.Len() == 0 { + prevContent, ok := gui.State.Panels.Merging.PopFileSnapshot() + if !ok { return nil } - prevContent := gui.State.Panels.Merging.EditHistory.Pop().(string) + gitFile := gui.getSelectedFile() if gitFile == nil { return nil @@ -87,28 +75,18 @@ func (gui *Gui) handlePopFileSnapshot() error { func (gui *Gui) handlePickHunk() error { return gui.withMergeConflictLock(func() error { - conflict := gui.getCurrentConflict() - if conflict == nil { - return nil - } - gui.takeOverMergeConflictScrolling() - if err := gui.pushFileSnapshot(); err != nil { + ok, err := gui.resolveConflict(gui.State.Panels.Merging.Selection()) + if err != nil { return err } - selection := mergeconflicts.BOTTOM - if gui.State.Panels.Merging.ConflictTop { - selection = mergeconflicts.TOP - } - err := gui.resolveConflict(*conflict, selection) - if err != nil { - panic(err) + if !ok { + return nil } - // if that was the last conflict, finish the merge for this file - if len(gui.State.Panels.Merging.Conflicts) == 1 { + if gui.State.Panels.Merging.IsFinalConflict() { if err := gui.handleCompleteMerge(); err != nil { return err } @@ -119,53 +97,38 @@ func (gui *Gui) handlePickHunk() error { func (gui *Gui) handlePickBothHunks() error { return gui.withMergeConflictLock(func() error { - conflict := gui.getCurrentConflict() - if conflict == nil { - return nil - } - gui.takeOverMergeConflictScrolling() - if err := gui.pushFileSnapshot(); err != nil { + ok, err := gui.resolveConflict(mergeconflicts.BOTH) + if err != nil { return err } - err := gui.resolveConflict(*conflict, mergeconflicts.BOTH) - if err != nil { - panic(err) + + if !ok { + return nil } + return gui.refreshMergePanel() }) } -func (gui *Gui) getCurrentConflict() *commands.Conflict { - if len(gui.State.Panels.Merging.Conflicts) == 0 { - return nil - } - - return &gui.State.Panels.Merging.Conflicts[gui.State.Panels.Merging.ConflictIndex] -} - -func (gui *Gui) resolveConflict(conflict commands.Conflict, selection mergeconflicts.Selection) error { +func (gui *Gui) resolveConflict(selection mergeconflicts.Selection) (bool, error) { gitFile := gui.getSelectedFile() if gitFile == nil { - return nil + return false, nil } - file, err := os.Open(gitFile.Name) + + ok, output, err := gui.State.Panels.Merging.ContentAfterConflictResolve(gitFile.Name, selection) if err != nil { - return err + return false, err } - defer file.Close() - reader := bufio.NewReader(file) - output := "" - for i := 0; true; i++ { - line, err := reader.ReadString('\n') - if err != nil { - break - } - if !mergeconflicts.IsIndexToDelete(i, conflict, selection) { - output += line - } + if !ok { + return false, nil + } + + if err := gui.pushFileSnapshot(); err != nil { + return false, gui.surfaceError(err) } var logStr string @@ -178,7 +141,7 @@ func (gui *Gui) resolveConflict(conflict commands.Conflict, selection mergeconfl logStr = "Picking both hunks" } gui.OnRunCommand(oscommands.NewCmdLogEntry(logStr, "Resolve merge conflict", false)) - return ioutil.WriteFile(gitFile.Name, []byte(output), 0644) + return true, ioutil.WriteFile(gitFile.Name, []byte(output), 0644) } func (gui *Gui) refreshMergePanelWithLock() error { @@ -197,17 +160,14 @@ func (gui *Gui) refreshMergePanel() error { }) } - panelState.Conflicts = mergeconflicts.FindConflicts(cat) + panelState.SetConflictsFromCat(cat) - // handle potential fixes that the user made in their editor since we last refreshed - if len(panelState.Conflicts) == 0 { + if panelState.NoConflicts() { return gui.handleCompleteMerge() - } else if panelState.ConflictIndex > len(panelState.Conflicts)-1 { - panelState.ConflictIndex = len(panelState.Conflicts) - 1 } hasFocus := gui.currentViewName() == "main" - content := mergeconflicts.ColoredConflictFile(cat, panelState.Conflicts, panelState.ConflictIndex, panelState.ConflictTop, hasFocus) + content := mergeconflicts.ColoredConflictFile(cat, panelState.State, hasFocus) if err := gui.scrollToConflict(); err != nil { return err @@ -246,19 +206,22 @@ func (gui *Gui) scrollToConflict() error { } panelState := gui.State.Panels.Merging - if len(panelState.Conflicts) == 0 { + if panelState.NoConflicts() { return nil } - mergingView := gui.Views.Main - conflict := panelState.Conflicts[panelState.ConflictIndex] - ox, _ := mergingView.Origin() - _, height := mergingView.Size() - newOriginY := int(math.Max(0, float64(conflict.Middle-(height/2)))) + gui.centerYPos(gui.Views.Main, panelState.GetConflictMiddle()) + + return nil +} + +func (gui *Gui) centerYPos(view *gocui.View, y int) { + ox, _ := view.Origin() + _, height := view.Size() + newOriginY := int(math.Max(0, float64(y-(height/2)))) gui.g.Update(func(g *gocui.Gui) error { - return mergingView.SetOrigin(ox, newOriginY) + return view.SetOrigin(ox, newOriginY) }) - return nil } func (gui *Gui) getMergingOptions() map[string]string { @@ -276,7 +239,7 @@ func (gui *Gui) getMergingOptions() map[string]string { func (gui *Gui) handleEscapeMerge() error { gui.takeOverMergeConflictScrolling() - gui.State.Panels.Merging.EditHistory = stack.New() + gui.State.Panels.Merging.Reset() if err := gui.refreshSidePanels(refreshOptions{scope: []RefreshableView{FILES}}); err != nil { return err } @@ -343,8 +306,8 @@ func (gui *Gui) canScrollMergePanel() bool { } func (gui *Gui) withMergeConflictLock(f func() error) error { - gui.State.Panels.Merging.ConflictsMutex.Lock() - defer gui.State.Panels.Merging.ConflictsMutex.Unlock() + gui.State.Panels.Merging.Lock() + defer gui.State.Panels.Merging.Unlock() return f() } |