Add file selector widget

This commit is contained in:
Dmitrii Kovanikov 2024-01-29 20:40:25 +00:00
parent 4c576beffa
commit 9fd83e2cdc
3 changed files with 67 additions and 18 deletions

View File

@ -1,17 +1,26 @@
type code_tab =
{
pos: int ;
files: string list ;
}
type tab =
| Code
| Code
| Issues
| PullRequests
type t =
{ repo: string ;
tab: tab ;
files: string list ;
current_tab: tab ;
code_tab: code_tab ;
}
let initial_model repo: t =
{
repo ;
tab = Code;
files = [ "src/"; "lib/"; "README.md" ]
current_tab = Code;
code_tab = {
pos = 0;
files = [ "src/"; "lib/"; "README.md" ]
};
}

View File

@ -1,5 +1,24 @@
open Minttea
let move_up (model: Model.t) = match model.current_tab with
| Code ->
let files_num = List.length model.code_tab.files in
let new_pos = (model.code_tab.pos + files_num - 1) mod files_num in
let code_tab = { model.code_tab with pos = new_pos } in
{ model with code_tab }
| Issues | PullRequests -> model
let move_down (model: Model.t) = match model.current_tab with
| Code ->
let files_num = List.length model.code_tab.files in
let new_pos = (model.code_tab.pos + 1) mod files_num in
let code_tab = { model.code_tab with pos = new_pos } in
{ model with code_tab }
| Issues | PullRequests -> model
let move_left model = model
let move_right model = model
let update event (model: Model.t) =
match event with
(* if we press `q` or the escape key, we exit *)
@ -7,11 +26,21 @@ let update event (model: Model.t) =
(* if we press a digit, we switch to the corresponding tab *)
| Event.KeyDown (Key "1") ->
({ model with tab = Model.Code }, Command.Noop)
({ model with current_tab = Model.Code }, Command.Noop)
| Event.KeyDown (Key "2") ->
({ model with tab = Model.Issues }, Command.Noop)
({ model with current_tab = Model.Issues }, Command.Noop)
| Event.KeyDown (Key "3") ->
({ model with tab = Model.PullRequests }, Command.Noop)
({ model with current_tab = Model.PullRequests }, Command.Noop)
(* directions/movements *)
| Event.KeyDown (Up | Key "k") ->
(move_up model, Command.Noop)
| Event.KeyDown (Down | Key "j") ->
(move_down model, Command.Noop)
| Event.KeyDown (Left | Key "h") ->
(move_left model, Command.Noop)
| Event.KeyDown (Right | Key "l") ->
(move_right model, Command.Noop)
(* otherwise, we do nothing *)
| _ -> (model, Command.Noop)

View File

@ -4,13 +4,13 @@ let fmt (styles : ANSITerminal.style list) : string -> string =
let fmt_repo =
fmt ANSITerminal.([Bold; blue])
let fmt_selected_tab =
let fmt_selected =
fmt ANSITerminal.([Bold; green])
let tab_section cur_tab =
let tabs_section cur_tab =
let p_tab tab txt =
if cur_tab = tab
then Pretty.Str (fmt_selected_tab txt)
then Pretty.Str (fmt_selected txt)
else Pretty.Str txt
in
Pretty.(render (
@ -37,7 +37,7 @@ let tab_section cur_tab =
)
)
let file_widget ~max_name_len files =
let file_widget ~max_name_len ~selected files =
(* Add two spaces for padding before and end of the file name *)
let max_len = max_name_len + 4 in
let top = "" ^ String_extra.repeat_txt (max_len - 2) "" ^ "" in
@ -46,20 +46,31 @@ let file_widget ~max_name_len files =
let fmt_line line =
"" ^ String_extra.fill_right max_name_len line ^ ""
in
let hi_pos = 2 * selected + 1 in
files
|> List.map fmt_line
|> List_extra.in_between ~sep:mid
|> (fun lines -> [top] @ lines @ [bot])
|> List.mapi (fun i s ->
if i = hi_pos - 1 || i = hi_pos || i = hi_pos + 1
then fmt_selected s
else s
)
|> String_extra.unlines
let files_section files =
let max_name_len = files |> List.map String_extra.graphemes_len |> List.fold_left max 0 in
file_widget ~max_name_len files
let code_section (code_tab: Model.code_tab) =
let max_name_len = code_tab.files |> List.map String_extra.graphemes_len |> List.fold_left max 0 in
file_widget ~max_name_len ~selected:code_tab.pos code_tab.files
let tab_content_section (model: Model.t) =
match model.current_tab with
| Code -> code_section model.code_tab
| Issues | PullRequests -> ""
let view (model: Model.t) =
let repo = fmt_repo model.repo in
let tabs = tab_section model.tab in
let files = files_section model.files in
let tabs = tabs_section model.current_tab in
let content = tab_content_section model in
Format.sprintf
{|%s
@ -67,4 +78,4 @@ let view (model: Model.t) =
%s
|} repo tabs files
|} repo tabs content