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
Which panel has keyboard focus. Deprecated: use View.focus().
Vim mode for the input field when focused.
A collapsed paste block. Deprecated: use Panel.paste_block().
Active prefix key. Deprecated: use View.prefix().
A search match. Deprecated: use View.search_match().
Search state. Deprecated: use View.search_state().
Agent UI state wrapping Panel and View sub-structs.
Thinking level for models that support extended reasoning.
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.
Pushes a toast.
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
@type focus() :: MingaEditor.Agent.UIState.View.focus()
Which panel has keyboard focus. Deprecated: use View.focus().
@type input_mode() :: :insert | :normal | :visual | :visual_line | :operator_pending
Vim mode for the input field when focused.
@type paste_block() :: MingaEditor.Agent.UIState.Panel.paste_block()
A collapsed paste block. Deprecated: use Panel.paste_block().
@type prefix() :: MingaEditor.Agent.UIState.View.prefix()
Active prefix key. Deprecated: use View.prefix().
@type search_match() :: MingaEditor.Agent.UIState.View.search_match()
A search match. Deprecated: use View.search_match().
@type search_state() :: MingaEditor.Agent.UIState.View.search_state()
Search state. Deprecated: use View.search_state().
@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.
@type thinking_level() :: String.t()
Thinking level for models that support extended reasoning.
@type toast() :: MingaEditor.Agent.UIState.View.toast()
A notification toast. Deprecated: use View.toast().
Functions
@spec activate(t(), MingaEditor.State.Windows.t(), MingaEditor.State.FileTree.t()) :: t()
Activates the view, saving the current window layout.
Cancels search.
Clears all diff baselines.
@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.
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).
@spec deactivate(t()) :: {t(), MingaEditor.State.Windows.t() | nil, MingaEditor.State.FileTree.t() | nil}
Deactivates the view and returns the restored window layout.
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.
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.
@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.
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.
@spec input_cursor(t() | MingaEditor.Agent.UIState.Panel.t()) :: {non_neg_integer(), non_neg_integer()}
Returns the input cursor position as {line, col}.
@spec input_empty?(t() | MingaEditor.Agent.UIState.Panel.t()) :: boolean()
Returns true if the input is empty (single empty line).
@spec input_line_count(t() | MingaEditor.Agent.UIState.Panel.t()) :: pos_integer()
Returns the number of input lines.
@spec input_lines(t() | MingaEditor.Agent.UIState.Panel.t()) :: [String.t()]
Returns the input lines as a list of strings.
@spec input_text(t() | MingaEditor.Agent.UIState.Panel.t()) :: String.t()
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.
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.
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.
@spec new() :: t()
Creates a new UIState with default sub-structs.
Moves to the next search match.
@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.
@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.
Returns true if the given line is a paste placeholder token.
Moves to the previous search match.
@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.
Pushes a toast.
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).
@spec scroll_down(t(), non_neg_integer()) :: t()
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.
@spec scroll_up(t(), non_neg_integer()) :: t()
Scrolls the content up. Delegates to Minga.Editing.Minga.Editing.scroll_up/2.
@spec scroll_viewer_down(t(), pos_integer()) :: t()
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).
@spec scroll_viewer_up(t(), pos_integer()) :: t()
Scrolls the preview pane up by the given number of lines, clamped at 0.
@spec search_input_active?(t() | MingaEditor.Agent.UIState.View.t()) :: boolean()
Returns true if search input is being typed.
@spec search_query(t() | MingaEditor.Agent.UIState.View.t()) :: String.t() | nil
Returns the search query, or nil if not searching.
@spec search_saved_scroll(t() | MingaEditor.Agent.UIState.View.t()) :: non_neg_integer() | nil
Returns the saved scroll position from before search started.
@spec searching?(t() | MingaEditor.Agent.UIState.View.t()) :: boolean()
Returns true if search is active.
@spec set_focus(t(), MingaEditor.Agent.UIState.View.focus()) :: t()
Switches focus to the given panel.
Sets the input focus state. Entering focus ensures the prompt buffer exists.
Sets the model name.
@spec set_prefix(t(), MingaEditor.Agent.UIState.View.prefix()) :: t()
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.
@spec set_scroll(t(), non_neg_integer()) :: t()
Sets the scroll offset to an absolute value. Unpins from bottom.
@spec set_search_matches(t(), [MingaEditor.Agent.UIState.View.search_match()]) :: t()
Sets search matches and resets current to 0.
Sets the thinking level.
Shrinks the chat panel width by one step (clamped at min).
@spec start_search(t(), non_neg_integer()) :: t()
Starts a search, saving the current scroll position.
Advances the spinner animation frame.
@spec toast_visible?(t() | MingaEditor.Agent.UIState.View.t()) :: boolean()
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.
@spec update_preview(t(), (MingaEditor.Agent.View.Preview.t() -> MingaEditor.Agent.View.Preview.t())) :: t()
Updates the preview state with the given function.
Updates the search query string.