1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
open! Core
open! Import
type t = string Patience_diff.Hunk.t list [@@deriving sexp_of]
let iter_sides ~f_hunk_break ~f_line (hunks : _ Patience_diff.Hunk.t list) =
List.iter hunks ~f:(fun hunk ->
f_hunk_break hunk;
let prev_line = ref hunk.prev_start in
let next_line = ref hunk.next_start in
let emit kind =
let side : Format.Annotation_gutter.side =
match kind with
| `Prev -> Prev { line = !prev_line }
| `Next -> Next { line = !next_line }
| `Same -> Same { prev = !prev_line; next = !next_line }
| `Unified -> Unified { prev = !prev_line; next = !next_line }
in
f_line side;
match kind with
| `Prev -> Int.incr prev_line
| `Next -> Int.incr next_line
| `Same | `Unified ->
Int.incr prev_line;
Int.incr next_line
in
List.iter hunk.ranges ~f:(function
| Same r -> Array.iter r ~f:(fun _ -> emit `Same)
| Prev (r, _) -> Array.iter r ~f:(fun _ -> emit `Prev)
| Next (r, _) -> Array.iter r ~f:(fun _ -> emit `Next)
| Unified (r, _) -> Array.iter r ~f:(fun _ -> emit `Unified)
| Replace (ar1, ar2, _) ->
Array.iter ar1 ~f:(fun _ -> emit `Prev);
Array.iter ar2 ~f:(fun _ -> emit `Next)))
;;
let iter_with_line_info ~f_hunk_break ~f_line (hunks : t) =
List.iter hunks ~f:(fun hunk ->
f_hunk_break hunk;
let prev_line = ref hunk.prev_start in
let next_line = ref hunk.next_start in
let emit kind text =
let side : Format.Annotation_gutter.side =
match kind with
| `Prev -> Prev { line = !prev_line }
| `Next -> Next { line = !next_line }
| `Same -> Same { prev = !prev_line; next = !next_line }
| `Unified -> Unified { prev = !prev_line; next = !next_line }
in
f_line side text;
match kind with
| `Prev -> Int.incr prev_line
| `Next -> Int.incr next_line
| `Same | `Unified ->
Int.incr prev_line;
Int.incr next_line
in
List.iter hunk.ranges ~f:(function
| Same r -> Array.iter r ~f:(fun (_annotation, text) -> emit `Same text)
| Prev (r, _) -> Array.iter r ~f:(emit `Prev)
| Next (r, _) -> Array.iter r ~f:(emit `Next)
| Unified (r, _) -> Array.iter r ~f:(emit `Unified)
| Replace (ar1, ar2, _) ->
Array.iter ar1 ~f:(emit `Prev);
Array.iter ar2 ~f:(emit `Next)))
;;
let iter' ~f_hunk_break ~f_line hunks =
iter_with_line_info ~f_hunk_break ~f_line:(fun _side line -> f_line line) hunks
;;