Enter to send·Shift+Enter new line
ChatInput( self, cwd: str | Path | None = None, history_file: Path
Vertical
cwd
str | Path | None
None
Current working directory for file completion
history_file
Path | None
Override path for persisted input history. Resolved by _default_history_path() when None.
_default_history_path()
image_tracker
MediaTracker | None
**kwargs
Any
{}
Border and prompt glyph change color per mode for immediate visual feedback.
Pause ordinary submissions while allowing editing and recovery commands.
Current input value.
Underlying TextArea widget.
TextArea
Compose the chat input layout.
Initialize components after mount.
Keep the resize handle aligned after layout changes.
Record the composer height at the start of a drag.
Apply a drag delta to the composer height.
Drop the drag baseline so a later delta cannot reuse it.
Update top-border hover feedback.
Expand the composer, or drop a manual height back to automatic.
Update file completion to use a new cwd.
Re-roots the file controller and schedules a background cache warm so the project-root walk runs off the event loop.
Update the slash command controller's command list.
Called by the app after discovering skills to merge static commands with dynamic /skill: entries.
/skill:
Set, suppress, or restore a runtime slash-command argument hint.
Detect input mode and update completions.
Switch input mode for a mode trigger typed at the start of the input.
Handles the switch before TextArea inserts the character so the trigger (!, !!, /) never flashes on screen for a frame before the change handler would strip it.
!
!!
/
Return the active @@ query for full-picker escalation.
@@
Replace the active @@ query with a durable thread reference.
Relay typing activity to the app as ChatInput.Typing.
ChatInput.Typing
Handle text submission.
Unless submission is paused, the app layer decides whether to process immediately or queue based on agent status.
Handle history previous request.
Handle history next request.
Apply an already-parsed paste payload to the input.
Callers apply a payload through this method rather than posting it as a message so it reaches the document synchronously. Textual appends a posted message to the tail of the receiving widget's FIFO queue, so a keystroke the terminal already delivered would be handled first and land ahead of the paste.
Skip mode-prefix detection for the next text change.
Used when inserting text that legitimately starts with a mode trigger, so the change handler does not consume that character. Shares the guard with _strip_mode_prefix, which reports a guard left uncleared by a missed change event.
_strip_mode_prefix
Handle paste text from app-level routing when input is not focused.
When the text area is mounted, the paste is always consumed: file paths are attached as images, large text is collapsed into a placeholder, and remaining plain text is inserted directly.
Handle key events for completion navigation.
Post mode changed message and update prompt indicator.
The prompt glyph update is scheduled for the next message-loop turn so callers which also schedule popup work can coalesce both visual changes before the next paint.
Focus the input field.
Set the input value and place the cursor at the end of the text.
Refresh and return submitted prompts in newest-first order.
Describe why the last prompt refresh came back empty, if it failed.
Insert text at the current cursor through the undoable edit path.
Leaves the cursor after the inserted text and keeps it visible once the chat input reflows.
Replace the draft through the undoable edit path.
Append text after the draft through the undoable edit path.
Closes an open prompt search first: the search panel hides the input row, so the text would otherwise land out of view.
Open the inline prompt search, or escalate an open one to the modal.
First call shows the inline panel with a fresh prompt snapshot, seeds its filter from the current draft, and saves that draft for cancel-restore; a call while the panel is already open means the second Ctrl+R tier.
Return the modal filter and close any open inline panel.
An active inline search supplies its current query. When autocomplete sends Ctrl+R directly to the modal tier, the current chat input is the query instead.
Close the search, restoring the draft, on empty-query Backspace.
Filter prompts as the query input's text changes.
Insert the selected prompt when the query input is submitted.
Select a clicked prompt row; Enter is still required to insert.
Clear the draft, keeping it restorable via undo (ctrl+z).
Handle clicks on the [ X ] / [ COPY ] input buttons.
[ X ]
[ COPY ]
Enable or disable the input widget.
Toggle input focus state (e.g., unfocus while agent is working).
Set the input cursor's visual style.
Toggle the input's cursor blink without changing focus.
Exit the current input mode (command/shell) back to normal.
Dismiss completion: clear view and reset controller state.
Render completion suggestions in the popup.
Clear/hide the completion popup.
Handle click on a completion option.
Replace text in the input field.
Message sent when input is submitted.
Message sent when input mode changes.
Posted when the user presses a printable key or backspace in the input.
The app uses this to delay approval widgets while the user is actively typing, preventing accidental key presses (e.g. y, n) from triggering approval decisions.
y
n
Chat input widget with prompt, multi-line text, autocomplete, and history.
Features:
config.newline_shortcut
Optional tracker for attached images
Additional arguments for parent