Skip to content

Commit

Permalink
progress on visual. still some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
yokurang committed Aug 14, 2024
1 parent 8e9edec commit 1240b8c
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 21 deletions.
16 changes: 3 additions & 13 deletions lib/HunkView.ml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,8 @@ open Nottui
module W = Nottui_widgets

(* Constants and Formatting Functions *)
let added_marker (content : Ui.t) : Ui.t =
Ui.hcat [ W.string "+" ~attr:Notty.A.(fg green); content ]

let removed_marker (content : Ui.t) : Ui.t =
Ui.hcat [ W.string "-" ~attr:Notty.A.(fg red); content ]

let added_marker (content : Ui.t) : Ui.t = Ui.hcat [ W.string "+"; content ]
let removed_marker (content : Ui.t) : Ui.t = Ui.hcat [ W.string "-"; content ]
let unchanged_marker (content : Ui.t) : Ui.t = Ui.hcat [ W.string " "; content ]

(* Types *)
Expand Down Expand Up @@ -117,13 +113,7 @@ let render_diff_line (mine_num : int) (their_num : int)
(content : WordDiff.word list) (mode : rendering_mode) : Ui.t =
let line_number = render_line_number mine_num their_num diff_type in
let content_ui = render_word_diff content diff_type mode in
let marker =
match diff_type with
| `Added -> added_marker
| `Removed -> removed_marker
| `Unchanged -> unchanged_marker
in
Ui.hcat [ line_number; marker content_ui ]
Ui.hcat [ line_number; content_ui ]

let render_hunk_lines (hunk_lines : WordDiff.line_content Patch.line list)
(mode : rendering_mode) : Ui.t =
Expand Down
58 changes: 50 additions & 8 deletions lib/WordDiff.ml
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
type word = Unchanged of string | Changed of string
type line_content = word list

let string_to_words s = Array.of_list (String.split_on_char ' ' s)
let string_arr_to_words s = Array.of_list (String.split_on_char ' ' s)

let string_to_words s =
s |> String.trim |> String.split_on_char ' ' |> List.filter (fun s -> s <> "")

let longest xs ys = if List.length xs > List.length ys then xs else ys

let lcs xs' ys' =
Expand Down Expand Up @@ -44,8 +48,8 @@ let edit_distance (type a) (compare : a -> a -> bool) (s : a array)
edit_distance_helper (Array.length s) (Array.length t)

let diff_words (s1 : string) (s2 : string) : line_content * line_content =
let words1 = Array.to_list (string_to_words s1) in
let words2 = Array.to_list (string_to_words s2) in
let words1 = Array.to_list (string_arr_to_words s1) in
let words2 = Array.to_list (string_arr_to_words s2) in
let common = lcs words1 words2 in

let rec construct_diff w1 w2 lcs acc_mine acc_their =
Expand Down Expand Up @@ -77,11 +81,49 @@ let diff_words (s1 : string) (s2 : string) : line_content * line_content =

construct_diff words1 words2 common [] []

let string_similarity s1 s2 =
let a1 = string_to_words s1 |> Array.of_list in
let a2 = string_to_words s2 |> Array.of_list in
let distance = edit_distance (=) a1 a2 in
let max_length = max (Array.length a1) (Array.length a2) in
1.0 -. (float_of_int distance /. float_of_int max_length)

let pair_lines mine their =
let similarity_threshold = 0.5 in
let rec pair acc mine their =
match mine, their with
| [], [] -> List.rev acc
| [], t::ts -> pair ((("", t) :: acc)) [] ts
| m::ms, [] -> pair (((m, "") :: acc)) ms []
| m::ms, t::ts ->
let similarity = string_similarity m t in
if similarity > similarity_threshold then
pair ((m, t) :: acc) ms ts
else
let (best_m, best_t) =
List.fold_left (fun (bm, bt) cur_t ->
let sim = string_similarity m cur_t in
if sim > similarity_threshold then (Some m, Some cur_t) else (bm, bt)
) (None, None) their
in
match best_m, best_t with
| Some bm, Some bt ->
pair ((bm, bt) :: acc) ms (List.filter ((<>) bt) their)
| _ -> pair ((m, "") :: acc) ms their
in
pair [] mine their

let compute (block : string Block.t) : line_content Block.t =
match block with
| Block.Common line -> Block.Common [ Unchanged line ]
| Block.Common line -> Block.Common [Unchanged line]
| Block.Changed { mine; their; order } ->
let mine_str = String.concat " " mine in
let their_str = String.concat " " their in
let mine_words, their_words = diff_words mine_str their_str in
Block.Changed { mine = [ mine_words ]; their = [ their_words ]; order }
let paired_lines = pair_lines mine their in
let mine_content, their_content =
List.split (List.map (fun (m, t) ->
let m_words, t_words = diff_words m t in
(m_words, t_words)
) paired_lines)
in
let mine_content = List.filter (fun l -> l <> []) mine_content in
let their_content = List.filter (fun l -> l <> []) their_content in
Block.Changed { mine = mine_content; their = their_content; order }

0 comments on commit 1240b8c

Please sign in to comment.