-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[yokurang]: Side-by-side diff view #32
Changes from all commits
d3c82af
577f92d
0905590
74b46b1
f44310a
c5e2898
95a8882
2cfbf01
d80fb25
abc0236
6cd4a6d
84fd92a
a61793a
ba026a6
a02222c
5d7682d
0f7a3de
fb70338
9051a34
d8feae8
c2d492e
43bffe6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,14 +47,7 @@ let ui_of_operation operation = | |
Ui.hcat | ||
[ W.string "Modification of "; W.string ~attr:blue_bold_attr path ] | ||
|
||
let ui_of_hunk hunk = | ||
let line_to_string line = | ||
match line with | ||
| `Their text -> W.string ~attr:Notty.A.(fg red) text | ||
| `Mine text -> W.string ~attr:Notty.A.(fg green) text | ||
| `Common text -> W.string text | ||
in | ||
Ui.vcat @@ List.map line_to_string hunk.Patch.lines | ||
let string_of_hunk = Format.asprintf "%a" Patch.pp_hunk | ||
|
||
let current_operation z_patches : ui Lwd.t = | ||
let$ z = Lwd.get z_patches in | ||
|
@@ -64,8 +57,8 @@ let current_operation z_patches : ui Lwd.t = | |
let current_hunks z_patches : ui Lwd.t = | ||
let$ z = Lwd.get z_patches in | ||
let p = Zipper.get_focus z in | ||
let hunks = List.map ui_of_hunk p.Patch.hunks in | ||
Ui.vcat hunks | ||
let hunks = List.map (fun h -> W.string (string_of_hunk h)) p.Patch.hunks in | ||
Ui.vcat @@ hunks | ||
|
||
type direction = Prev | Next | ||
|
||
|
@@ -111,6 +104,65 @@ let change_summary z_patches : ui Lwd.t = | |
in | ||
W.string ~attr:Notty.A.(fg lightcyan) operation_count | ||
|
||
(** Side by side diff view implementation **) | ||
|
||
type view_mode = SideBySide | Normal | ||
|
||
let view_mode = Lwd.var Normal | ||
|
||
let toggle_view_mode () = | ||
match Lwd.peek view_mode with | ||
| Normal -> Lwd.set view_mode SideBySide | ||
| SideBySide -> Lwd.set view_mode Normal | ||
|
||
let rec split_and_align_hunk hunks mine_acc their_acc = | ||
yokurang marked this conversation as resolved.
Show resolved
Hide resolved
|
||
match hunks with | ||
| [] -> (List.rev mine_acc, List.rev their_acc) | ||
| (`Common _ as common) :: t -> | ||
split_and_align_hunk t (common :: mine_acc) (common :: their_acc) | ||
| `Mine s :: `Their s' :: t -> | ||
split_and_align_hunk t (`Mine s :: mine_acc) (`Their s' :: their_acc) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This pairs only one added line with one removed line. This might not be the output we expect, for example:
This diff renders like this in side-by-side:
It would be more intuitive if the whole block of removed line was paired with the added line. |
||
| `Mine s :: t -> | ||
split_and_align_hunk t (`Mine s :: mine_acc) (`Common "" :: their_acc) | ||
| `Their s :: t -> | ||
split_and_align_hunk t (`Common "" :: mine_acc) (`Their s :: their_acc) | ||
|
||
let lines_to_ui lines attr_change = | ||
List.map | ||
(fun line -> | ||
let content, attr = | ||
match line with | ||
| `Common s -> (s, Notty.A.empty) | ||
| `Mine s -> (s, attr_change) | ||
| `Their s -> (s, attr_change) | ||
in | ||
W.string ~attr content) | ||
lines | ||
|
||
let ui_of_hunk_side_by_side hunk = | ||
let mine_lines, their_lines = split_and_align_hunk hunk.Patch.lines [] [] in | ||
|
||
let attr_mine = Notty.A.(fg red ++ st bold) in | ||
let attr_their = Notty.A.(fg green ++ st bold) in | ||
|
||
let mine_ui = lines_to_ui mine_lines attr_mine in | ||
let their_ui = lines_to_ui their_lines attr_their in | ||
let space = Ui.space 1 0 in | ||
Ui.hcat | ||
[ | ||
Ui.resize ~w:0 ~sw:2 (Ui.vcat mine_ui); | ||
space; | ||
Ui.resize ~w:0 ~sw:2 (Ui.vcat their_ui); | ||
] | ||
|
||
let current_hunks_side_by_side z_patches : ui Lwd.t = | ||
let$ z = Lwd.get z_patches in | ||
let p = Zipper.get_focus z in | ||
let hunks_ui = List.map (fun h -> ui_of_hunk_side_by_side h) p.Patch.hunks in | ||
Ui.vcat @@ hunks_ui | ||
|
||
(** end of side by side diff view implementation **) | ||
|
||
let view (patches : Patch.t list) = | ||
let help_panel = | ||
Ui.vcat | ||
|
@@ -120,14 +172,21 @@ let view (patches : Patch.t list) = | |
W.string "q: Quit the diffcessible viewer"; | ||
W.string "n: Move to the next operation, if present"; | ||
W.string "p: Move to the previous operation, if present"; | ||
W.string "g: Scroll back to the top of the displayed operation."; | ||
W.string "t: Toggle view mode"; | ||
W.string "l: Toggle line numbers"; | ||
] | ||
in | ||
let z_patches : 'a Zipper.t Lwd.var = | ||
match Zipper.zipper_of_list patches with | ||
| Some z -> Lwd.var z | ||
| None -> failwith "zipper_of_list: empty list" | ||
in | ||
let hunks_ui = | ||
Lwd.bind (Lwd.get view_mode) ~f:(fun mode -> | ||
match mode with | ||
| Normal -> current_hunks z_patches | ||
| SideBySide -> current_hunks_side_by_side z_patches) | ||
in | ||
let curr_scroll_state = Lwd.var W.default_scroll_state in | ||
let change_scroll_state _action state = | ||
let off_screen = state.W.position > state.W.bound in | ||
|
@@ -158,8 +217,7 @@ let view (patches : Patch.t list) = | |
current_operation z_patches; | ||
W.vscroll_area | ||
~state:(Lwd.get curr_scroll_state) | ||
~change:change_scroll_state | ||
@@ current_hunks z_patches; | ||
~change:change_scroll_state hunks_ui; | ||
Lwd.pure | ||
@@ Ui.keyboard_area | ||
(function | ||
|
@@ -175,14 +233,14 @@ let view (patches : Patch.t list) = | |
| `ASCII 'h', [] -> | ||
Lwd.set help true; | ||
`Handled | ||
| `ASCII 'g', [] -> | ||
Lwd.set curr_scroll_state | ||
{ (Lwd.peek curr_scroll_state) with W.position = 0 }; | ||
| `ASCII 't', [] -> | ||
toggle_view_mode (); | ||
`Handled | ||
| _ -> `Unhandled) | ||
(W.string | ||
"Type 'h' to go to the help panel, 'q' to quit, 'n' to go to \ | ||
the next operation, 'p' to go to the previous operation"); | ||
the next operation, 'p' to go to the previous operation. \ | ||
Press 't' to toggle view mode."); | ||
] | ||
in | ||
W.vbox [ ui ] | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This diff is an artifact of being based off #57, which has been reverted since. Could you rebase or
merge main
?