Keybindings
All keyboard shortcuts can be customized via~/.atomic/agent/keybindings.json. Each action can be bound to one or more keys.
The config file uses the same namespaced keybinding ids that Atomic uses internally and that extension authors use in keyHint() and injected keybindings managers.
Older configs using pre-namespaced ids such as cursorUp or expandTools are migrated automatically to the namespaced ids on startup.
After editing keybindings.json, run /reload in Atomic to apply the changes without restarting the session.
Key Format
modifier+key where modifiers are ctrl, shift, alt, or super (combinable) and keys are:
- Letters:
a-z - Digits:
0-9 - Special:
escape,esc,enter,return,tab,space,backspace,delete,insert,clear,home,end,pageUp,pageDown,up,down,left,right - Function:
f1-f12 - Symbols:
`,-,=,[,],\,;,',,,.,/,!,@,#,$,%,^,&,*,(,),_,+,|,~,{,},:,<,>,?
ctrl+shift+x, alt+ctrl+x, ctrl+shift+alt+x, ctrl+super+x, ctrl+1, etc. super depends on terminal support.
All Actions
TUI Editor Cursor Movement
The dedicated history actions always change history entries, regardless of the cursor position in a multiline prompt. Explicit history bindings take precedence over ordinary application action handlers while the main editor is focused, so binding
tui.editor.historyPrevious to ctrl+p or tui.editor.historyNext to ctrl+n overrides those app actions without changing the same keys in selectors.
TUI Editor Deletion
TUI Input
TUI Kill Ring
TUI Clipboard and Selection
TUI Fullscreen Viewport
Interactive sessions always use this fullscreen viewport for the primary transcript scroll region. Mouse-wheel input scrolls the region under the pointer, falling back to the transcript over the fixed editor/status/footer dock. Clicking an OSC 8 hyperlink opens it in the default handler; the jump-to-bottom indicator’s internal OSC 8 link returns the focused transcript surface to its live end, including an attached workflow stage chat. Dragging with the primary mouse button selects text and copies it to the clipboard. See Terminal setup for terminal-specific mouse and trackpad behavior. Fullscreen text selection comes from the installed pi-tui 0.84.2 renderer. Drag with the primary button to select characters; double-click selects a word and triple-click selects a line. Focus changes and non-drag clicks clear transient selection state, preventing a stale highlight from appearing. A drag release reported with the generic SGR button code also ends the selection. The renderer also reduces mouse tracking in tmux, Zellij, and GNU Screen. Fullscreen transcript bindings take precedence over editor bindings while the main editor has focus. The default unmodified navigation keys therefore control the transcript, while theirctrl variants continue to control the editor. When a fullscreen overlay or inline custom component has focus, Atomic sends matching viewport bindings to that component first. Returning true keeps the key local. For an in-process component, returning false, undefined, or void lets transcript scrolling handle it. A remote component’s correlated reply falls through on false, failure, or timeout; undefined after disposal is dropped because that component no longer owns focus.
This routing remains configurable through the ordinary action bindings. For example,
"tui.altScreen.pageUp": "ctrl+pageUp" makes pageUp control the editor and ctrl+pageUp control the transcript in fullscreen mode. Bind tui.altScreen.halfPageUp and tui.altScreen.halfPageDown for half-page steps, or tui.altScreen.lineUp and tui.altScreen.lineDown for single-line steps, while keeping the full-page bindings. Setting "tui.altScreen.pageUp": [] disables that transcript shortcut entirely. User bindings replace the defaults for that action.
When a fullscreen overlay or inline custom component owns focus, it receives matching pageUp, pageDown, home, end, and custom tui.altScreen.* bindings before transcript scrolling. Its handler returns true when it consumes the key; an unhandled result lets transcript scrolling proceed. Remote components receive a correlated reply and have a bounded fallback if the engine stalls. Mouse-wheel and click sequences follow the same focused-component route, so workflow graphs and stage chats can consume them before unhandled events fall through to the fullscreen viewport.
The blocking ask_user_question dialog is pinned to the bottom of the screen as an overlay rather than measured into the layout, so opening it does not shrink the transcript viewport or the page step: pageUp, pageDown, home, end, and the wheel move by the same amount and reach every line of the scrollback, including the newest ones, in the strip that stays visible above the dialog. Those transcript actions still work while the Notes editor is open. Notes keeps ordinary text and edit actions, including the default ctrl+home and ctrl+end; a key moves the transcript instead only when configured for a tui.altScreen.* action. The dialog is bounded so the visible strip survives on a short terminal, and the active questionnaire row stays visible inside the bound as you move through single-select choices, multi-select choices, Next, Submit, Cancel, and inline inputs. It keeps its own arrow, enter, tab, space, esc, click, and selection input.
Atomic does not ship a find-in-transcript shortcut. The four
tui.altScreen.search* actions remain in the keybinding table so an existing keybindings.json still validates, but they have no default keys and do nothing.
On Windows, pressing the secondary mouse button in fullscreen pastes text from the system clipboard into the focused component.
Application
When
app.clipboard.pasteImage finds text rather than an image, Atomic inserts that clipboard text into the editor instead of reporting an image-paste failure.
On macOS, native Cmd+V also pastes a clipboard image when the copy was image-only. Terminals may deliver that as an empty bracketed-paste event or (with Kitty keyboard protocol, e.g. Ghostty) as super+v. Text under Cmd+V still goes through normal terminal paste when the terminal sends a paste event. Cmd+V is not a configurable Atomic keybinding.
Inside tmux on macOS, Ctrl+V is the reliable image-paste shortcut; native Cmd+V depends on terminal forwarding. VS Code’s terminal may forward the empty bracketed-paste route through tmux, while Ghostty may not forward its Kitty super+v route through tmux. This is terminal forwarding behavior, not an Atomic defect.
When the clipboard has both text and an image, behavior depends on the terminal: empty-paste terminals may insert the text on Cmd+V, while Kitty-protocol terminals that deliver super+v go through the image path (same preference as Ctrl+V). Ctrl+V always prefers the image. Apple Terminal may send nothing for image-only paste; use Ghostty/iTerm/Kitty or Ctrl+V in that case.
A held paused queue by itself is idle for Ctrl+C handling. After an interruption settles, the next Ctrl+C clears the editor without releasing or dequeuing the hold, and a second quick idle press exits normally.
In interactive sessions the agent runs in a supervised engine child (see Extensions). Escape there requests the engine’s cooperative cancellation and waits for it with no deadline; it never terminates or replaces the engine.
Both keys are recognized by their physical identity, not by the configured app.clear action, so rebinding app.clear cannot make Escape stop the engine or take the host route away from Ctrl+C.
Ctrl+C is the host’s escape hatch whenever an engine-owned ctx.ui.custom() component or overlay holds input: those forward every key to the engine, so a component that never resolves would swallow Ctrl+C. Which component gets the press is decided per mount, in this order:
- If the engine is provably not answering, the first press terminates and replaces it — a wedged child cannot run the component’s own handler either. “Not answering” means the watchdog has declared it unresponsive, a cooperative abort has gone unanswered past the same one-second threshold, a replacement has been waiting for readiness past it, or a replacement failed. A failed replacement keeps Ctrl+C armed so another press can try again; Atomic never retries on its own.
- Otherwise, if the component declared
handlesCtrlCwhen it was mounted, it receives the press and keeps its own Skip, Close, or cancel behavior. The bundled workflow surfaces declare it. If the same component is still holding input on the next press, that press closes it. - Otherwise the first press closes that one component, exactly as if it had been cancelled: its
ctx.ui.custom()promise resolves withundefined, the editor comes back, and the engine — along with everything else it has mounted or is running — is left alone.
tui.select.cancel still keeps Ctrl+C as local cancel inside host-native selectors, dialogs, input forms, and session pickers.
Sessions
Models and Thinking
Display and Message Queue
Tree Navigation
Scoped Models Selector
Used inside the scoped models selector (opened via/scoped-models).
Custom Configuration
Create~/.atomic/agent/keybindings.json:
app.suspend has no default binding because Windows terminals do not support Unix job control. If you bind it manually, Atomic shows a status message instead of suspending. In WSL, the normal Linux ctrl+z/fg behavior still applies.