Make horizontal_fill take character filler

This commit is contained in:
Dmitrii Kovanikov 2024-06-22 12:20:30 +01:00
parent 8551b60cbe
commit 15302724c0
5 changed files with 28 additions and 16 deletions

View File

@ -7,10 +7,10 @@ type chunk = {
let fmt_chunk { styles; string } = ANSITerminal.sprintf styles "%s" string
let padding_chunk width =
let replicate_chunk width c =
if width <= 0 then { styles = []; string = "" }
else
let padding = String.make width ' ' in
let padding = String.make width c in
{ styles = []; string = padding }
type t = {

View File

@ -7,8 +7,8 @@ type chunk = {
string : string;
}
(** [padding_chunk n] created a [chunk] without formatting of [n] spaces. *)
val padding_chunk : int -> chunk
(** [replicate_chunk n c] creates a [chunk] without formatting of [n] repeated characters [c]. *)
val replicate_chunk : int -> char -> chunk
(** A type defining a single line of text with different parts ("chunks") having
potentially different formatting. *)

View File

@ -1,6 +1,6 @@
type doc =
| Str of Line.styles * string
| Horizontal_fill
| Horizontal_fill of char
| Vertical of doc list
| Horizontal of doc list
@ -8,7 +8,7 @@ let str string = Str ([], string)
let fmt styles string = Str (styles, string)
let horizontal cols = Horizontal cols
let vertical rows = Vertical rows
let horizontal_fill = Horizontal_fill
let horizontal_fill filler = Horizontal_fill filler
let zip_lines (l : Line.t list) (r : Line.t list) =
let max_len_l = List.map Line.length l |> List.fold_left max 0 in
@ -19,7 +19,7 @@ let zip_lines (l : Line.t list) (r : Line.t list) =
| [], r ->
(* Optimisation: Add extra chunk only if padding is needed *)
if max_len_l > 0 then
let padding_chunk = Line.padding_chunk max_len_l in
let padding_chunk = Line.replicate_chunk max_len_l ' ' in
List.map (Line.prepend_chunk padding_chunk) r
else r
| hd_l :: tl_l, hd_r :: tl_r ->
@ -30,7 +30,7 @@ let zip_lines (l : Line.t list) (r : Line.t list) =
let new_line = Line.append hd_l hd_r in
new_line :: zip tl_l tl_r
else
let padding_chunk = Line.padding_chunk (max_len_l - left_len) in
let padding_chunk = Line.replicate_chunk (max_len_l - left_len) ' ' in
let new_line =
Line.append hd_l
(Line.append (Line.of_chunks [ padding_chunk ]) hd_r)
@ -47,11 +47,12 @@ type prerender_pass_info = {
type prerender =
| Rendered of Line.t list
| Fill
| Fill of char
let rec render_to_lines ~width = function
| Str (styles, string) -> [ Line.of_chunks [ { styles; string } ] ]
| Horizontal_fill -> [ Line.of_chunks [ Line.padding_chunk width ] ]
| Horizontal_fill filler ->
[ Line.of_chunks [ Line.replicate_chunk width filler ] ]
| Vertical rows -> List.concat_map (render_to_lines ~width) rows
| Horizontal cols -> horizontal_to_lines ~width cols
@ -63,8 +64,9 @@ and horizontal_to_lines ~width cols =
(fun (pass_info, prerendered) col ->
let new_pass_info, new_prerendered =
match col with
| Horizontal_fill ->
({ has_fill = true; size_taken = pass_info.size_taken }, Fill)
| Horizontal_fill filler ->
( { has_fill = true; size_taken = pass_info.size_taken },
Fill filler )
| other ->
(* WARNING: This will pass the total width to the left-most Horizontal_fill *)
let rendered = render_to_lines ~width other in
@ -90,10 +92,14 @@ and horizontal_to_lines ~width cols =
(fun (remaining_width, rendered) prerendered ->
match prerendered with
| Rendered lines -> (remaining_width, rendered @ [ lines ])
| Fill ->
| Fill filler ->
( 0,
rendered
@ [ [ Line.(of_chunks [ padding_chunk remaining_width ]) ] ] ))
@ [
[
Line.(of_chunks [ replicate_chunk remaining_width filler ]);
];
] ))
(fill_width, []) prerendered
in

View File

@ -18,7 +18,7 @@ val vertical : doc list -> doc
Only one [horizontal_fill] is allowed per [horizontal] element. The first one
will be used, the remaining ones will be ignored.
*)
val horizontal_fill : doc
val horizontal_fill : char -> doc
(** Render the resulting document.

View File

@ -38,6 +38,12 @@ let to_doc (model : Model.t) =
let content = tab_content_section model in
vertical
[ repo; empty; tabs; horizontal [ content; horizontal_fill; about ]; empty ]
[
repo;
empty;
tabs;
horizontal [ content; horizontal_fill ' '; about ];
empty;
]
let view (model : Model.t) = model |> to_doc |> Pretty.render ~width:model.width