Minga.Project.FileTree (Minga v0.1.0)

Copy Markdown View Source

Pure data structure for a navigable filesystem tree.

Holds the root path, a set of expanded directories, a cursor position, and a show_hidden toggle. The flat list of visible entries is cached in the struct after the first computation and invalidated whenever tree state changes (expand, collapse, toggle_hidden, refresh, reveal).

No GenServer; the editor owns this struct in its state.

Summary

Types

A single visible entry in the tree.

t()

Functions

Clears the active substring filter and resets selection to the first visible entry.

Collapses the directory at cursor, or if on a file/collapsed dir, collapses the parent.

Collapses all directories, keeping only the root expanded. Resets cursor to 0.

Returns the tree with entries guaranteed to be populated.

Expands the directory at cursor. No-op on files or already-expanded dirs.

Marks a directory path as expanded and invalidates cached entries.

Moves the cursor down by one entry, clamped to the last visible entry.

Moves the cursor up by one entry.

Creates a new file tree rooted at the given directory path.

Refreshes the tree by rescanning the filesystem (clamps cursor).

Replaces the cached git status map for the tree.

Re-roots the tree while preserving display options.

Highlights the given file path in the tree by expanding its parent directories and moving the cursor to it.

Selects the visible entry at the given index, clamped to the current visible range.

Returns the entry at the current cursor position, or nil if empty.

Sets the active substring filter and resets selection to the first match.

Toggles expand/collapse for the entry at the cursor.

Toggles visibility of hidden files (dotfiles).

Returns the flat list of currently visible entries.

Types

entry()

@type entry() :: %{
  path: String.t(),
  name: String.t(),
  dir?: boolean(),
  depth: non_neg_integer(),
  last_child?: boolean(),
  guides: [boolean()]
}

A single visible entry in the tree.

The guides field is a list of booleans, one per ancestor depth level (index 0 = depth 0, index 1 = depth 1, etc.). true means the ancestor at that depth has more siblings below this entry (draw ), false means it was the last child (draw blank). The renderer uses this plus last_child? to pick ├── vs └── at the entry's own depth.

t()

@type t() :: %Minga.Project.FileTree{
  cursor: non_neg_integer(),
  entries: [entry()] | nil,
  expanded: MapSet.t(String.t()),
  filter: String.t() | nil,
  git_status: Minga.Project.FileTree.GitStatus.status_map(),
  root: String.t(),
  show_hidden: boolean(),
  width: pos_integer()
}

Functions

clear_filter(tree)

@spec clear_filter(t()) :: t()

Clears the active substring filter and resets selection to the first visible entry.

collapse(tree)

@spec collapse(t()) :: t()

Collapses the directory at cursor, or if on a file/collapsed dir, collapses the parent.

collapse_all(tree)

@spec collapse_all(t()) :: t()

Collapses all directories, keeping only the root expanded. Resets cursor to 0.

ensure_entries(tree)

@spec ensure_entries(t()) :: t()

Returns the tree with entries guaranteed to be populated.

If entries are already cached, returns the tree unchanged. Otherwise computes entries from the filesystem and caches them. Use this when you need to read entries multiple times from the same tree without redundant filesystem walks.

expand(tree)

@spec expand(t()) :: t()

Expands the directory at cursor. No-op on files or already-expanded dirs.

expand_path(tree, path)

@spec expand_path(t(), String.t()) :: t()

Marks a directory path as expanded and invalidates cached entries.

move_down(tree)

@spec move_down(t()) :: t()

Moves the cursor down by one entry, clamped to the last visible entry.

move_up(tree)

@spec move_up(t()) :: t()

Moves the cursor up by one entry.

new(root, opts \\ [])

@spec new(
  String.t(),
  keyword()
) :: t()

Creates a new file tree rooted at the given directory path.

refresh(tree)

@spec refresh(t()) :: t()

Refreshes the tree by rescanning the filesystem (clamps cursor).

replace_git_status(tree, git_status)

@spec replace_git_status(t(), Minga.Project.FileTree.GitStatus.status_map()) :: t()

Replaces the cached git status map for the tree.

reroot(tree, root)

@spec reroot(t(), String.t()) :: t()

Re-roots the tree while preserving display options.

reveal(tree, file_path)

@spec reveal(t(), String.t()) :: t()

Highlights the given file path in the tree by expanding its parent directories and moving the cursor to it.

select(tree, index)

@spec select(t(), integer()) :: t()

Selects the visible entry at the given index, clamped to the current visible range.

selected_entry(tree)

@spec selected_entry(t()) :: entry() | nil

Returns the entry at the current cursor position, or nil if empty.

This reads from the cached entries if available. For performance-sensitive callers that will call this repeatedly, call ensure_entries/1 first to populate the cache; subsequent calls on the same struct will use it.

set_filter(tree, filter)

@spec set_filter(t(), String.t()) :: t()

Sets the active substring filter and resets selection to the first match.

toggle_expand(tree)

@spec toggle_expand(t()) :: t()

Toggles expand/collapse for the entry at the cursor.

If the cursor is on a directory, toggles its expanded state. If on a file, this is a no-op.

toggle_hidden(tree)

@spec toggle_hidden(t()) :: t()

Toggles visibility of hidden files (dotfiles).

visible_entries(tree)

@spec visible_entries(t()) :: [entry()]

Returns the flat list of currently visible entries.

Returns cached entries if available. Otherwise walks the directory tree starting from root, descending into expanded directories. Results are sorted: directories first, then files, both alphabetically. Hidden files are excluded unless show_hidden is true.

Note: this returns only the list, not the updated struct. If the cache was empty, the computed entries are not stored back in the struct. Callers that need repeated access should call ensure_entries/1 first to populate the cache, then read .entries or call this function on the returned struct.