Implement simple pretty-printing library and basic tabs view

This commit is contained in:
Dmitrii Kovanikov 2024-01-08 19:07:07 +00:00
parent 538e5bd048
commit 1a7618a5c5
5 changed files with 83 additions and 8 deletions

View File

@ -23,6 +23,7 @@
(cmdliner (>= "1.2.0"))
(ezcurl (>= "0.2.4"))
(minttea (>= "0.0.2"))
uuseg.string
)
(tags
(tui cli git github)))

View File

@ -15,7 +15,7 @@ depends: [
"cmdliner" {>= "1.2.0"}
"ezcurl" {>= "0.2.4"}
"minttea" {>= "0.0.2"}
"spices"
"uuseg.string"
"odoc" {with-doc}
]
build: [

View File

@ -7,5 +7,6 @@
cmdliner
ezcurl
minttea
uuseg.string
)
)

45
lib/pretty.ml Normal file
View File

@ -0,0 +1,45 @@
(* A simple pretty printing combinator library *)
type doc =
| Empty
| Str of string
| Vertical of doc * doc
| Horizontal of doc * doc
let (---) t b = Vertical (t, b)
let (<|>) l r = Horizontal (l, r)
let graphemes_len =
Uuseg_string.fold_utf_8 `Grapheme_cluster (fun len _ -> len + 1) 0
let fill_right (n : int) (s : string) : string =
s ^ String.concat "" (List.init (n - graphemes_len s) (fun _ -> ""))
let zip_lines l r =
let max_len_l = List.map graphemes_len l |> List.fold_left max 0 in
let padding = String.make max_len_l ' ' in
let rec zip l r =
match (l, r) with
| (l, []) ->
l
| ([], r) ->
List.map (fun s -> padding ^ s) r
| (hd_l :: tl_l, hd_r :: tl_r) ->
(fill_right max_len_l hd_l ^ hd_r) :: zip tl_l tl_r
in
zip l r
let rec render_to_lines = function
| Empty ->
[]
| Str s ->
[s]
| Vertical (top, bottom) ->
render_to_lines top @ render_to_lines bottom
| Horizontal (left, right) ->
zip_lines (render_to_lines left) (render_to_lines right)
let render doc =
doc
|> render_to_lines
|> String.concat "\n"

View File

@ -2,19 +2,47 @@ let fmt (styles : ANSITerminal.style list) : string -> string =
ANSITerminal.sprintf styles "%s"
let fmt_repo =
fmt ANSITerminal.([Bold; blue])
let fmt_selected_tab =
fmt ANSITerminal.([Bold; green])
let tab_section cur_tab =
let p_tab tab txt =
if cur_tab = tab
then Pretty.Str (fmt_selected_tab txt)
else Pretty.Str txt
in
Pretty.(render (
(p_tab Model.Code "╭──────╮" ---
p_tab Model.Code "│ Code │" ---
p_tab Model.Code "└──────┴"
) <|>
(Str " " ---
Str " " ---
Str ""
) <|>
(p_tab Model.Issues "╭────────╮" ---
p_tab Model.Issues "│ Issues │" ---
p_tab Model.Issues "┴────────┴"
) <|>
(Str " " ---
Str " " ---
Str ""
) <|>
(p_tab Model.PullRequests "╭───────────────╮" ---
p_tab Model.PullRequests "│ Pull Requests │" ---
p_tab Model.PullRequests "┴───────────────┴"
)
)
)
let view (model: Model.t) =
let repo = fmt_repo model.repo in
let tab =
match model.tab with
| Code -> "Code"
| Issues -> "Issues"
| PullRequests -> "Pull Requests"
in
let tabs = tab_section model.tab in
Format.sprintf
{|%s
%s
|} repo tab
|} repo tabs