109 lines
2.8 KiB
Go
109 lines
2.8 KiB
Go
// Package patience implements the Patience Diff algorithm.
|
|
package patience
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// typeSymbol returns the associated symbol of a DiffType.
|
|
func typeSymbol(t DiffType) string {
|
|
switch t {
|
|
case Equal:
|
|
return " "
|
|
case Insert:
|
|
return "+"
|
|
case Delete:
|
|
return "-"
|
|
default:
|
|
panic("unknown DiffType")
|
|
}
|
|
}
|
|
|
|
// DiffText returns the source and destination texts (all equalities, insertions and deletions).
|
|
func DiffText(diffs []DiffLine) string {
|
|
s := make([]string, len(diffs))
|
|
for i, l := range diffs {
|
|
if len(l.Text) == 0 && l.Type == Equal {
|
|
continue
|
|
}
|
|
s[i] = fmt.Sprintf("%s%s", typeSymbol(l.Type), l.Text)
|
|
}
|
|
return strings.Join(s, "\n")
|
|
}
|
|
|
|
// DiffTextA returns the source text (all equalities and deletions).
|
|
func DiffTextA(diffs []DiffLine) string {
|
|
s := []string{}
|
|
for _, l := range diffs {
|
|
if l.Type == Insert {
|
|
continue
|
|
}
|
|
if l.Type == Equal && len(l.Text) == 0 {
|
|
s = append(s, "")
|
|
} else {
|
|
s = append(s, fmt.Sprintf("%s%s", typeSymbol(l.Type), l.Text))
|
|
}
|
|
}
|
|
return strings.Join(s, "\n")
|
|
}
|
|
|
|
// DiffTextB returns the destination text (all equalities and insertions).
|
|
func DiffTextB(diffs []DiffLine) string {
|
|
s := []string{}
|
|
for _, l := range diffs {
|
|
if l.Type == Delete {
|
|
continue
|
|
}
|
|
if l.Type == Equal && len(l.Text) == 0 {
|
|
s = append(s, "")
|
|
} else {
|
|
s = append(s, fmt.Sprintf("%s%s", typeSymbol(l.Type), l.Text))
|
|
}
|
|
}
|
|
return strings.Join(s, "\n")
|
|
}
|
|
|
|
// UnifiedDiffOptions represents the options for UnifiedDiffTextWithOptions.
|
|
type UnifiedDiffOptions struct {
|
|
// Precontext is the number of lines of context before each change in a hunk.
|
|
Precontext int
|
|
// Postcontext is the number of lines of context after each change in a hunk.
|
|
Postcontext int
|
|
// SrcHeader is the header for the source file.
|
|
SrcHeader string
|
|
// DstHeader is the header for the destination file.
|
|
DstHeader string
|
|
}
|
|
|
|
// UnifiedDiffTextWithOptions returns the diff text in unidiff format.
|
|
func UnifiedDiffTextWithOptions(diffs []DiffLine, opts UnifiedDiffOptions) string {
|
|
hunks := makeHunks(diffs, opts.Precontext, opts.Postcontext)
|
|
s := []string{}
|
|
if len(opts.SrcHeader) > 0 {
|
|
s = append(s, fmt.Sprintf("--- %s", opts.SrcHeader))
|
|
}
|
|
if len(opts.DstHeader) > 0 {
|
|
s = append(s, fmt.Sprintf("+++ %s", opts.DstHeader))
|
|
}
|
|
for _, h := range hunks {
|
|
s = append(s, fmt.Sprintf("@@ -%d,%d +%d,%d @@", h.SrcStart, h.SrcLines, h.DstStart, h.DstLines))
|
|
for _, l := range h.Diffs {
|
|
if l.Type == Equal && len(l.Text) == 0 {
|
|
s = append(s, "")
|
|
} else {
|
|
s = append(s, fmt.Sprintf("%s%s", typeSymbol(l.Type), l.Text))
|
|
}
|
|
}
|
|
}
|
|
return strings.Join(s, "\n")
|
|
}
|
|
|
|
// UnifiedDiffText returns the diff text in unidiff format with a context of 3 lines.
|
|
func UnifiedDiffText(diffs []DiffLine) string {
|
|
return UnifiedDiffTextWithOptions(
|
|
diffs,
|
|
UnifiedDiffOptions{Precontext: 3, Postcontext: 3},
|
|
)
|
|
}
|