split.go 1.2 KB

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