MingaEditor.Agent.UIState (Minga v0.1.0)

Copy Markdown View Source

Unified agent UI state wrapping Panel and View sub-structs.

Panel holds prompt editing and chat display state (buffer, history, scroll, model config, paste blocks). View holds layout, search, preview, toasts, and diff baselines. Splitting into sub-structs keeps each under 16 fields while providing a single access point on EditorState.agent_ui.

Most callers use the functions on this module (routed through AgentAccess.update_agent_ui/2). Input handlers and renderers that need read-only field access use AgentAccess.panel/1 to get the Panel sub-struct directly.

Summary

Types

focus() deprecated

Which panel has keyboard focus. Deprecated: use View.focus().

Vim mode for the input field when focused.

paste_block() deprecated

A collapsed paste block. Deprecated: use Panel.paste_block().

prefix() deprecated

Active prefix key. Deprecated: use View.prefix().

search_match() deprecated

A search match. Deprecated: use View.search_match().

search_state() deprecated

Search state. Deprecated: use View.search_state().

t()

Agent UI state wrapping Panel and View sub-structs.

Thinking level for models that support extended reasoning.

toast() deprecated

A notification toast. Deprecated: use View.toast().

Functions

Activates the view, saving the current window layout.

Cancels search.

Clears all diff baselines.

Clears the chat display without affecting conversation history.

Clears the input (after submission). Saves current text to history first.

Clears the input and scrolls to the bottom.

Clears any pending prefix.

Clears all toasts.

Confirms search (keeps matches for n/N navigation, disables input).

Deactivates the view and returns the restored window layout.

Deletes the character before the cursor.

Dismisses the help overlay.

Dismisses the current toast.

Re-engages auto-scroll. Delegates to Minga.Editing.Minga.Editing.pin_to_bottom/1.

Ensures a prompt Buffer.Server is running. Starts one if prompt_buffer is nil or the process is dead.

Returns the baseline content for a path, or nil if none recorded.

Grows the chat panel width by one step (clamped at max).

Recalls the next (more recent) prompt from history.

Recalls the previous prompt from history.

Returns the input cursor position as {line, col}.

Returns true if the input is empty (single empty line).

Returns the number of input lines.

Returns the input lines as a list of strings.

Returns the raw input text (with placeholders, not substituted).

Inserts a character at the cursor position.

Inserts a newline at the cursor, splitting the current line.

Inserts pasted text into the input.

No-op. Streaming events call this; renderer handles pinning.

Moves cursor down within the input. Returns :at_bottom if already on the last line.

Moves cursor up within the input. Returns :at_top if already on the first line.

Creates a new UIState with default sub-structs.

Moves to the next search match.

Returns the paste block index for a placeholder line, or nil if not a placeholder.

Returns the line count for a paste block at the given index.

Returns true if the given line is a paste placeholder token.

Moves to the previous search match.

Returns the prompt text with paste placeholders substituted.

Records the baseline content for a file path (first edit only).

Resets the chat panel width to the configured default.

Saves the current input to prompt history (if non-empty).

Scrolls the content down. Delegates to Minga.Editing.Minga.Editing.scroll_down/2.

Pins chat to bottom. Delegates to Minga.Editing.Minga.Editing.pin_to_bottom/1.

Scrolls to top. Delegates to Minga.Editing.Minga.Editing.scroll_to_top/1.

Scrolls the content up. Delegates to Minga.Editing.Minga.Editing.scroll_up/2.

Scrolls the preview pane down by the given number of lines.

Scrolls the preview pane to a large offset (renderer clamps to actual content).

Scrolls the preview pane to the top (offset 0).

Scrolls the preview pane up by the given number of lines, clamped at 0.

Returns true if search input is being typed.

Returns the search query, or nil if not searching.

Returns the saved scroll position from before search started.

Returns true if search is active.

Switches focus to the given panel.

Sets the input focus state. Entering focus ensures the prompt buffer exists.

Sets the model name.

Sets the pending prefix for multi-key sequences.

Replaces the input content with the given text. Does not save to history.

Sets the provider name.

Sets the scroll offset to an absolute value. Unpins from bottom.

Sets search matches and resets current to 0.

Sets the thinking level.

Shrinks the chat panel width by one step (clamped at min).

Starts a search, saving the current scroll position.

Advances the spinner animation frame.

Returns true if a toast is currently visible.

Toggles panel visibility.

Toggles the help overlay visibility.

Toggles expand/collapse on the paste block at the current cursor line.

Updates the preview state with the given function.

Updates the search query string.

Types

focus()

This type is deprecated. Use View.focus() instead.

Which panel has keyboard focus. Deprecated: use View.focus().

input_mode()

@type input_mode() :: :insert | :normal | :visual | :visual_line | :operator_pending

Vim mode for the input field when focused.

paste_block()

This type is deprecated. Use Panel.paste_block() instead.

A collapsed paste block. Deprecated: use Panel.paste_block().

prefix()

This type is deprecated. Use View.prefix() instead.

Active prefix key. Deprecated: use View.prefix().

search_match()

This type is deprecated. Use View.search_match() instead.

A search match. Deprecated: use View.search_match().

search_state()

This type is deprecated. Use View.search_state() instead.

Search state. Deprecated: use View.search_state().

t()

@type t() :: %MingaEditor.Agent.UIState{
  panel: MingaEditor.Agent.UIState.Panel.t(),
  view: MingaEditor.Agent.UIState.View.t()
}

Agent UI state wrapping Panel and View sub-structs.

thinking_level()

@type thinking_level() :: String.t()

Thinking level for models that support extended reasoning.

toast()

This type is deprecated. Use View.toast() instead.

A notification toast. Deprecated: use View.toast().

Functions

activate(state, windows, file_tree)

Activates the view, saving the current window layout.

cancel_search(state)

@spec cancel_search(t()) :: t()

Cancels search.

clear_baselines(state)

@spec clear_baselines(t()) :: t()

Clears all diff baselines.

clear_display(state, message_count)

@spec clear_display(t(), non_neg_integer()) :: t()

Clears the chat display without affecting conversation history.

Sets display_start_index to the given message count so the renderer skips all messages before this point. Scrolls to bottom.

clear_input(state)

@spec clear_input(t()) :: t()

Clears the input (after submission). Saves current text to history first.

clear_input_and_scroll(state)

@spec clear_input_and_scroll(t()) :: t()

Clears the input and scrolls to the bottom.

clear_prefix(state)

@spec clear_prefix(t()) :: t()

Clears any pending prefix.

clear_toasts(state)

@spec clear_toasts(t()) :: t()

Clears all toasts.

confirm_search(state)

@spec confirm_search(t()) :: t()

Confirms search (keeps matches for n/N navigation, disables input).

deactivate(state)

@spec deactivate(t()) ::
  {t(), MingaEditor.State.Windows.t() | nil,
   MingaEditor.State.FileTree.t() | nil}

Deactivates the view and returns the restored window layout.

delete_char(state)

@spec delete_char(t()) :: t()

Deletes the character before the cursor.

At the start of a line (col 0), joins with the previous line. At the start of the first line, no-op.

dismiss_help(state)

@spec dismiss_help(t()) :: t()

Dismisses the help overlay.

dismiss_toast(state)

@spec dismiss_toast(t()) :: t()

Dismisses the current toast.

engage_auto_scroll(state)

@spec engage_auto_scroll(t()) :: t()

Re-engages auto-scroll. Delegates to Minga.Editing.Minga.Editing.pin_to_bottom/1.

ensure_prompt_buffer(state)

@spec ensure_prompt_buffer(t()) :: t()

Ensures a prompt Buffer.Server is running. Starts one if prompt_buffer is nil or the process is dead.

get_baseline(view, path)

@spec get_baseline(t() | MingaEditor.Agent.UIState.View.t(), String.t()) ::
  String.t() | nil

Returns the baseline content for a path, or nil if none recorded.

grow_chat(state)

@spec grow_chat(t()) :: t()

Grows the chat panel width by one step (clamped at max).

history_next(state)

@spec history_next(t()) :: t()

Recalls the next (more recent) prompt from history.

history_prev(state)

@spec history_prev(t()) :: t()

Recalls the previous prompt from history.

input_cursor(panel)

Returns the input cursor position as {line, col}.

input_empty?(panel)

@spec input_empty?(t() | MingaEditor.Agent.UIState.Panel.t()) :: boolean()

Returns true if the input is empty (single empty line).

input_line_count(panel)

@spec input_line_count(t() | MingaEditor.Agent.UIState.Panel.t()) :: pos_integer()

Returns the number of input lines.

input_lines(panel)

@spec input_lines(t() | MingaEditor.Agent.UIState.Panel.t()) :: [String.t()]

Returns the input lines as a list of strings.

input_text(panel)

@spec input_text(t() | MingaEditor.Agent.UIState.Panel.t()) :: String.t()

Returns the raw input text (with placeholders, not substituted).

insert_char(state, char)

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

Inserts a character at the cursor position.

insert_newline(state)

@spec insert_newline(t()) :: t()

Inserts a newline at the cursor, splitting the current line.

insert_paste(state, text)

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

Inserts pasted text into the input.

For short pastes (fewer than 3 lines), the text is inserted directly into the buffer. For longer pastes, the text is stored in pasted_blocks and a placeholder token is inserted at the cursor position. The placeholder renders as a compact indicator (e.g. "󰆏 [pasted 23 lines]") but prompt_text/1 substitutes the full content when the prompt is submitted.

maybe_auto_scroll(state)

@spec maybe_auto_scroll(t()) :: t()

No-op. Streaming events call this; renderer handles pinning.

move_cursor_down(state)

@spec move_cursor_down(t()) :: t() | :at_bottom

Moves cursor down within the input. Returns :at_bottom if already on the last line.

move_cursor_up(state)

@spec move_cursor_up(t()) :: t() | :at_top

Moves cursor up within the input. Returns :at_top if already on the first line.

new()

@spec new() :: t()

Creates a new UIState with default sub-structs.

next_search_match(state)

@spec next_search_match(t()) :: t()

Moves to the next search match.

paste_block_index(line)

@spec paste_block_index(String.t()) :: non_neg_integer() | nil

Returns the paste block index for a placeholder line, or nil if not a placeholder.

paste_block_line_count(blocks, index)

@spec paste_block_line_count(t() | [paste_block()], non_neg_integer()) ::
  non_neg_integer()

Returns the line count for a paste block at the given index.

paste_placeholder?(line)

@spec paste_placeholder?(String.t()) :: boolean()

Returns true if the given line is a paste placeholder token.

prev_search_match(state)

@spec prev_search_match(t()) :: t()

Moves to the previous search match.

prompt_text(arg1)

@spec prompt_text(t() | MingaEditor.Agent.UIState.Panel.t()) :: String.t()

Returns the prompt text with paste placeholders substituted.

This is the text submitted to the LLM. Placeholder tokens are replaced with the full paste content from pasted_blocks.

push_toast(state, message, level)

@spec push_toast(t(), String.t(), :info | :warning | :error) :: t()

Pushes a toast.

record_baseline(state, path, content)

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

Records the baseline content for a file path (first edit only).

reset_split(state)

@spec reset_split(t()) :: t()

Resets the chat panel width to the configured default.

save_to_history(state)

@spec save_to_history(t()) :: t()

Saves the current input to prompt history (if non-empty).

scroll_down(state, amount)

@spec scroll_down(t(), non_neg_integer()) :: t()

Scrolls the content down. Delegates to Minga.Editing.Minga.Editing.scroll_down/2.

scroll_to_bottom(state)

@spec scroll_to_bottom(t()) :: t()

Pins chat to bottom. Delegates to Minga.Editing.Minga.Editing.pin_to_bottom/1.

scroll_to_top(state)

@spec scroll_to_top(t()) :: t()

Scrolls to top. Delegates to Minga.Editing.Minga.Editing.scroll_to_top/1.

scroll_up(state, amount)

@spec scroll_up(t(), non_neg_integer()) :: t()

Scrolls the content up. Delegates to Minga.Editing.Minga.Editing.scroll_up/2.

scroll_viewer_down(state, amount)

@spec scroll_viewer_down(t(), pos_integer()) :: t()

Scrolls the preview pane down by the given number of lines.

scroll_viewer_to_bottom(state)

@spec scroll_viewer_to_bottom(t()) :: t()

Scrolls the preview pane to a large offset (renderer clamps to actual content).

scroll_viewer_to_top(state)

@spec scroll_viewer_to_top(t()) :: t()

Scrolls the preview pane to the top (offset 0).

scroll_viewer_up(state, amount)

@spec scroll_viewer_up(t(), pos_integer()) :: t()

Scrolls the preview pane up by the given number of lines, clamped at 0.

search_input_active?(view)

@spec search_input_active?(t() | MingaEditor.Agent.UIState.View.t()) :: boolean()

Returns true if search input is being typed.

search_query(view)

@spec search_query(t() | MingaEditor.Agent.UIState.View.t()) :: String.t() | nil

Returns the search query, or nil if not searching.

search_saved_scroll(view)

@spec search_saved_scroll(t() | MingaEditor.Agent.UIState.View.t()) ::
  non_neg_integer() | nil

Returns the saved scroll position from before search started.

searching?(view)

@spec searching?(t() | MingaEditor.Agent.UIState.View.t()) :: boolean()

Returns true if search is active.

set_focus(state, focus)

@spec set_focus(t(), MingaEditor.Agent.UIState.View.focus()) :: t()

Switches focus to the given panel.

set_input_focused(state, bool)

@spec set_input_focused(t(), boolean()) :: t()

Sets the input focus state. Entering focus ensures the prompt buffer exists.

set_model_name(state, model)

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

Sets the model name.

set_prefix(state, prefix)

@spec set_prefix(t(), MingaEditor.Agent.UIState.View.prefix()) :: t()

Sets the pending prefix for multi-key sequences.

set_prompt_text(state, text)

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

Replaces the input content with the given text. Does not save to history.

set_provider_name(state, provider)

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

Sets the provider name.

set_scroll(state, offset)

@spec set_scroll(t(), non_neg_integer()) :: t()

Sets the scroll offset to an absolute value. Unpins from bottom.

set_search_matches(state, matches)

@spec set_search_matches(t(), [MingaEditor.Agent.UIState.View.search_match()]) :: t()

Sets search matches and resets current to 0.

set_thinking_level(state, level)

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

Sets the thinking level.

shrink_chat(state)

@spec shrink_chat(t()) :: t()

Shrinks the chat panel width by one step (clamped at min).

start_search(state, current_scroll)

@spec start_search(t(), non_neg_integer()) :: t()

Starts a search, saving the current scroll position.

tick_spinner(state)

@spec tick_spinner(t()) :: t()

Advances the spinner animation frame.

toast_visible?(view)

@spec toast_visible?(t() | MingaEditor.Agent.UIState.View.t()) :: boolean()

Returns true if a toast is currently visible.

toggle(state)

@spec toggle(t()) :: t()

Toggles panel visibility.

toggle_help(state)

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

Toggles the help overlay visibility.

toggle_paste_expand(state)

@spec toggle_paste_expand(t()) :: t()

Toggles expand/collapse on the paste block at the current cursor line.

update_preview(state, fun)

@spec update_preview(t(), (MingaEditor.Agent.View.Preview.t() ->
                       MingaEditor.Agent.View.Preview.t())) ::
  t()

Updates the preview state with the given function.

update_search_query(state, query)

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

Updates the search query string.