mirror of
https://github.com/chshersh/github-tui.git
synced 2024-10-05 14:57:53 +03:00
Add initial support for horizontal filling
This commit is contained in:
parent
e7b216cdfb
commit
2d6a0083bf
@ -8,8 +8,10 @@ type chunk = {
|
||||
let fmt_chunk { styles; string } = ANSITerminal.sprintf styles "%s" string
|
||||
|
||||
let padding_chunk width =
|
||||
let padding = String.make width ' ' in
|
||||
{ styles = []; string = padding }
|
||||
if width <= 0 then { styles = []; string = "" }
|
||||
else
|
||||
let padding = String.make width ' ' in
|
||||
{ styles = []; string = padding }
|
||||
|
||||
type t = {
|
||||
chunks : chunk list;
|
||||
|
@ -15,3 +15,5 @@ let rec take n = function
|
||||
| _ when n <= 0 -> []
|
||||
| [] -> []
|
||||
| x :: xs -> x :: take (n - 1) xs
|
||||
|
||||
let max_on f list = List.fold_left (fun acc x -> max acc (f x)) 0 list
|
||||
|
@ -32,25 +32,76 @@ let zip_lines (l : Line.t list) (r : Line.t list) =
|
||||
else
|
||||
let padding_chunk = Line.padding_chunk (max_len_l - left_len) in
|
||||
let new_line =
|
||||
Line.append hd_l (Line.append (Line.of_chunks [ padding_chunk ]) hd_r)
|
||||
Line.append hd_l
|
||||
(Line.append (Line.of_chunks [ padding_chunk ]) hd_r)
|
||||
in
|
||||
new_line :: zip tl_l tl_r
|
||||
in
|
||||
|
||||
zip l r
|
||||
|
||||
type prerender_pass_info = {
|
||||
has_fill : bool;
|
||||
size_taken : int;
|
||||
}
|
||||
|
||||
type prerender =
|
||||
| Rendered of Line.t list
|
||||
| Fill
|
||||
|
||||
let rec render_to_lines ~width = function
|
||||
| Str (styles, string) -> [ Line.of_chunks [ { styles; string } ] ]
|
||||
| Horizontal_fill -> [ Line.of_chunks [ Line.padding_chunk width ] ]
|
||||
| Vertical rows -> List.concat_map (render_to_lines ~width) rows
|
||||
| Horizontal cols -> (
|
||||
match cols with
|
||||
| [] -> []
|
||||
(* TODO: This is potentially really slow; optimise *)
|
||||
| hd :: tl ->
|
||||
List.fold_left
|
||||
(fun acc col -> zip_lines acc (render_to_lines ~width col))
|
||||
(render_to_lines ~width hd) tl)
|
||||
| Horizontal cols -> horizontal_to_lines ~width cols
|
||||
|
||||
and horizontal_to_lines ~width cols =
|
||||
(* Step [prerender]. Check if there's Horizontal_fill, render everything else
|
||||
and calculate rendered size. *)
|
||||
let pass_info, prerendered =
|
||||
List.fold_left
|
||||
(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)
|
||||
| other ->
|
||||
(* WARNING: This will pass the total width to the left-most Horizontal_fill *)
|
||||
let rendered = render_to_lines ~width other in
|
||||
let max_line_width = List_extra.max_on Line.length rendered in
|
||||
( {
|
||||
has_fill = pass_info.has_fill;
|
||||
size_taken = pass_info.size_taken + max_line_width;
|
||||
},
|
||||
Rendered rendered )
|
||||
in
|
||||
(* TODO: This is suboptimal *)
|
||||
(new_pass_info, prerendered @ [ new_prerendered ]))
|
||||
({ has_fill = false; size_taken = 0 }, [])
|
||||
cols
|
||||
in
|
||||
|
||||
(* Step [fill_size]. Calculate the size of remaining fill *)
|
||||
let fill_width = width - pass_info.size_taken in
|
||||
|
||||
(* Step [fill]. Fill the first Horizontal_fill *)
|
||||
let _, rendered =
|
||||
List.fold_left
|
||||
(fun (remaining_width, rendered) prerendered ->
|
||||
match prerendered with
|
||||
| Rendered lines -> (remaining_width, rendered @ [ lines ])
|
||||
| Fill ->
|
||||
( 0,
|
||||
rendered
|
||||
@ [ [ Line.(of_chunks [ padding_chunk remaining_width ]) ] ] ))
|
||||
(fill_width, []) prerendered
|
||||
in
|
||||
|
||||
(* Step [combine]. Combine the final columns of lines. *)
|
||||
match rendered with
|
||||
| [] -> []
|
||||
(* TODO: This is potentially really slow; optimise *)
|
||||
| hd :: tl -> List.fold_left zip_lines hd tl
|
||||
|
||||
let render ~width doc =
|
||||
doc |> render_to_lines ~width |> List.map Line.fmt |> String_extra.unlines
|
||||
|
@ -8,9 +8,7 @@ let init ~repo ~root_dir_path : Model.initial_data =
|
||||
| Fs.Dir (_, files) -> files
|
||||
in
|
||||
let height = Option.value (Terminal_size.get_rows ()) ~default:120 in
|
||||
let width =
|
||||
Option.value (Terminal_size.get_columns ()) ~default:140
|
||||
in
|
||||
let width = Option.value (Terminal_size.get_columns ()) ~default:140 in
|
||||
{ repo; root_dir_path; files; width; height }
|
||||
|
||||
let app = Minttea.app ~init:Init.init ~update:Update.update ~view:View.view ()
|
||||
|
@ -3,9 +3,7 @@ let style_selected = ANSITerminal.[ Bold; green ]
|
||||
let style_directory = ANSITerminal.[ Bold; magenta ]
|
||||
|
||||
let debug_section (model : Model.t) =
|
||||
let debug_info =
|
||||
Printf.sprintf "%dw x %dh" model.width model.height
|
||||
in
|
||||
let debug_info = Printf.sprintf "%dw x %dh" model.width model.height in
|
||||
Pretty.str debug_info
|
||||
|
||||
let tabs_section cur_tab =
|
||||
@ -28,9 +26,12 @@ let code_section (code_tab : Model.code_tab) =
|
||||
Pretty.vertical [ current_path_doc; fs_doc ]
|
||||
|
||||
let tab_content_section (model : Model.t) =
|
||||
match model.current_tab with
|
||||
| Code -> code_section model.code_tab
|
||||
| Issues | PullRequests -> Pretty.str ""
|
||||
let tab_doc =
|
||||
match model.current_tab with
|
||||
| Code -> code_section model.code_tab
|
||||
| Issues | PullRequests -> Pretty.str ""
|
||||
in
|
||||
Pretty.(horizontal [ tab_doc; horizontal_fill; str "This is test" ])
|
||||
|
||||
let to_doc (model : Model.t) =
|
||||
let open Pretty in
|
||||
|
Loading…
Reference in New Issue
Block a user