From 64e9a9f1f922276f412792676864ecf71a8cd919 Mon Sep 17 00:00:00 2001 From: Dmitrii Kovanikov Date: Sun, 4 Feb 2024 14:26:18 +0000 Subject: [PATCH] Add FS tree zipper --- lib/fs.ml | 33 +++++++++++++++++++++++++++++++++ lib/tui/model.ml | 17 +++++++++++++---- lib/tui/update.ml | 12 ++++-------- lib/tui/view.ml | 10 ++++++++-- 4 files changed, 58 insertions(+), 14 deletions(-) create mode 100644 lib/fs.ml diff --git a/lib/fs.ml b/lib/fs.ml new file mode 100644 index 0000000..6d6d78b --- /dev/null +++ b/lib/fs.ml @@ -0,0 +1,33 @@ +type tree = + | File of string + | Dir of string * tree array + +let file_name = function + | File path -> path + | Dir (path, _) -> path + +type cursor = + { + pos: int; + files: tree array; + } + +type zipper = + { + parents: cursor list; + current: cursor; + } + +let go_down zipper = + let cursor = zipper.current in + let len = Array.length cursor.files in + let new_pos = (cursor.pos + 1) mod len in + let new_cursor = { cursor with pos = new_pos } in + { zipper with current = new_cursor } + +let go_up zipper = + let cursor = zipper.current in + let len = Array.length cursor.files in + let new_pos = (cursor.pos + len - 1) mod len in + let new_cursor = { cursor with pos = new_pos } in + { zipper with current = new_cursor } diff --git a/lib/tui/model.ml b/lib/tui/model.ml index 35ee04a..8a776b2 100644 --- a/lib/tui/model.ml +++ b/lib/tui/model.ml @@ -1,7 +1,6 @@ type code_tab = { - pos: int ; - files: string list ; + fs: Fs.zipper ; } type tab = @@ -20,7 +19,17 @@ let initial_model repo: t = repo ; current_tab = Code; code_tab = { - pos = 0; - files = [ "src/"; "lib/"; "README.md" ] + fs = + { + parents = []; + current = { + pos = 0; + files = + [| Dir ("src/", [||]); + Dir ("lib/", [||]); + File "README.md"; + |] + } + } }; } \ No newline at end of file diff --git a/lib/tui/update.ml b/lib/tui/update.ml index e716701..a08be36 100644 --- a/lib/tui/update.ml +++ b/lib/tui/update.ml @@ -2,18 +2,14 @@ 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 } + let fs = Fs.go_up model.code_tab.fs in + { model with code_tab = { fs } } | 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 } + let fs = Fs.go_down model.code_tab.fs in + { model with code_tab = { fs } } | Issues | PullRequests -> model let move_left model = model diff --git a/lib/tui/view.ml b/lib/tui/view.ml index d3013c6..9c60cf1 100644 --- a/lib/tui/view.ml +++ b/lib/tui/view.ml @@ -48,6 +48,7 @@ let file_widget ~max_name_len ~selected files = in let hi_pos = 2 * selected + 1 in files + |> Array.to_list |> List.map fmt_line |> List_extra.in_between ~sep:mid |> (fun lines -> [top] @ lines @ [bot]) @@ -59,8 +60,13 @@ let file_widget ~max_name_len ~selected files = |> String_extra.unlines 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 cursor = code_tab.fs.current in + let files = Array.map Fs.file_name cursor.files in + let max_name_len = + files + |> Array.map String_extra.graphemes_len + |> Array.fold_left max 0 in + file_widget ~max_name_len ~selected:cursor.pos files let tab_content_section (model: Model.t) = match model.current_tab with