diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2021-04-02 00:48:13 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2021-04-02 11:09:12 +1100 |
commit | eeeef9ca863e529f4442dd780a462a577ff251cc (patch) | |
tree | 5a289d25ef876954c4561d8b67fc8b662cfe7262 /pkg/gui/mergeconflicts | |
parent | cc9293b38698af48da0c18309fb22eb83b986ceb (diff) |
refactor
Diffstat (limited to 'pkg/gui/mergeconflicts')
-rw-r--r-- | pkg/gui/mergeconflicts/merge_conflicts.go | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/pkg/gui/mergeconflicts/merge_conflicts.go b/pkg/gui/mergeconflicts/merge_conflicts.go new file mode 100644 index 000000000..fe3bdfbe3 --- /dev/null +++ b/pkg/gui/mergeconflicts/merge_conflicts.go @@ -0,0 +1,86 @@ +package mergeconflicts + +import ( + "bytes" + "strings" + + "github.com/fatih/color" + "github.com/jesseduffield/lazygit/pkg/commands" + "github.com/jesseduffield/lazygit/pkg/theme" + "github.com/jesseduffield/lazygit/pkg/utils" +) + +type Selection int + +const ( + TOP Selection = iota + BOTTOM + BOTH +) + +func FindConflicts(content string) []commands.Conflict { + conflicts := make([]commands.Conflict, 0) + + if content == "" { + return conflicts + } + + var newConflict commands.Conflict + for i, line := range utils.SplitLines(content) { + trimmedLine := strings.TrimPrefix(line, "++") + switch trimmedLine { + case "<<<<<<< HEAD", "<<<<<<< MERGE_HEAD", "<<<<<<< Updated upstream", "<<<<<<< ours": + newConflict = commands.Conflict{Start: i} + case "=======": + newConflict.Middle = i + default: + if strings.HasPrefix(trimmedLine, ">>>>>>> ") { + newConflict.End = i + conflicts = append(conflicts, newConflict) + } + } + + } + return conflicts +} + +func ColoredConflictFile(content string, conflicts []commands.Conflict, conflictIndex int, conflictTop, hasFocus bool) string { + if len(conflicts) == 0 { + return content + } + conflict, remainingConflicts := shiftConflict(conflicts) + var outputBuffer bytes.Buffer + for i, line := range utils.SplitLines(content) { + colourAttr := theme.DefaultTextColor + if i == conflict.Start || i == conflict.Middle || i == conflict.End { + colourAttr = color.FgRed + } + colour := color.New(colourAttr) + if hasFocus && conflictIndex < len(conflicts) && conflicts[conflictIndex] == conflict && shouldHighlightLine(i, conflict, conflictTop) { + colour.Add(color.Bold) + colour.Add(theme.SelectedRangeBgColor) + } + if i == conflict.End && len(remainingConflicts) > 0 { + conflict, remainingConflicts = shiftConflict(remainingConflicts) + } + outputBuffer.WriteString(utils.ColoredStringDirect(line, colour) + "\n") + } + return outputBuffer.String() +} + +func IsIndexToDelete(i int, conflict commands.Conflict, selection Selection) bool { + return i == conflict.Middle || + i == conflict.Start || + i == conflict.End || + selection != BOTH && + (selection == BOTTOM && i > conflict.Start && i < conflict.Middle) || + (selection == TOP && i > conflict.Middle && i < conflict.End) +} + +func shiftConflict(conflicts []commands.Conflict) (commands.Conflict, []commands.Conflict) { + return conflicts[0], conflicts[1:] +} + +func shouldHighlightLine(index int, conflict commands.Conflict, top bool) bool { + return (index >= conflict.Start && index <= conflict.Middle && top) || (index >= conflict.Middle && index <= conflict.End && !top) +} |