Skip to content
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

Towards rendering without colours #76

Merged
merged 28 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions lib/Block.ml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
type block_origin = Mine | Their | None

type 'a t =
| Common of 'a
| Changed of { mine : 'a list; their : 'a list; order : block_origin }
| Changed of { mine : 'a list; their : 'a list; order : Types.block_origin }

let rec first_change_order (hunk_lines : 'a Patch.line list) : block_origin =
let rec first_change_order (hunk_lines : 'a Patch.line list) :
Types.block_origin =
match hunk_lines with
| [] -> None
| `Common _ :: rest -> first_change_order rest
Expand Down Expand Up @@ -54,6 +53,6 @@ let to_hunk (blocks : 'a t list) : 'a Patch.line list =
| Changed { mine; their; order } ->
let mine_lines = List.map (fun x -> `Mine x) mine in
let their_lines = List.map (fun x -> `Their x) their in
if order = Mine then mine_lines @ their_lines
if order = Types.Mine then mine_lines @ their_lines
else their_lines @ mine_lines)
blocks
4 changes: 1 addition & 3 deletions lib/Block.mli
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
type block_origin = Mine | Their | None

type 'a t =
| Common of 'a
| Changed of { mine : 'a list; their : 'a list; order : block_origin }
| Changed of { mine : 'a list; their : 'a list; order : Types.block_origin }

val of_hunk : 'a Patch.line list -> 'a t list

Expand Down
91 changes: 66 additions & 25 deletions lib/HunkView.ml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ let split_and_align_hunk hunks : line list * line list =

(* Normal Mode *)

let ui_hunk_summary (hunk : string Patch.hunk) : Nottui.ui =
let ui_hunk_summary (hunk : string Patch.hunk)
(rendering_mode : Types.rendering_mode) : Nottui.ui =
let mine_info =
if hunk.Patch.mine_len = 0 then "0,0"
else Printf.sprintf "%d,%d" (hunk.Patch.mine_start + 1) hunk.Patch.mine_len
Expand All @@ -50,12 +51,22 @@ let ui_hunk_summary (hunk : string Patch.hunk) : Nottui.ui =
Printf.sprintf "%d,%d" (hunk.Patch.their_start + 1) hunk.Patch.their_len
in
let mine_summary =
W.string ~attr:Notty.A.(fg red) (Printf.sprintf "-%s" mine_info)
match rendering_mode with
| Types.Color ->
W.string ~attr:Notty.A.(fg red) (Printf.sprintf "-%s" mine_info)
| Types.TextMarkers -> W.string (Printf.sprintf "-%s" mine_info)
in
let their_summary =
W.string ~attr:Notty.A.(fg green) (Printf.sprintf "+%s" their_info)
match rendering_mode with
| Types.Color ->
W.string ~attr:Notty.A.(fg green) (Printf.sprintf "+%s" their_info)
| Types.TextMarkers -> W.string (Printf.sprintf "+%s" their_info)
in
let at_symbols =
match rendering_mode with
| Types.Color -> W.string ~attr:Notty.A.(fg lightblue) "@@"
| Types.TextMarkers -> W.string "@@"
in
let at_symbols = W.string ~attr:Notty.A.(fg lightblue) "@@" in
Ui.hcat
[
at_symbols;
Expand All @@ -67,8 +78,9 @@ let ui_hunk_summary (hunk : string Patch.hunk) : Nottui.ui =
at_symbols;
]

let ui_unified_diff (hunk : string Patch.hunk) : Nottui.ui =
let hunk_summary = ui_hunk_summary hunk in
let ui_unified_diff (hunk : string Patch.hunk)
(rendering_mode : Types.rendering_mode) : Nottui.ui =
let hunk_summary = ui_hunk_summary hunk rendering_mode in
let hunk_content =
let blocks = Block.of_hunk hunk.Patch.lines in
let single_line_changes =
Expand All @@ -82,33 +94,50 @@ let ui_unified_diff (hunk : string Patch.hunk) : Nottui.ui =
if single_line_changes then
let word_diff_blocks = List.map WordDiff.compute blocks in
let word_diff_lines = Block.to_hunk word_diff_blocks in
WordDiff.render_hunk_lines word_diff_lines
else WordDiff.render_hunk hunk
WordDiff.render_hunk_lines word_diff_lines rendering_mode
else WordDiff.render_hunk hunk rendering_mode
in
Ui.vcat [ hunk_summary; hunk_content ]

let current_hunks (z_patches : string Patch.t Zipper.t) : Nottui.ui =
(** Side by side diff view implementation **)
let current_hunks (z_patches : string Patch.t Zipper.t)
(render_mode : Types.rendering_mode) : Nottui.ui =
let p = Zipper.get_focus z_patches in
let hunks = List.map ui_unified_diff p.Patch.hunks in
let hunks =
List.map (fun hunk -> ui_unified_diff hunk render_mode) p.Patch.hunks
in
Ui.vcat hunks

(** Side by side diff view implementation **)

let lines_with_numbers (lines : line list) (attr_change : Notty.attr)
(prefix : string) : Nottui.ui list =
(prefix : string) (rendering_mode : Types.rendering_mode) : Nottui.ui list =
let rec process_lines line_num acc = function
| [] -> List.rev acc
| line :: rest ->
let content, attr, next_num =
match line with
| Common s ->
let content = Printf.sprintf "%3d %s" line_num s in
(content, Notty.A.empty, line_num + 1)
let content, attr =
match rendering_mode with
| Types.Color ->
( Printf.sprintf "%3d %s" line_num s,
Notty.A.(fg lightblue) )
| Types.TextMarkers ->
(Printf.sprintf "%3d %s" line_num s, Notty.A.empty)
in
(content, attr, line_num + 1)
| Change s ->
let content = Printf.sprintf "%3d %s %s" line_num prefix s in
let content =
match rendering_mode with
| Types.Color -> Printf.sprintf "%3d %s %s" line_num prefix s
| Types.TextMarkers ->
let open_tag, close_tag =
if prefix = "-" then ("<- ", " /->") else ("<+ ", " /+>")
in
Printf.sprintf "%3d %s%s%s" line_num open_tag s close_tag
in
(content, attr_change, line_num + 1)
| Empty ->
let content = Printf.sprintf " " in
let content = Printf.sprintf " " in
(content, Notty.A.empty, line_num)
in
let new_acc = W.string ~attr content :: acc in
Expand All @@ -124,14 +153,22 @@ let create_summary (start_line_num : int) (hunk_length : int)
(Printf.sprintf "@@ %s%d,%d @@" sign start_line_num hunk_length)
else W.string ~attr (Printf.sprintf "@@ %s0,0 @@" sign)

let ui_of_hunk_side_by_side (hunk : string Patch.hunk) : Nottui.ui =
let attr_mine = Notty.A.(fg red ++ st bold) in
let attr_their = Notty.A.(fg green ++ st bold) in
let ui_of_hunk_side_by_side (hunk : string Patch.hunk)
(rendering_mode : Types.rendering_mode) : Nottui.ui =
let attr_mine, attr_their =
match rendering_mode with
| Types.Color -> (Notty.A.(fg red ++ st bold), Notty.A.(fg green ++ st bold))
| Types.TextMarkers -> (Notty.A.empty, Notty.A.empty)
yokurang marked this conversation as resolved.
Show resolved Hide resolved
in

let mine_lines, their_lines = split_and_align_hunk hunk.Patch.lines in

let content_mine = lines_with_numbers mine_lines attr_mine "-" in
let content_their = lines_with_numbers their_lines attr_their "+" in
let content_mine =
lines_with_numbers mine_lines attr_mine "-" rendering_mode
in
let content_their =
lines_with_numbers their_lines attr_their "+" rendering_mode
in
let summary_mine =
create_summary
(hunk.Patch.mine_start + 1)
Expand All @@ -150,8 +187,12 @@ let ui_of_hunk_side_by_side (hunk : string Patch.hunk) : Nottui.ui =
Ui.resize ~w:0 ~sw:2 (Ui.vcat (summary_their :: content_their));
]

let current_hunks_side_by_side (z_patches : string Patch.t Zipper.t) : Nottui.ui
=
let current_hunks_side_by_side (z_patches : string Patch.t Zipper.t)
(render_mode : Types.rendering_mode) : Nottui.ui =
let p = Zipper.get_focus z_patches in
let hunks_ui = List.map ui_of_hunk_side_by_side p.Patch.hunks in
let hunks_ui =
List.map
(fun hunk -> ui_of_hunk_side_by_side hunk render_mode)
p.Patch.hunks
in
Ui.vcat hunks_ui
5 changes: 3 additions & 2 deletions lib/HunkView.mli
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
val current_hunks : string Patch.t Zipper.t -> Nottui.ui
val current_hunks : string Patch.t Zipper.t -> Types.rendering_mode -> Nottui.ui
(** [current_hunks zipper] returns the current hunks in a patch zipper for
normal view. *)

val current_hunks_side_by_side : string Patch.t Zipper.t -> Nottui.ui
val current_hunks_side_by_side :
string Patch.t Zipper.t -> Types.rendering_mode -> Nottui.ui
(** [current_hunks_side_by_side zipper] returns the current hunks in a patch
zipper for side-by-side view. *)
25 changes: 19 additions & 6 deletions lib/InteractiveViewer.ml
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,38 @@ open Lwd_infix
type view_mode = SideBySide | Normal

let view_mode : view_mode Lwd.var = Lwd.var Normal
let rendering_mode : Types.rendering_mode Lwd.var = Lwd.var Types.Color

let toggle_view_mode () : unit =
match Lwd.peek view_mode with
| Normal -> Lwd.set view_mode SideBySide
| SideBySide -> Lwd.set view_mode Normal

let toggle_rendering_mode () : unit =
match Lwd.peek rendering_mode with
| Color -> Lwd.set rendering_mode TextMarkers
| TextMarkers -> Lwd.set rendering_mode Color

let help_visible = Lwd.var false
let quit = Lwd.var false

let toggle_help_visibility () =
Lwd.set help_visible (not (Lwd.peek help_visible))

(* In InteractiveViewer.ml *)
let view (patches : string Patch.t list) =
let z_patches_var : string Patch.t 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 =
let$ mode = Lwd.get view_mode and$ z_patches = Lwd.get z_patches_var in
let$ mode = Lwd.get view_mode
and$ z_patches = Lwd.get z_patches_var
and$ render_mode = Lwd.get rendering_mode in
match mode with
| Normal -> HunkView.current_hunks z_patches
| SideBySide -> HunkView.current_hunks_side_by_side z_patches
| Normal -> HunkView.current_hunks z_patches render_mode
| SideBySide -> HunkView.current_hunks_side_by_side z_patches render_mode
in
let curr_scroll_state = Lwd.var W.default_scroll_state in
let change_scroll_state _action state =
Expand Down Expand Up @@ -69,12 +78,12 @@ let view (patches : string Patch.t list) =
`Handled
| `ASCII 'n', [] ->
Lwd.set z_patches_var
(PatchNavigation.navigate PatchNavigation.Next
(PatchNavigation.navigate Types.Next
(Lwd.peek z_patches_var));
`Handled
| `ASCII 'p', [] ->
Lwd.set z_patches_var
(PatchNavigation.navigate PatchNavigation.Prev
(PatchNavigation.navigate Types.Prev
(Lwd.peek z_patches_var));
`Handled
| `ASCII 'h', [] ->
Expand All @@ -83,11 +92,15 @@ let view (patches : string Patch.t list) =
| `ASCII 't', [] ->
toggle_view_mode ();
`Handled
| `ASCII 'r', [] ->
toggle_rendering_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. \
Press 't' to toggle view mode.");
Press 't' to toggle view mode. Press 'r' to toggle \
rendering mode.");
yokurang marked this conversation as resolved.
Show resolved Hide resolved
]
in
Lwd.return ui
Expand Down
8 changes: 2 additions & 6 deletions lib/PatchNavigation.ml
Original file line number Diff line number Diff line change
@@ -1,6 +1,2 @@
module W = Nottui_widgets

type direction = Prev | Next

let navigate (dir : direction) =
match dir with Prev -> Zipper.prev | Next -> Zipper.next
let navigate (dir : Types.navigation_direction) =
match dir with Types.Prev -> Zipper.prev | Types.Next -> Zipper.next
7 changes: 2 additions & 5 deletions lib/PatchNavigation.mli
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
type direction =
| Prev
| Next (** [direction] represents the direction of navigation. *)

val navigate : direction -> 'a Patch.t Zipper.t -> 'a Patch.t Zipper.t
val navigate :
Types.navigation_direction -> 'a Patch.t Zipper.t -> 'a Patch.t Zipper.t
(** [navigate direction zipper] returns the zipper that is the result of
navigating in the given direction. *)
5 changes: 5 additions & 0 deletions lib/Types.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type rendering_mode = Color | TextMarkers
type block_origin = Mine | Their | None
type navigation_direction = Prev | Next
type word = Unchanged of string | Changed of string
type line_content = word list
5 changes: 5 additions & 0 deletions lib/Types.mli
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
type rendering_mode = Color | TextMarkers
type block_origin = Mine | Their | None
yokurang marked this conversation as resolved.
Show resolved Hide resolved
type navigation_direction = Prev | Next
type word = Unchanged of string | Changed of string
type line_content = word list
Loading