diff --git a/lib/fs/fs.ml b/lib/fs/fs.ml index fc14d9d..53e5ec1 100644 --- a/lib/fs/fs.ml +++ b/lib/fs/fs.ml @@ -1,8 +1,15 @@ module Filec = Filec type tree = - | File of string * Filec.t Lazy.t * Filec.file_type Lazy.t - | Dir of string * tree array Lazy.t + | File of { + name : string; + contents : Filec.t Lazy.t; + file_type : Filec.file_type Lazy.t; + } + | Dir of { + name : string; + children : tree array Lazy.t; + } type dir_cursor = { pos : int; @@ -15,8 +22,8 @@ type cursor = (* Extracts the file name from a tree node *) let file_name = function - | File (name, _, _) -> name - | Dir (name, _) -> name + | File { name; _ } -> name + | Dir { name; _ } -> name (* A files comparison: @@ -30,10 +37,10 @@ let order_files t1 t2 = | _, _ -> String.compare (file_name t1) (file_name t2) let rec sort_tree = function - | File (name, contents, ft) -> File (name, contents, ft) - | Dir (name, (lazy children)) -> + | File _ as f -> f + | Dir { name; children = (lazy children) } -> Array.sort order_files children; - Dir (name, lazy (Array.map sort_tree children)) + Dir { name; children = lazy (Array.map sort_tree children) } (* Recursively reads a directory tree *) let rec to_tree path = @@ -44,13 +51,15 @@ let rec to_tree path = (fun child_name -> to_tree (Filename.concat path child_name)) (Sys.readdir path)) in - let dirname = Filename.basename path in - Dir (dirname, children) + let name = Filename.basename path in + Dir { name; children } else File - ( Filename.basename path, - lazy (Filec.read path), - lazy (Filec.type_of_path path) ) + { + name = Filename.basename path; + contents = lazy (Filec.read path); + file_type = lazy (Filec.type_of_path path); + } let read_tree path = path |> to_tree |> sort_tree let file_at cursor = cursor.files.(cursor.pos) @@ -100,12 +109,12 @@ let go_next zipper = | Dir_cursor cursor -> ( let next = file_at cursor in match next with - | File (_name, contents, _) -> + | File { contents; _ } -> { parents = cursor :: zipper.parents; current = File_cursor (Lazy.force contents); } - | Dir (_, (lazy next)) -> + | Dir { children = (lazy next); _ } -> if Array.length next = 0 then zipper else { diff --git a/lib/fs/fs.mli b/lib/fs/fs.mli index 49d6611..c957b70 100644 --- a/lib/fs/fs.mli +++ b/lib/fs/fs.mli @@ -2,10 +2,20 @@ and current offsets. *) module Filec = Filec +(* NOTE: contents and file_type are stored separately so we can know the file + type and assign a proper icon without reading the contents *) + (** A definition of a file tree. *) type tree = - | File of string * Filec.t Lazy.t * Filec.file_type Lazy.t - | Dir of string * tree array Lazy.t + | File of { + name : string; + contents : Filec.t Lazy.t; + file_type : Filec.file_type Lazy.t; + } + | Dir of { + name : string; + children : tree array Lazy.t; + } (** Return the name of a given tree node. *) val file_name : tree -> string diff --git a/lib/tui/tui.ml b/lib/tui/tui.ml index f962065..2eaeb0d 100644 --- a/lib/tui/tui.ml +++ b/lib/tui/tui.ml @@ -29,10 +29,10 @@ let read_root_tree ~root_dir_path = let tree = Fs.read_tree root_dir_path in let files = match tree with - | Fs.File (path, _, _) -> - Printf.eprintf "Given path '%s' is not a directory!" path; + | Fs.File { name; _ } -> + Printf.eprintf "Given path '%s' is not a directory!" name; exit 1 - | Fs.Dir (_, files) -> files + | Fs.Dir { children = files; _ } -> files in files diff --git a/lib/tui/widget/code.ml b/lib/tui/widget/code.ml index 95dfa82..f5dddf2 100644 --- a/lib/tui/widget/code.ml +++ b/lib/tui/widget/code.ml @@ -50,11 +50,11 @@ let max_file_name_len files = let fmt_file ~max_name_len (tree : Fs.tree) = let pad = Extra.String.fill_right max_name_len in match tree with - | File (name, _, file_type) -> ( + | File { name; file_type; _ } -> ( match Lazy.force file_type with | Fs.Filec.Text -> Pretty.Icon.file_char ^ " " ^ pad name | Fs.Filec.Binary -> Pretty.Icon.bin_char ^ " " ^ pad name) - | Dir (name, (lazy children)) -> ( + | Dir { name; children = (lazy children) } -> ( match children with | [||] -> Pretty.Icon.empty_dir_char ^ " " ^ pad name | _ -> Pretty.Icon.dir_char ^ " " ^ pad name) @@ -189,8 +189,8 @@ let fs_to_view (fs : Fs.zipper) = | File_cursor contents, parent :: _ -> (parent, File_selected contents) | Dir_cursor cursor, _ -> ( match Fs.file_at cursor with - | File (_, contents, _) -> (cursor, File_selected (Lazy.force contents)) - | Dir (_, children) -> + | File { contents; _ } -> (cursor, File_selected (Lazy.force contents)) + | Dir { children; _ } -> ( cursor, Dir_selected {