1
0
mirror of https://github.com/jesseduffield/lazygit.git synced 2024-12-14 11:23:09 +02:00
lazygit/pkg/gui/mergeconflicts/state.go

156 lines
3.1 KiB
Go
Raw Normal View History

2021-04-18 10:07:10 +02:00
package mergeconflicts
import (
"sync"
"github.com/golang-collections/collections/stack"
"github.com/jesseduffield/lazygit/pkg/utils"
)
type State struct {
sync.Mutex
2021-08-25 12:43:57 +02:00
conflicts []*mergeConflict
// this is the index of the above `conflicts` field which is currently selected
conflictIndex int
// this is the index of the selected conflict's available selections slice e.g. [TOP, MIDDLE, BOTTOM]
// We use this to know which hunk of the conflict is selected.
2021-08-23 15:14:59 +02:00
selectionIndex int
2021-08-25 12:43:57 +02:00
// this allows us to undo actions
EditHistory *stack.Stack
2021-04-18 10:07:10 +02:00
}
func NewState() *State {
return &State{
2021-08-23 15:14:59 +02:00
Mutex: sync.Mutex{},
conflictIndex: 0,
selectionIndex: 0,
conflicts: []*mergeConflict{},
EditHistory: stack.New(),
2021-04-18 10:07:10 +02:00
}
}
2021-08-23 15:14:59 +02:00
func (s *State) setConflictIndex(index int) {
if len(s.conflicts) == 0 {
s.conflictIndex = 0
2021-08-25 12:43:57 +02:00
} else {
s.conflictIndex = clamp(index, 0, len(s.conflicts)-1)
}
2021-08-23 15:14:59 +02:00
s.setSelectionIndex(s.selectionIndex)
2021-04-18 10:07:10 +02:00
}
2021-08-23 15:14:59 +02:00
func (s *State) setSelectionIndex(index int) {
if selections := s.availableSelections(); len(selections) != 0 {
s.selectionIndex = clamp(index, 0, len(selections)-1)
}
2021-04-18 10:07:10 +02:00
}
2021-08-23 15:14:59 +02:00
func (s *State) SelectNextConflictHunk() {
s.setSelectionIndex(s.selectionIndex + 1)
}
func (s *State) SelectPrevConflictHunk() {
s.setSelectionIndex(s.selectionIndex - 1)
}
2021-04-18 10:07:10 +02:00
func (s *State) SelectNextConflict() {
2021-08-23 15:14:59 +02:00
s.setConflictIndex(s.conflictIndex + 1)
2021-04-18 10:07:10 +02:00
}
func (s *State) SelectPrevConflict() {
2021-08-23 15:14:59 +02:00
s.setConflictIndex(s.conflictIndex - 1)
2021-04-18 10:07:10 +02:00
}
func (s *State) PushFileSnapshot(content string) {
s.EditHistory.Push(content)
}
func (s *State) PopFileSnapshot() (string, bool) {
if s.EditHistory.Len() == 0 {
return "", false
}
return s.EditHistory.Pop().(string), true
}
func (s *State) currentConflict() *mergeConflict {
if len(s.conflicts) == 0 {
return nil
}
return s.conflicts[s.conflictIndex]
}
func (s *State) SetConflictsFromCat(cat string) {
s.setConflicts(findConflicts(cat))
}
func (s *State) setConflicts(conflicts []*mergeConflict) {
s.conflicts = conflicts
2021-08-23 15:14:59 +02:00
s.setConflictIndex(s.conflictIndex)
2021-04-18 10:07:10 +02:00
}
func (s *State) NoConflicts() bool {
return len(s.conflicts) == 0
}
func (s *State) Selection() Selection {
2021-08-23 15:14:59 +02:00
if selections := s.availableSelections(); len(selections) > 0 {
return selections[s.selectionIndex]
}
return TOP
}
func (s *State) availableSelections() []Selection {
if conflict := s.currentConflict(); conflict != nil {
2021-08-25 12:43:57 +02:00
return availableSelections(conflict)
2021-08-23 15:14:59 +02:00
}
return nil
2021-04-18 10:07:10 +02:00
}
func (s *State) IsFinalConflict() bool {
return len(s.conflicts) == 1
}
func (s *State) Reset() {
s.EditHistory = stack.New()
}
func (s *State) GetConflictMiddle() int {
return s.currentConflict().target
2021-04-18 10:07:10 +02:00
}
2021-08-25 12:43:57 +02:00
func (s *State) ContentAfterConflictResolve(
path string,
selection Selection,
) (bool, string, error) {
2021-04-18 10:07:10 +02:00
conflict := s.currentConflict()
if conflict == nil {
return false, "", nil
}
content := ""
2021-05-30 07:22:04 +02:00
err := utils.ForEachLineInFile(path, func(line string, i int) {
2021-08-25 12:43:57 +02:00
if selection.isIndexToKeep(conflict, i) {
2021-04-18 10:07:10 +02:00
content += line
}
2021-05-30 07:22:04 +02:00
})
if err != nil {
return false, "", err
2021-04-18 10:07:10 +02:00
}
return true, content, nil
}
2021-08-25 12:43:57 +02:00
func clamp(x int, min int, max int) int {
if x < min {
return min
} else if x > max {
return max
}
2021-08-25 12:43:57 +02:00
return x
2021-04-18 10:07:10 +02:00
}