Skip to content

Commit a978092

Browse files
panglesdyokurang
andcommitted
Pair programming session
- Fixed bugs in the pairing of lines The LACS must consist of the _two_ subsequence - Finished rendering paired lines Co-authored-by: Alan Matthew <[email protected]>
1 parent c3a7479 commit a978092

File tree

4 files changed

+29
-33
lines changed

4 files changed

+29
-33
lines changed

lib/HunkView.ml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,9 @@ let ui_unified_diff (hunk : string Patch.hunk) (mode : rendering_mode) : Ui.t =
242242
let hunk_content =
243243
let blocks = Block.of_hunk hunk.Patch.lines in
244244
let word_diff_blocks = List.map WordDiff.compute blocks in
245-
let word_diff_lines = Block.to_hunk word_diff_blocks in
245+
let word_diff_lines =
246+
List.map Block.to_hunk word_diff_blocks |> List.concat
247+
in
246248
render_hunk_lines word_diff_lines mode
247249
in
248250
Ui.vcat [ hunk_summary; hunk_content ]

lib/WordDiff.ml

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,18 @@ let is_approximately_equal s1 s2 =
8181
let compare_char c1 c2 = c1 = c2 in
8282
let s1_array = Array.of_seq (String.to_seq s1) in
8383
let s2_array = Array.of_seq (String.to_seq s2) in
84-
let threshold = max 3 (max (String.length s1) (String.length s2) / 5) in
84+
let threshold = max 3 (max (String.length s1) (String.length s2) / 2) in
8585
edit_distance compare_char s1_array s2_array <= threshold
8686

8787
let lacs words1 words2 =
8888
let m = List.length words1 and n = List.length words2 in
8989
let dp = Array.make_matrix (m + 1) (n + 1) [] in
9090
for i = 1 to m do
9191
for j = 1 to n do
92-
if
93-
is_approximately_equal
94-
(List.nth words1 (i - 1))
95-
(List.nth words2 (j - 1))
96-
then dp.(i).(j) <- List.nth words1 (i - 1) :: dp.(i - 1).(j - 1)
92+
let c1 = List.nth words1 (i - 1) in
93+
let c2 = List.nth words2 (j - 1) in
94+
if is_approximately_equal c1 c2 then
95+
dp.(i).(j) <- (c1, c2) :: dp.(i - 1).(j - 1)
9796
else if List.length dp.(i - 1).(j) > List.length dp.(i).(j - 1) then
9897
dp.(i).(j) <- dp.(i - 1).(j)
9998
else dp.(i).(j) <- dp.(i).(j - 1)
@@ -116,48 +115,43 @@ let pair_lines (s1 : string array) (s2 : string array) :
116115
let rec construct_pairs w1 w2 lacs acc =
117116
match (w1, w2, lacs) with
118117
| [], [], [] -> List.rev acc
119-
| x :: xs, y :: ys, z :: zs -> (
120-
match (is_approximately_equal x z, is_approximately_equal y z) with
118+
| x :: xs, y :: ys, ((z1, z2) as z) :: zs -> (
119+
match (String.equal x z1, String.equal y z2) with
121120
| true, true -> construct_pairs xs ys zs ((Some x, Some y) :: acc)
122-
| false, true ->
121+
| false, _ ->
123122
construct_pairs xs (y :: ys) (z :: zs) ((Some x, None) :: acc)
124-
| true, false ->
125-
construct_pairs (x :: xs) ys (z :: zs) ((None, Some y) :: acc)
126-
| false, false ->
127-
construct_pairs xs ys (z :: zs) ((Some x, Some y) :: acc))
123+
| _, false ->
124+
construct_pairs (x :: xs) ys (z :: zs) ((None, Some y) :: acc))
128125
| x :: xs, [], lacs -> construct_pairs xs [] lacs ((Some x, None) :: acc)
129126
| [], y :: ys, lacs -> construct_pairs [] ys lacs ((None, Some y) :: acc)
130-
| x :: xs, y :: ys, [] -> construct_pairs xs ys [] ((Some x, Some y) :: acc)
127+
| x :: xs, ys, [] -> construct_pairs xs ys [] ((Some x, None) :: acc)
131128
| [], [], _ :: _ -> assert false
132129
(* Since lacs is the longest almost common subsequence, this case cannot happen *)
133130
in
134131

135132
construct_pairs words1 words2 common []
136133

137-
let compute (block : string Block.t) : line_content Block.t =
134+
let compute (block : string Block.t) : line_content Block.t list =
138135
match block with
139-
| Block.Common line -> Block.Common [ Unchanged line ]
136+
| Block.Common line -> [ Block.Common [ Unchanged line ] ]
140137
| Block.Changed { mine; their; order } ->
141138
let mine_array = Array.of_list mine in
142139
let their_array = Array.of_list their in
143140
let paired_lines = pair_lines mine_array their_array in
144141

145142
let diff_words line1 line2 =
146143
match (line1, line2) with
147-
| Some l1, Some l2 -> diff_words l1 l2
148-
| Some l, None | None, Some l ->
149-
let words = String.split_on_char ' ' l in
150-
(List.map (fun w -> Changed w) words, [])
151-
| None, None -> ([], [])
144+
| Some l1, Some l2 ->
145+
let l1, l2 = diff_words l1 l2 in
146+
Block.Changed { mine = [ l1 ]; their = [ l2 ]; order }
147+
| Some l1, None ->
148+
Block.Changed { mine = [ [ Changed l1 ] ]; their = []; order }
149+
| None, Some l2 ->
150+
Block.Changed { mine = []; their = [ [ Changed l2 ] ]; order }
151+
| None, None -> assert false
152152
in
153153

154-
let mine_content, their_content =
155-
List.fold_left
156-
(fun (mine_acc, their_acc) (m, t) ->
157-
let mine_diff, their_diff = diff_words m t in
158-
(mine_diff :: mine_acc, their_diff :: their_acc))
159-
([], []) paired_lines
160-
in
154+
List.map (fun (m, t) -> diff_words m t) paired_lines
161155

162-
Block.Changed
163-
{ mine = List.rev mine_content; their = List.rev their_content; order }
156+
(* Block.Changed *)
157+
(* { mine = List.rev mine_content; their = List.rev their_content; order } *)

lib/WordDiff.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
type word = Unchanged of string | Changed of string
22
type line_content = word list
33

4-
val compute : string Block.t -> line_content Block.t
4+
val compute : string Block.t -> line_content Block.t list
55

66
(* for tests *)
77
val lcs : 'a list -> 'a list -> 'a list

test/unit/TestWordDiff.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ let test_pair_lines_1 =
9696

9797
let test_pair_lines_2 =
9898
( [| "line1"; "line2"; "line3 old" |],
99-
[| "line1 new"; "line2"; "line3 updated" |],
99+
[| "line1 n"; "line2"; "line3 updated" |],
100100
[
101101
(Some "line1", Some "line1 new");
102102
(Some "line2", Some "line2");

0 commit comments

Comments
 (0)