7 "github.com/sergi/go-diff/diffmatchpatch"
16 func (v *Variant) String() string {
18 case len(v.New) == 0 && len(v.Ref) == 0:
19 return fmt.Sprintf("%d=", v.Position)
20 case len(v.New) == 0 && len(v.Ref) == 1:
21 return fmt.Sprintf("%ddel", v.Position)
23 return fmt.Sprintf("%d_%ddel", v.Position, v.Position+len(v.Ref)-1)
24 case len(v.Ref) == 1 && len(v.New) == 1:
25 return fmt.Sprintf("%d%s>%s", v.Position, v.Ref, v.New)
27 return fmt.Sprintf("%d_%dins%s", v.Position-1, v.Position, v.New)
28 case len(v.Ref) == 1 && len(v.New) > 0:
29 return fmt.Sprintf("%ddelins%s", v.Position, v.New)
31 return fmt.Sprintf("%d_%ddelins%s", v.Position, v.Position+len(v.Ref)-1, v.New)
35 func Diff(a, b string, timeout time.Duration) ([]Variant, bool) {
36 dmp := diffmatchpatch.New()
37 var deadline time.Time
39 deadline = time.Now().Add(timeout)
41 diffs := dmp.DiffBisect(a, b, deadline)
43 if timeout > 0 && time.Now().After(deadline) {
46 diffs = cleanup(dmp.DiffCleanupEfficiency(diffs))
48 var variants []Variant
49 for i := 0; i < len(diffs); i++ {
50 switch diffs[i].Type {
51 case diffmatchpatch.DiffEqual:
52 pos += len(diffs[i].Text)
53 case diffmatchpatch.DiffDelete:
54 if i+1 < len(diffs) && diffs[i+1].Type == diffmatchpatch.DiffInsert {
55 // deletion followed by insertion
56 variants = append(variants, Variant{Position: pos, Ref: diffs[i].Text, New: diffs[i+1].Text})
57 pos += len(diffs[i].Text)
60 variants = append(variants, Variant{Position: pos, Ref: diffs[i].Text})
61 pos += len(diffs[i].Text)
63 case diffmatchpatch.DiffInsert:
64 if i+1 < len(diffs) && diffs[i+1].Type == diffmatchpatch.DiffDelete {
65 // insertion followed by deletion
66 variants = append(variants, Variant{Position: pos, Ref: diffs[i+1].Text, New: diffs[i].Text})
67 pos += len(diffs[i+1].Text)
70 variants = append(variants, Variant{Position: pos, New: diffs[i].Text})
74 return variants, timedOut
77 func cleanup(in []diffmatchpatch.Diff) (out []diffmatchpatch.Diff) {
78 for i := 0; i < len(in); i++ {
80 for i < len(in)-1 && in[i].Type == in[i+1].Type {
81 d.Text += in[i+1].Text