Prompt UI: open, key handling, and close.
Manages a single-line text input prompt in the minibuffer area. Extensions
use this for collecting free-form text input (capture titles, rename targets,
search queries). All functions are pure state -> state transformations.
Prompts and pickers are mutually exclusive: opening a prompt closes any
active picker. The replacement is handled automatically by
MingaEditor.State.ModalOverlay.open/3.
Usage
# Open a prompt
state = PromptUI.open(state, MyCapturePrompt)
state = PromptUI.open(state, MyCapturePrompt, default: "pre-filled")
# Keys are routed here when prompt is active
{state, action} = PromptUI.handle_key(state, key, mods)
Summary
Functions
Closes the prompt without calling any handler callback.
Handles a key event while the prompt is active.
Opens a text input prompt with the given handler module.
Returns true if a prompt is currently open.
Renders the prompt overlay into draw commands and a cursor position.
Returns the label and current text for rendering.
Applies fun to the current PromptState inside the modal and writes
back via ModalOverlay.transition, keeping the modal sum type and
consistency check in sync.
Types
@type action() :: nil
Optional action the GenServer should dispatch after handle_key.
@type state() :: MingaEditor.State.t()
Internal editor state.
Functions
Closes the prompt without calling any handler callback.
@spec handle_key(state(), non_neg_integer(), non_neg_integer()) :: {state(), action()}
Handles a key event while the prompt is active.
Returns {state, action} where action is always nil (prompts don't
produce deferred actions like the picker does).
Opens a text input prompt with the given handler module.
Replaces any active modal (the gate's replacement policy handles the
picker → prompt transition). An optional :default value pre-fills the
input field. An optional :context map is stored for the handler to
read.
Options
:default— pre-filled text (default:""):context— arbitrary map passed through to the handler (default:nil)
Returns true if a prompt is currently open.
@spec render(state(), MingaEditor.Viewport.t()) :: {[MingaEditor.DisplayList.draw()], {non_neg_integer(), non_neg_integer()} | nil}
Renders the prompt overlay into draw commands and a cursor position.
Returns {draws, cursor} where draws is a list of display list
draw commands and cursor is a %Cursor{} for the input position.
Returns {[], nil} when no prompt is active.
@spec render_data(state()) :: {String.t(), String.t(), non_neg_integer()}
Returns the label and current text for rendering.
Returns {label, text, cursor_col} where cursor_col is the column
within the text (not including the label width).
@spec update_prompt(state(), (MingaEditor.State.Prompt.t() -> MingaEditor.State.Prompt.t())) :: state()
Applies fun to the current PromptState inside the modal and writes
back via ModalOverlay.transition, keeping the modal sum type and
consistency check in sync.