1package diffview
2
3import (
4 "slices"
5
6 "github.com/aymanbagabas/go-udiff"
7 "github.com/charmbracelet/x/exp/slice"
8)
9
10type splitHunk struct {
11 fromLine int
12 toLine int
13 lines []*splitLine
14}
15
16type splitLine struct {
17 before *udiff.Line
18 after *udiff.Line
19}
20
21func hunkToSplit(h *udiff.Hunk) (sh splitHunk) {
22 lines := slices.Clone(h.Lines)
23 sh = splitHunk{
24 fromLine: h.FromLine,
25 toLine: h.ToLine,
26 lines: make([]*splitLine, 0, len(lines)),
27 }
28
29 for {
30 var ul udiff.Line
31 var ok bool
32 ul, lines, ok = slice.Shift(lines)
33 if !ok {
34 break
35 }
36
37 var sl splitLine
38
39 switch ul.Kind {
40
41 // For equal lines, add as is
42 case udiff.Equal:
43 sl.before = &ul
44 sl.after = &ul
45
46 // For inserted lines, set after and keep before as nil
47 case udiff.Insert:
48 sl.before = nil
49 sl.after = &ul
50
51 // For deleted lines, set before and loop over the next lines
52 // searching for the equivalent after line.
53 case udiff.Delete:
54 sl.before = &ul
55
56 inner:
57 for i, l := range lines {
58 switch l.Kind {
59 case udiff.Insert:
60 var ll udiff.Line
61 ll, lines, _ = slice.DeleteAt(lines, i)
62 sl.after = &ll
63 break inner
64 case udiff.Equal:
65 break inner
66 }
67 }
68 }
69
70 sh.lines = append(sh.lines, &sl)
71 }
72
73 return
74}