diff options
Diffstat (limited to 'pkg/commands/patch/parse.go')
-rw-r--r-- | pkg/commands/patch/parse.go | 85 |
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 +} |