MingaEditor.State.FileTree (Minga v0.1.0)

Copy Markdown View Source

File tree sub-state: tree data, focus, and backing buffer.

Wraps the file-tree-related fields from EditorState into a single struct with query and transition helpers. Includes inline editing state for new file, new folder, and rename operations.

Summary

Types

Single owner tag for resident file-tree content.

Inline editing state for creating files/folders or renaming entries.

Identity of the latest admitted filter request.

Explicit user interaction phase for the file tree sidebar.

Derived presentation state for the file tree sidebar.

t()

File tree sub-state.

Explicit visibility phase for the file tree sidebar.

Functions

Accepts the current filter and leaves the narrowed tree visible.

Installs a current filter result prepared by a scheduler worker.

Atomically accepts a current refresh result or identifies why it cannot apply.

Collapses watcher lineage only for the latest exact successful request.

Publishes an immediate loading tree for a root scan without resolving entries.

Cancels inline editing, clearing the editing state back to browse.

Changes the watcher target to cleanup-only while retaining all known roots.

Clears a pending file tree clipboard operation.

Publishes an unfiltered loading tree while preserving filter-input disposition.

Closes the tree and clears the buffer.

Marks the sidebar as failed with a displayable reason.

Terminalizes watcher retry correlation after the bounded attempt budget.

Reports a current filter failure while preserving recovery on the next query.

Finishes a current failed or canceled filter request without installing rows.

Finishes a failed or canceled current request without changing tree content.

Finishes watcher work without discarding cleanup candidates.

Marks the visible file tree as focused.

Hides the sidebar while keeping the loaded tree, backing buffer, and watchers.

Hides the file tree help overlay.

Returns true when the file tree has loaded data.

Marks the sidebar as loading.

Stores a pending file tree clipboard operation.

Consumes a correlated debounce message and focuses the result on the live tree.

Reports a refresh failure while preserving the open tree interaction state.

Replaces metadata on the current tree without changing topology status or refresh correlation.

Records one debounced request to refresh the open tree.

Returns the monotonic generation of the current root and watcher lineage.

Installs an empty failed root scan while retaining the requested root.

Correlates a bounded watcher synchronization retry.

Updates the project root associated with the file tree.

Replaces the tree data.

Enters inline editing mode at the given index.

Starts inline file tree filtering without resolving any rows.

Toggles the file tree help overlay.

Correlates the latest admitted filter request with its exact root and query.

Correlates an admitted typed refresh request with the root it scans.

Re-arms one pending refresh intent after scheduler admission pressure.

Correlates the latest admitted watcher synchronization request.

Marks the file tree as unfocused.

Updates the text being typed in the inline editor.

Publishes a loading filter transition without cache or filesystem calls.

Returns the immutable watcher intent owned by this file tree.

Consumes only the current watcher retry timer.

Types

clipboard_mark()

@type clipboard_mark() :: MingaEditor.State.FileTree.ClipboardMark.t()

clipboard_operation()

@type clipboard_operation() :: MingaEditor.State.FileTree.ClipboardMark.operation()

content()

@type content() ::
  :closed
  | {:loading, Minga.Project.FileTree.t() | nil}
  | {:ready, Minga.Project.FileTree.t()}
  | {:error, String.t(), Minga.Project.FileTree.t() | nil}

Single owner tag for resident file-tree content.

editing()

@type editing() :: %{
  index: non_neg_integer(),
  text: String.t(),
  type: editing_type(),
  original_name: String.t() | nil
}

editing_type()

@type editing_type() :: :new_file | :new_folder | :rename

Inline editing state for creating files/folders or renaming entries.

Present while interaction is {:editing, editing()}. The editing/1 query returns nil in every other interaction phase. The index is the visual position in the visible entry list where the editing row appears. For new file/folder, this is the insertion point. For rename, this is the entry being renamed.

filter_request()

@type filter_request() :: %{root: String.t(), filter: String.t(), token: reference()}

Identity of the latest admitted filter request.

interaction()

@type interaction() :: :browse | {:editing, editing()} | :filtering | :help

Explicit user interaction phase for the file tree sidebar.

status()

@type status() :: :hidden | :loading | :empty | :ready | {:error, String.t()}

Derived presentation state for the file tree sidebar.

t()

@type t() :: %MingaEditor.State.FileTree{
  buffer: pid() | nil,
  clipboard_mark: clipboard_mark() | nil,
  content: content(),
  filter_request: filter_request() | nil,
  interaction: interaction(),
  original_root: String.t() | nil,
  project_root: String.t() | nil,
  refresh: MingaEditor.State.FileTree.Refresh.t(),
  tree_width: pos_integer(),
  visibility: visibility(),
  watchers: MingaEditor.State.FileTree.Watchers.t()
}

File tree sub-state.

visibility()

@type visibility() :: :hidden | :visible | :focused

Explicit visibility phase for the file tree sidebar.

Functions

accept_filter(ft)

@spec accept_filter(t()) :: t()

Accepts the current filter and leaves the narrowed tree visible.

accept_filter_result(ft, root, filter, token, result)

@spec accept_filter_result(
  t(),
  String.t(),
  String.t(),
  reference(),
  MingaEditor.FileTree.FilterWalk.Result.t()
) :: {:accepted | :closed | :rerooted | :stale, t()}

Installs a current filter result prepared by a scheduler worker.

accept_refresh_result(ft, root, token, refreshed_tree)

@spec accept_refresh_result(
  t(),
  String.t(),
  MingaEditor.State.FileTree.Refresh.request_token(),
  Minga.Project.FileTree.t()
) :: {:accepted | :closed | :rerooted | :stale, t()}

Atomically accepts a current refresh result or identifies why it cannot apply.

accept_watcher_result(ft, token, target)

@spec accept_watcher_result(t(), reference(), String.t() | nil) ::
  {:current | :stale, t()}

Collapses watcher lineage only for the latest exact successful request.

begin_root_scan(ft, tree, kind)

@spec begin_root_scan(t(), Minga.Project.FileTree.t(), :project | :reroot) :: t()

Publishes an immediate loading tree for a root scan without resolving entries.

cancel_editing(ft)

@spec cancel_editing(t()) :: t()

Cancels inline editing, clearing the editing state back to browse.

cleanup_watchers(ft)

@spec cleanup_watchers(t()) :: t()

Changes the watcher target to cleanup-only while retaining all known roots.

clear_clipboard(ft)

@spec clear_clipboard(t()) :: t()

Clears a pending file tree clipboard operation.

clear_filter_loading(ft, disposition)

@spec clear_filter_loading(t(), :keep_open | :dismiss) :: t()

Publishes an unfiltered loading tree while preserving filter-input disposition.

close(ft)

@spec close(t()) :: t()

Closes the tree and clears the buffer.

content(file_tree)

@spec content(t()) :: content()

editing(file_tree)

@spec editing(t()) :: editing() | nil

editing?(ft)

@spec editing?(t()) :: boolean()

error(ft, reason)

@spec error(t(), term()) :: t()

Marks the sidebar as failed with a displayable reason.

exhaust_watcher_retry(ft)

@spec exhaust_watcher_retry(t()) :: t()

Terminalizes watcher retry correlation after the bounded attempt budget.

filter_failed(ft, reason)

@spec filter_failed(t(), term()) :: t()

Reports a current filter failure while preserving recovery on the next query.

finish_filter(ft, root, filter, token)

@spec finish_filter(t(), String.t(), String.t(), reference()) ::
  {:current | :closed | :rerooted | :stale, t()}

Finishes a current failed or canceled filter request without installing rows.

finish_refresh(ft, root, token)

@spec finish_refresh(
  t(),
  String.t(),
  MingaEditor.State.FileTree.Refresh.request_token()
) ::
  {:current | :closed | :rerooted | :stale, t()}

Finishes a failed or canceled current request without changing tree content.

finish_watcher_request(ft, token)

@spec finish_watcher_request(t(), reference()) :: {:current | :stale, t()}

Finishes watcher work without discarding cleanup candidates.

focus(ft)

@spec focus(t()) :: t()

Marks the visible file tree as focused.

focused?(ft)

@spec focused?(t()) :: boolean()

hide(ft)

@spec hide(t()) :: t()

Hides the sidebar while keeping the loaded tree, backing buffer, and watchers.

Toggling visibility off is a pure layout change: the render model still carries the full tree data so showing it again does not rebuild anything (#2626).

hide_help(ft)

@spec hide_help(t()) :: t()

Hides the file tree help overlay.

loaded?(ft)

@spec loaded?(t()) :: boolean()

Returns true when the file tree has loaded data.

A hidden-but-loaded tree is still loaded: the data, buffer, and watchers stay alive so refresh handlers keep it fresh. This is intentionally NOT "is the sidebar visible" — use visible?/1 for that. Mixing the two leaks the backing buffer (see #2626).

loading(ft)

@spec loading(t()) :: t()

Marks the sidebar as loading.

mark_clipboard(ft, path, name, dir?, operation)

@spec mark_clipboard(t(), String.t(), String.t(), boolean(), clipboard_operation()) ::
  t()

Stores a pending file tree clipboard operation.

open(ft, tree, buffer)

@spec open(t(), Minga.Project.FileTree.t(), pid() | nil) :: t()

refresh_debounce_elapsed(ft, token)

@spec refresh_debounce_elapsed(
  t(),
  MingaEditor.State.FileTree.Refresh.debounce_token()
) ::
  {:ready, Minga.Project.FileTree.t(), non_neg_integer(), t()}
  | {:closed, non_neg_integer(), t()}
  | {:stale, t()}

Consumes a correlated debounce message and focuses the result on the live tree.

refresh_failed(ft, reason)

@spec refresh_failed(t(), term()) :: t()

Reports a refresh failure while preserving the open tree interaction state.

replace_tree(ft, tree)

@spec replace_tree(t(), Minga.Project.FileTree.t()) :: t()

replace_tree_metadata(ft, tree)

@spec replace_tree_metadata(t(), Minga.Project.FileTree.t()) :: t()

Replaces metadata on the current tree without changing topology status or refresh correlation.

request_refresh_debounce(ft, token)

@spec request_refresh_debounce(
  t(),
  MingaEditor.State.FileTree.Refresh.debounce_token()
) ::
  {:scheduled | :already_scheduled, t()}

Records one debounced request to refresh the open tree.

root_generation(ft)

@spec root_generation(t()) :: non_neg_integer()

Returns the monotonic generation of the current root and watcher lineage.

root_scan_failed(ft, reason)

@spec root_scan_failed(t(), term()) :: t()

Installs an empty failed root scan while retaining the requested root.

schedule_watcher_retry(ft, token)

@spec schedule_watcher_retry(t(), reference()) :: {pos_integer(), t()}

Correlates a bounded watcher synchronization retry.

set_project_root(ft, root)

@spec set_project_root(t(), String.t() | nil) :: t()

Updates the project root associated with the file tree.

set_tree(ft, tree)

@spec set_tree(t(), Minga.Project.FileTree.t() | nil) :: t()

Replaces the tree data.

show(ft)

@spec show(t()) :: t()

start_editing(ft, index, type, initial_text \\ "")

@spec start_editing(t(), non_neg_integer(), editing_type(), String.t()) :: t()

Enters inline editing mode at the given index.

For new file/folder, initial_text is empty. For rename, initial_text is the current entry name.

start_filtering(ft)

@spec start_filtering(t()) :: t()

Starts inline file tree filtering without resolving any rows.

status(file_tree)

@spec status(t()) :: status()

toggle_help(ft)

@spec toggle_help(t()) :: t()

Toggles the file tree help overlay.

track_filter_request(ft, root, filter, token)

@spec track_filter_request(t(), String.t(), String.t(), reference()) :: t()

Correlates the latest admitted filter request with its exact root and query.

track_refresh_request(ft, root, token)

@spec track_refresh_request(
  t(),
  String.t(),
  MingaEditor.State.FileTree.Refresh.request_token()
) :: t()

Correlates an admitted typed refresh request with the root it scans.

track_refresh_retry(ft, token)

@spec track_refresh_retry(t(), MingaEditor.State.FileTree.Refresh.debounce_token()) ::
  {pos_integer(), t()}

Re-arms one pending refresh intent after scheduler admission pressure.

track_watcher_request(ft, token)

@spec track_watcher_request(t(), reference()) :: t()

Correlates the latest admitted watcher synchronization request.

tree(file_tree)

@spec tree(t()) :: Minga.Project.FileTree.t() | nil

unfocus(ft)

@spec unfocus(t()) :: t()

Marks the file tree as unfocused.

update_editing_text(ft, new_text)

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

Updates the text being typed in the inline editor.

update_filter(ft, filter)

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

Publishes a loading filter transition without cache or filesystem calls.

visible?(file_tree)

@spec visible?(t()) :: boolean()

visible_status?(arg1)

@spec visible_status?(status()) :: boolean()

watcher_intent(ft)

@spec watcher_intent(t()) :: MingaEditor.State.FileTree.Watchers.t()

Returns the immutable watcher intent owned by this file tree.

watcher_retry_elapsed(ft, token)

@spec watcher_retry_elapsed(t(), reference()) :: {:current | :stale, t()}

Consumes only the current watcher retry timer.

width(ft)

@spec width(t()) :: pos_integer()