summaryrefslogtreecommitdiffstats
path: root/pkg/commands/patch/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/commands/patch/parse.go')
-rw-r--r--pkg/commands/patch/parse.go85
1 files changed, 85 insertions, 0 deletions
diff --git a/pkg/commands/patch/parse.go b/pkg/commands/patch/parse.go
new file mode 100644
index 000000000..fee7d2918
--- /dev/null
+++ b/pkg/commands/patch/parse.go
@@ -0,0 +1,85 @@
+package patch
+
+import (
+ "regexp"
+ "strings"
+
+ "github.com/jesseduffield/lazygit/pkg/utils"
+)
+
+var hunkHeaderRegexp = regexp.MustCompile(`(?m)^@@ -(\d+)[^\+]+\+(\d+)[^@]+@@(.*)$`)
+
+func Parse(patchStr string) *Patch {
+ // ignore trailing newline.
+ lines := strings.Split(strings.TrimSuffix(patchStr, "\n"), "\n")
+
+ hunks := []*Hunk{}
+ patchHeader := []string{}
+
+ var currentHunk *Hunk
+ for _, line := range lines {
+ if strings.HasPrefix(line, "@@") {
+ oldStart, newStart, headerContext := headerInfo(line)
+
+ currentHunk = &Hunk{
+ oldStart: oldStart,
+ newStart: newStart,
+ headerContext: headerContext,
+ bodyLines: []*PatchLine{},
+ }
+ hunks = append(hunks, currentHunk)
+ } else if currentHunk != nil {
+ currentHunk.bodyLines = append(currentHunk.bodyLines, newHunkLine(line))
+ } else {
+ patchHeader = append(patchHeader, line)
+ }
+ }
+
+ return &Patch{
+ hunks: hunks,
+ header: patchHeader,
+ }
+}
+
+func headerInfo(header string) (int, int, string) {
+ match := hunkHeaderRegexp.FindStringSubmatch(header)
+
+ oldStart := utils.MustConvertToInt(match[1])
+ newStart := utils.MustConvertToInt(match[2])
+ headerContext := match[3]
+
+ return oldStart, newStart, headerContext
+}
+
+func newHunkLine(line string) *PatchLine {
+ if line == "" {
+ return &PatchLine{
+ Kind: CONTEXT,
+ Content: "",
+ }
+ }
+
+ firstChar := line[:1]
+
+ kind := parseFirstChar(firstChar)
+
+ return &PatchLine{
+ Kind: kind,
+ Content: line,
+ }
+}
+
+func parseFirstChar(firstChar string) PatchLineKind {
+ switch firstChar {
+ case " ":
+ return CONTEXT
+ case "+":
+ return ADDITION
+ case "-":
+ return DELETION
+ case "\\":
+ return NEWLINE_MESSAGE
+ }
+
+ return CONTEXT
+}