Keyboard shortcuts
A terminal agent’s input line looks like a text box and behaves like a readline-descended line editor. Ctrl+A doesn’t select all, it moves to the start of the line. Ctrl+X doesn’t cut. Nothing errors - you just get a different feature, silently.
Everything below was read from each tool’s own source, binary or docs, and is dated. 489 bindings, 6 tools, 8 surfaces.
The test: if you keep reaching for the same familiar key and the agent does something else, look up the binding by intent before changing your terminal or editor.
Everything on this page - the tables, the collisions, the full reference - filters to what you pick above.
The tasks you’ll actually do
Section titled “The tasks you’ll actually do”| Task | Claude Code | Codex | OpenCode | Pi | Cursor IDE | Cursor | Copilot IDE | Copilot |
|---|---|---|---|---|---|---|---|---|
| Stop the agent | Esc | Esc | Esc | Esc | - | - | - | Esc |
| Newline without submitting | Ctrl+J | Ctrl+J | Ctrl+J | Ctrl+J | - | Ctrl+J | - | - |
| Newline (alternative) | - | Shift+Enter | Shift+Enter | Shift+Enter | - | Shift+Enter | - | Shift+Enter |
| Paste an image | Ctrl+V | Ctrl+V | - | Ctrl+V | - | - | - | - |
| Delete to line start | Ctrl+U | Ctrl+U | Ctrl+U | Ctrl+U | - | - | - | Ctrl+U |
| Delete to line end | Ctrl+K | Ctrl+K | Ctrl+K | Ctrl+K | Ctrl+K | - | - | Ctrl+K |
| Delete previous word | Ctrl+W | Ctrl+W | Ctrl+W | Ctrl+W | Ctrl+W | - | - | Ctrl+W |
| Paste back what you deleted | Ctrl+Y | Ctrl+Y | - | Ctrl+Y | - | - | - | - |
| Jump to line start | Ctrl+A | Ctrl+A | Ctrl+A | Ctrl+A | - | - | - | Ctrl+A |
| Jump to line end | Ctrl+E | Ctrl+E | Ctrl+E | Ctrl+E | Ctrl+E | - | - | Ctrl+E |
| Search past prompts | Ctrl+R | Ctrl+R | - | - | - | - | - | Ctrl+R |
| Open $EDITOR | - | Ctrl+G | - | Ctrl+G | - | - | - | Ctrl+X then e |
| Cycle mode | Shift+Tab | Shift+Tab | Shift+Tab | Shift+Tab | Shift+Tab | Shift+Tab | - | Shift+Tab |
| Quit | Ctrl+D | Ctrl+D | Ctrl+D | Ctrl+D | - | Ctrl+D | - | Ctrl+D |
| Suspend to shell | Ctrl+Z | Ctrl+Z | Ctrl+Z | Ctrl+Z | - | - | - | Ctrl+Z |
Three things worth pulling out of that table, if you turn all six on:
Escis the stop key in most of the terminal agents here. NotCtrl+C. This is the strongest convergence in the set - but it holds for the CLI surfaces, not the editor ones, and not for every CLI: Copilot CLI needsEsctwice to interrupt a running turn, and Cursor’s published CLI docs describe a secondEnteras the interrupt instead of namingEsc. Inside an IDE,Escis already spoken for: in Cursor it can accept a suggested terminal command, and in VS Code it dismisses an inline suggestion. Check which surface you are actually typing into.Shift+Tabcycles a mode everywhere, but not the same mode - permission modes in Claude Code, the Default or Plan collaboration mode in Codex, the agent in OpenCode, thinking level in Pi, agent modes in Cursor, session modes in Copilot CLI.Ctrl+Jinserts a newline in every TUI agent here;Shift+Entersometimes can’t.Shift+Enterdepends on your terminal being able to transmit it.Ctrl+Jis the newline character, so it survives the trip. In Cursor and Copilot the newline is the host editor’s to define, not the agent’s. IfShift+Enterkeeps submitting, that’s your terminal, not the agent.
Keys that don’t mean what you think
Section titled “Keys that don’t mean what you think”| Key | You expect | What it actually does |
|---|---|---|
| ctrl+k can lose work | In stock VS Code, Cmd/Ctrl+K is a chord prefix (e.g. Cmd+K Cmd+S for Keyboard Shortcuts, Cmd+K Cmd+C to comment a block, Cmd+K Cmd+F to format selection, etc.) - pressing it alone does nothing visible, it just arms the second key. |
|
| ctrl+a silently different | Select all text in the current field |
|
| ctrl+c can lose work | Copy the current selection to the clipboard |
|
| ctrl+d can lose work | No universal GUI meaning; closest common expectation is 'do nothing' or, in a browser, 'bookmark this page' |
|
| ctrl+r silently different | Reload the page, or redo the last undone action, in most GUI apps and browsers |
|
| ctrl+w can lose work | close tab/window (browsers, many GUI apps) |
|
| ctrl+z can lose work | Undo the last action |
|
| ctrl+v silently different | Paste clipboard contents as plain text at the cursor |
|
| ctrl+x silently different | Cut the current selection to the clipboard |
|
| tab silently different | Inside any text input/textarea (including VS Code's own webview panels), Tab conventionally either inserts a tab character or moves focus to the next control - it does not change which message is displayed. |
|
| ctrl+b silently different | toggle the browser's bookmarks bar (most browsers) |
|
| ctrl+i silently different | Cmd/Ctrl+I has no default binding in stock VS Code, but is widely muscle-memorized by GitHub Copilot users as 'open Copilot Inline Chat' (an inline, in-editor AI prompt at the cursor position). |
|
| ctrl+o silently different | open a file |
|
| ctrl+t silently different | new tab (browser) |
|
| ctrl+y silently different | In the classic emacs/readline convention this CLI otherwise follows for Ctrl+A/E/U/K/W/B/F/H, Ctrl+Y is 'yank' - paste back the text most recently deleted by Ctrl+U, Ctrl+K, or Ctrl+W |
|
| escape silently different | Escape is a near-universal 'cancel/dismiss' convention across editors and OSes, and is commonly used to close dialogs and popups. |
|
Ctrl+Z is the one that generates panic. It is not a crash and your session isn’t gone - the process is stopped in the background. Type fg to bring it back.
Explore it
Section titled “Explore it”Pick a tool, hold a modifier, click a key. Or search by what you’re trying to do - including the key you’d wrongly reach for, so typing ctrl+x or “select all and delete” lands on the correction.
Three things that explain most surprises
Section titled “Three things that explain most surprises”The kill ring is not your clipboard. Ctrl+U and Ctrl+Y are a matched pair inside the editor. Text moved that way cannot be pasted into your browser. To get text out, use your terminal emulator’s own selection and copy. Some tools bind their own key for it: Pi copies the last assistant message with Ctrl+X, Codex copies the last response with Ctrl+O.
Context decides, not the key. In OpenCode, Ctrl+A, Ctrl+D, Ctrl+F and the arrows each appear against several actions and don’t conflict: a managed text-area layer is active only while the prompt has focus and wins there, and the history handler declines the keystroke unless the cursor is already at the buffer edge. When a shortcut “doesn’t work,” focus is usually somewhere you didn’t think it was.
You can rebind almost all of it, by action id. Four tools ship a remappable keymap: Claude Code (~/.claude/keybindings.json), Codex (tui.keymap.*, with an in-app /keymap picker), OpenCode (tui.json, or cli.json in OpenCode 2; ~140 actions plus a leader key), Pi (~/.pi/agent/keybindings.json). Default keys move between releases; action names rarely do, so write down the action. This also reveals capability no shortcut list shows: Codex ships toggle_vim_mode and toggle_fast_mode as real actions with no default key.
Full reference
Section titled “Full reference”Every binding we have, grouped by where it applies. rl marks bindings inherited from readline rather than implemented by the tool. The last column is how the fact was established: source (read from the implementation), first-hand (run locally), docs.
Claude Code terminal
Input line
| Keys | Does | Src |
|---|---|---|
| ctrl+l | Force a full terminal redraw, preserving input and conversation. Use it to recover a garbled or partially blank display. Cmd+K does the same where the terminal passes it through. chat:clearInput | source |
| ctrl+r | Open reverse history search over previous prompts. rl history:search | source |
| ctrl+s | Stash the current prompt text and clear the input. Pressed again on an empty prompt, restores the stashed text, cursor position, pasted content, and input mode (a stashed ! shell command returns in shell mode). chat:stash | source |
| ctrl+v ctrl+v (or cmd+v in iTerm2) macOS | Paste an image from the clipboard, inserting a `[Image #N]` chip at the cursor. chat:imagePaste | source |
| esc esc | Double-tap: if the prompt has text, clears it and saves the draft to history (Up recalls it). If the prompt is empty, opens the rewind menu to restore/summarize code and conversation from an earlier point. | docs |
| shift+tab | Cycle permission modes: default (labeled Manual), acceptEdits, plan, and, when available, bypassPermissions and then auto. From auto the first press switches to default. chat:cycleMode | source |
| option+p (mac) / alt+p (win/linux) option+p / meta+p macOS | Open the model picker. chat:modelPicker | source |
| option+t (mac) / alt+t (win/linux) option+t / meta+t macOS | Toggle extended thinking mode. No effect on Opus 5.5, Sonnet 5.5, Haiku 5.5, or the Fable models, which always use extended thinking. chat:thinkingToggle | source |
| option+o (mac) / alt+o (win/linux) option+o / meta+o macOS | Toggle fast mode. chat:fastMode | source |
| enter | Submit the message. chat:submit | source |
| ctrl+j | Insert a newline without submitting. Works in any terminal without configuration. chat:newline | source |
| ctrl+_ / ctrl+shift+- | Undo last input edit - restores the previous input text and cursor position. rl chat:undo | source |
| ctrl+g / ctrl+x ctrl+e | Open the current prompt in your default text editor ($VISUAL/$EDITOR). rl chat:externalEditor | source |
| ctrl+x ctrl+k | Stop all running background subagents in this session and turn off artifact auto-replies for the rest of it. Press twice within 3 seconds to confirm; works while a background subagent's permission prompt is open. chat:killAgents | source |
| ctrl+a | Move cursor to the start of the current logical line (in multiline input). rl | docs |
| ctrl+e | Move cursor to the end of the current logical line (in multiline input). rl | docs |
| ctrl+k | Delete from cursor to end of line. Stores deleted text for pasting (yank buffer). rl | docs |
| ctrl+u | Delete from cursor to line start. Stores deleted text for pasting; repeat to clear across lines in multiline input. rl | docs |
| ctrl+w | Delete back to the previous whitespace. One press removes a whole path or --flag=value. Stores deleted text for pasting. To delete only the previous word, use Option+Delete on macOS or Ctrl+Backspace on Windows. rl | docs |
| ctrl+y | Paste (yank) text previously deleted with Ctrl+K, Ctrl+U, or Ctrl+W. rl | docs |
| alt+y (after ctrl+y) option+y (after ctrl+y, requires Option-as-Meta) macOS | Cycle through previously deleted (killed) text after a yank. rl | docs |
| alt+b option+b (requires Option-as-Meta) macOS | Move cursor back one word. rl | docs |
| alt+f option+f (requires Option-as-Meta) macOS | Move cursor forward one word. rl | docs |
| up / down (or ctrl+p / ctrl+n) | Move cursor within a multi-row prompt first; once the cursor is on the first/last visual row, navigates command history instead. While messages are queued, Up from the first row takes them back into the input box instead. history:previoushistory:next | source |
| ? | On an empty prompt, toggles the shortcut help panel. With text already in the input, types a literal '?' instead. | docs |
| tab | Accept the current autocomplete suggestion (or place a prompt suggestion into the input). autocomplete:accept | source |
| / | At the start of input, opens the command/skill menu. | docs |
| ! | At the start of input, enters shell mode - runs a command directly and adds its output to context. | docs |
| @ | Trigger file path autocomplete/mention. | docs |
| :name: | Type a full :shortcode: to insert an emoji, or 2+ chars for a suggestion popup. | docs |
| space (hold or tap) space macOS | Voice dictation push-to-talk (hold to record, or /voice tap for tap-to-toggle). voice:pushToTalk | docs |
| esc / ctrl+[ | In vim editing mode: switch from INSERT or VISUAL back to NORMAL mode. Ctrl+[ does the same. | docs |
| i / I / a / A / o / O / v / V | Vim NORMAL-mode entry points into INSERT or VISUAL modes (insert before/at-line-start/after/at-line-end cursor, open line below/above, char-wise/line-wise visual select). | docs |
| h j k l, space, w e b, 0 $ ^, gg G, f/F/t/T{char}, ; , % same macOS | Vim NORMAL-mode navigation motions (left/down/up/right, Space moves right, word/end/back-word, line start/end/first-non-blank, buffer start/end, find-char motions, repeat motion, % jumps to the matching bracket). / opens reverse history search, same as Ctrl+R. | docs |
| x, r{char}, dd, D, dw/de/db, df/dt{char}, dj/dk, dgg/dG, d0/c0/y0, d%/c%/y%, cc, C, cw/ce/cb, s, S, yy/Y, yw/ye/yb, p, P, >>, <<, J, u, . same macOS | Vim NORMAL-mode editing operators (delete char/line/to-end/word variants, replace char, delete to a character or across lines, delete/change/yank to line start or through a bracket, change line/to-end/word variants, substitute char/line, yank line/word variants, paste after/before, indent/dedent, join lines, undo, repeat last change). | docs |
| iw/aw, iW/aW, i"/a", i'/a', i(/a(, i[/a[, i{/a{ same macOS | Vim text objects (inner/around word, WORD, quotes, brackets) usable with d/c/y operators. | docs |
| ctrl+enter / ctrl+x ctrl+s | Send your queued messages (and your draft with them) right away instead of waiting for the turn to end. If Claude is running shell commands or subagents they move to the background; if it is only writing a response, the turn is interrupted. In terminals that do not report extended keys Ctrl+Enter arrives as plain Enter; Ctrl+X Ctrl+S works everywhere. chat:sendNow | source |
| ctrl+x enter | Submit the message marked to wait its turn: while Claude is working, Claude Code queues it and never interrupts the turn. Unlike plain Enter, it submits the draft even while an autocomplete suggestion is highlighted. chat:queueSubmit | source |
| ctrl+x ctrl+a | Collapse the band above the prompt (where mods draw buttons, inputs and selects) to a one-row hint, or expand it again. abovePrompt:toggle | source |
| ctrl+x tab | Move keyboard focus into the band above the prompt, then to each open mod pane, and from the last pane back to the prompt. abovePrompt:focus | source |
| left (empty prompt) | On an empty prompt, background the session and open agent view with its row selected. In an attached background session the same key detaches back to agent view. If you just deleted the last of the prompt text or browsed history, a second press confirms. | docs |
| ctrl+s (history search) | In the fullscreen history-search dialog opened by Ctrl+R, cycle the search scope through this session, this project, and all projects. The classic inline search always searches all projects. historySearch:cycleScope | source |
| alt+d option+d / meta+d macOS | Delete to the end of the current word (or the end of the next word when the cursor is between words). Stores deleted text for pasting. rl | docs |
| option+delete (mac) / ctrl+backspace (win/linux) option+delete / ctrl+backspace macOS | Delete only the previous word (stops at punctuation), unlike Ctrl+W which removes back to the previous whitespace. rl | docs |
| command:<name> (custom binding) | Bind any key in the Chat context to run a slash command, for example `"meta+g": "command:compact"` runs /compact. command:<name> | docs |
| v / V (visual mode) | Vim visual mode: v selects character-wise, V line-wise. Motions extend the selection; d or x delete, y yank, c or s change, p replace with register, r{char} replace every selected char, ~ u U toggle/lower/upper case, > < indent/dedent, J join, o swap cursor and anchor, text objects select, v/V toggle or exit. Block-wise Ctrl+V is not supported. | docs |
Anywhere
| Keys | Does | Src |
|---|---|---|
| ctrl+c | Interrupt a running operation. If nothing is running, first press clears the prompt input; a second press exits Claude Code. After clearing, press Up on the empty prompt to bring the draft back (v2.1.288 or later); the ten most recent cleared drafts stay reachable with Up after you send a message or command (v2.1.292 or later). app:interrupt | source |
| ctrl+d | Exit Claude Code. First press shows a confirmation hint, second press within 800ms exits. When the prompt has text, deletes the character after the cursor instead (classic readline forward-delete). app:exit | source |
| ctrl+o | Toggle the verbose transcript viewer (detailed tool usage/execution with timestamps and model per message). app:toggleTranscript | source |
| ctrl+t | Toggle visibility of Claude's to-do checklist (not the /tasks background-task view). app:toggleTodos | source |
| ctrl+b / ctrl+x ctrl+b | Background the currently running Bash command, agent task, or skill shell command. Also moves a subagent's running command to the background. Tmux users press twice, or use the Ctrl+X Ctrl+B chord. task:background | source |
| ctrl+z | Suspend Claude Code to the shell (Unix only). Run `fg` to resume. | docs |
| esc | Interrupt Claude mid-turn (stop the current response/tool call, keeping work done so far; queued messages are then sent), or close an open dialog (e.g. permission prompt) without interrupting. While a footer item is selected, Esc deselects it instead of interrupting. On a permission prompt, Esc declines the action. chat:cancel | source |
Transcript / pager
| Keys | Does | Src |
|---|---|---|
| q / ctrl+c / esc | Exit the transcript viewer. transcript:exit | source |
| { / } | Jump to the previous/next user prompt in the transcript, like vim paragraph motion. | docs |
| [ | Write the full conversation to the terminal's native scrollback so Cmd+F/tmux copy mode can search it. | docs |
| v | Write the conversation to a temp file and open it in $VISUAL/$EDITOR. | docs |
| ? | Show the full shortcut reference panel inside the transcript viewer. | docs |
| ctrl+home / ctrl+end ctrl+home / ctrl+end (cmd+up / cmd+down conventionally on mac, but docs specify Ctrl+Home/End) macOS | Jump to start/latest message of the conversation (fullscreen rendering). scroll:topscroll:bottom | docs |
| pageup / pagedown pageup / pagedown (fn+up/down on mac laptop keyboards) macOS | Scroll up/down half the viewport height in the transcript or diff viewer. scroll:pageUpscroll:pageDown | docs |
| ctrl+shift+c / cmd+c cmd+c macOS | Copy the selected transcript text to the clipboard (fullscreen rendering text selection). selection:copy | docs |
| ctrl+e (classic renderer) | In the transcript viewer, toggle showing all content. transcript:toggleShowAll | source |
| wheelup / wheeldown | Scroll the conversation one line per wheel event in fullscreen rendering. scroll:lineUpscroll:lineDown | source |
| shift+left / shift+right / shift+up / shift+down / shift+home / shift+end | Extend the active text selection by a column, a row, or to the line start or end in fullscreen rendering. Shift+Up and Shift+Down scroll the viewport when the selection reaches an edge. selection:extendLeftselection:extendRightselection:extendUpselection:extendDownselection:extendLineStartselection:extendLineEnd | source |
Dialogs and pickers
| Keys | Does | Src |
|---|---|---|
| left / right (or shift+tab / tab) | Cycle through dialog tabs: Tab or Right goes to the next tab, Shift+Tab or Left to the previous. In a tabbed dialog the keys switch tabs while the tab row has focus; Up/Down move focus between the tab row and the content. tabs:previoustabs:next | source |
| up/down, ctrl+n/ctrl+p, j/k, pageup/pagedown, home/end same macOS | Move selection up/down in generic select lists and the rewind/summarize message selector; PageUp/PageDown page and Home/End jump to the first or last option. Enter accepts and Esc cancels. rl select:nextselect:previous | source |
| space | Toggle a checkbox/selection in confirmation dialogs, plugin dialogs, or settings. confirm:toggle | source |
| / | Enter search mode in the Settings menu. settings:search | docs |
| up / down / j / k, left / right, enter, esc | Diff viewer (/diff in the classic renderer): Up/Down or K/J pick a file, Enter opens its diff, Left/Right switch the diff source, Esc goes back from a file to the list and then closes the dialog. Tab moves to the source picker and, in a file's diff, to the ask button. diff:dismissdiff:previousSourcediff:nextSourcediff:previousFilediff:nextFile | source |
| space / shift+space / b / g / G / home / end | Pager keys in a file's diff detail view: Space and Shift+Space or B page down and up a full viewport, G and Shift+G or Home and End jump to top and bottom, PageUp/PageDown scroll half a viewport. scroll:fullPageDownscroll:fullPageUpscroll:topscroll:bottomscroll:pageUpscroll:pageDown | source |
| left / right / backspace / delete / down / esc (attachment selected) | Navigate image attachments in select dialogs: Left/Right move between attachments, Backspace or Delete removes the selected one, Down or Esc leaves attachment navigation. attachments:nextattachments:previousattachments:removeattachments:exit | source |
| left / right, s (model picker) | In the model picker, Left/Right lower or raise the effort level and S applies the highlighted model to this session only. modelPicker:decreaseEffortmodelPicker:increaseEffortmodelPicker:thisSessionOnly | source |
| left / right / tab / s (/effort slider) | In the slider that /effort opens with no argument, Left/Right move to the next lower or higher effort level, Tab turns ultracode on or off for this session when the slider offers it, and S applies the focused level to this session only. effortSlider:decreaseEfforteffortSlider:increaseEfforteffortSlider:toggleUltracodeeffortSlider:thisSessionOnly | source |
| space / i / f (plugin dialog) | In the plugin dialog, Space toggles plugin selection, I installs the selected plugins, and F favorites the selected plugin so it sorts near the top of the Installed tab. plugin:toggleplugin:installplugin:favorite | source |
| r / f (settings) | In the /config settings panel, R retries loading usage data after an error and F sends your session the /usage recommendations Claude Code can apply, when the usage footer offers a fix. settings:retrysettings:fixUsage | source |
| space / enter / esc, up / down, shift+left / shift+right, c, f, x (/btw overlay) | Keys in the /btw side-question overlay: Space, Enter or Esc dismiss it; Up/Down scroll; Shift+Left/Shift+Right (or [ and ], Tab and Shift+Tab) step between earlier /btw answers; C copies the answer as raw Markdown; F forks a subagent that inherits the conversation plus this exchange; X clears the earlier exchanges list. | docs |
Permission prompts
| Keys | Does | Src |
|---|---|---|
| enter / esc | Confirm (Enter) or decline (Esc) a permission or confirmation dialog. Y and N are no longer default bindings (removed in v2.1.280), though a dialog that displays y and n as its keys reads them itself and you can rebind them in the Confirmation context. Ctrl+C or Ctrl+D twice closes most dialogs. confirm:yesconfirm:no | source |
| tab (permission prompt) | On most permission prompts with Yes or No focused, open a comment field on that option; pressing it again closes the field. The comment goes to Claude with your answer. | docs |
| shift+tab (permission prompt) | On a file permission prompt, close an open comment field; with no field open, select the option that allows the action for the rest of the session, when the prompt offers it. confirm:cycleMode | source |
agent-view
| Keys | Does | Src |
|---|---|---|
| ctrl+s / ctrl+t / ctrl+f / ctrl+r / ctrl+up / ctrl+down (agent view) | In agent view (claude agents): Ctrl+S switches grouping between state and directory, Ctrl+T pins or unpins the selected session, Ctrl+F finds sessions by name, Ctrl+R renames the selected session, Ctrl+Up/Ctrl+Down (or Alt+Up/Alt+Down) jump between group headers. agents:switchViewagents:togglePinagents:findagents:renameagents:previousGroupagents:nextGroup | source |
diff-panel
| Keys | Does | Src |
|---|---|---|
| ctrl+x b | In the diff panel, cycle the comparison base: this session's changes, then your uncommitted changes, then everything since the branch split from the default branch. app:cycleDiffBase | source |
| ctrl+up / ctrl+down (or alt+up / alt+down) ctrl+up / ctrl+down (or meta+up / meta+down) macOS | Scroll the diff panel's file list when it is too long to fit. app:diffFileListUpapp:diffFileListDown | source |
footer
| Keys | Does | Src |
|---|---|---|
| left / right / up / down / enter / esc / x (footer selected) | Navigate the footer indicators below the prompt (tasks, agents, diff, artifacts): arrows or Ctrl+P/Ctrl+N move, Enter opens the selected item, Esc clears the selection instead of interrupting. X stops the selected agent or workflow, or dismisses its row if it is no longer running. footer:nextfooter:previousfooter:upfooter:downfooter:openSelectedfooter:clearSelectionfooter:close | source |
pane
| Keys | Does | Src |
|---|---|---|
| ctrl+x x | Close the focused mod pane. Ctrl+X Left/Right/Up/Down grow or shrink the pane (width beside the transcript, height above the prompt). pane:closepane:growpane:shrink | source |
Codex terminal
Input line
| Keys | Does | Src |
|---|---|---|
| enter return macOS | Submit the current composer draft. tui.keymap.composer.submit | source |
| tab | Queue the draft while a task is running. tui.keymap.composer.queue | source |
| ? or shift+? | Show or hide the composer shortcut overlay. tui.keymap.composer.toggle_shortcuts | source |
| ctrl+r | Open reverse history search, or move to the previous match. rl tui.keymap.composer.history_search_previous | source |
| ctrl+s | Move to the next match in reverse history search. tui.keymap.composer.history_search_next | source |
| ctrl+j / ctrl+m / shift+enter / alt+enter ctrl+j / ctrl+m / shift+return / option+return macOS | Insert a newline in the editor. tui.keymap.editor.insert_newline | source |
| left / ctrl+b | Move the cursor left. rl tui.keymap.editor.move_left | source |
| right / ctrl+f | Move the cursor right. rl tui.keymap.editor.move_right | source |
| up / ctrl+p | Move the cursor up. rl tui.keymap.editor.move_up | source |
| down / ctrl+n | Move the cursor down. rl tui.keymap.editor.move_down | source |
| alt+b / alt+left / ctrl+left option+b / option+left / ctrl+left macOS | Move to the beginning of the previous word. rl tui.keymap.editor.move_word_left | source |
| alt+f / alt+right / ctrl+right option+f / option+right / ctrl+right macOS | Move to the end of the next word. rl tui.keymap.editor.move_word_right | source |
| home / ctrl+a / super+left home / ctrl+a / cmd+left macOS | Move to the beginning of the line. rl tui.keymap.editor.move_line_start | source |
| end / ctrl+e / super+right end / ctrl+e / cmd+right macOS | Move to the end of the line. rl tui.keymap.editor.move_line_end | source |
| backspace / shift+backspace / ctrl+h delete / shift+delete / ctrl+h macOS | Delete one grapheme to the left. rl tui.keymap.editor.delete_backward | source |
| delete / shift+delete / ctrl+d fn+delete / shift+fn+delete / ctrl+d macOS | Delete one grapheme to the right. rl tui.keymap.editor.delete_forward | source |
| alt+backspace / ctrl+backspace / ctrl+shift+backspace / ctrl+w / ctrl+alt+h option+delete / ctrl+delete / ctrl+shift+delete / ctrl+w / ctrl+option+h macOS | Delete the previous word. rl tui.keymap.editor.delete_backward_word | source |
| alt+delete / ctrl+delete / ctrl+shift+delete / alt+d option+fn+delete / ctrl+fn+delete / ctrl+shift+fn+delete / option+d macOS | Delete the next word. rl tui.keymap.editor.delete_forward_word | source |
| ctrl+u / super+backspace ctrl+u / cmd+backspace macOS | Delete from cursor to line start. rl tui.keymap.editor.kill_line_start | source |
| ctrl+k | Delete from cursor to line end. rl tui.keymap.editor.kill_line_end | source |
| ctrl+y | Paste the kill buffer (yank). rl tui.keymap.editor.yank | source |
| ctrl+v cmd+v is NOT wired; use ctrl+v macOS | Paste an image from the clipboard as an attachment. | source |
| / | Trigger the slash-command popup (only at the start of an empty draft). | source |
| ! | Trigger shell-command mode (only at the start of an empty draft). | source |
| @ | Trigger the file-path mention popup. | source |
| $ | Trigger the connector-mentions popup. | source |
| esc (backtrack step 1, main view, empty composer, no running turn) esc macOS | Prime edit-previous-message (backtrack) mode. | source |
| i / insert | Enter insert mode at the cursor. tui.keymap.vim_normal.enter_insert | source |
| a | Enter insert mode after the cursor. tui.keymap.vim_normal.append_after_cursor | source |
| shift+a / A | Enter insert mode at end of line. tui.keymap.vim_normal.append_line_end | source |
| shift+i / I | Enter insert mode at the first non-blank character. tui.keymap.vim_normal.insert_line_start | source |
| o | Open a new line below and enter insert mode. tui.keymap.vim_normal.open_line_below | source |
| shift+o / O | Open a new line above and enter insert mode. tui.keymap.vim_normal.open_line_above | source |
| h / left | Move left in Vim normal mode. tui.keymap.vim_normal.move_left | source |
| l / right | Move right in Vim normal mode. tui.keymap.vim_normal.move_right | source |
| k / up | Move up or recall older history in Vim normal mode. tui.keymap.vim_normal.move_up | source |
| j / down | Move down or recall newer history in Vim normal mode. tui.keymap.vim_normal.move_down | source |
| w | Move to the start of the next word. tui.keymap.vim_normal.move_word_forward | source |
| b | Move to the start of the previous word. tui.keymap.vim_normal.move_word_backward | source |
| e | Move to the end of the current or next word. tui.keymap.vim_normal.move_word_end | source |
| 0 | Move to the start of the line. tui.keymap.vim_normal.move_line_start | source |
| $ / shift+$ | Move to the end of the line. tui.keymap.vim_normal.move_line_end | source |
| x | Delete the character under the cursor. tui.keymap.vim_normal.delete_char | source |
| s | Delete the character under the cursor and enter insert mode. tui.keymap.vim_normal.substitute_char | source |
| shift+d / D | Delete from cursor to end of line. tui.keymap.vim_normal.delete_to_line_end | source |
| shift+c / C | Change from cursor to end of line and enter insert mode. tui.keymap.vim_normal.change_to_line_end | source |
| shift+y / Y | Yank the entire line. tui.keymap.vim_normal.yank_line | source |
| p | Paste after the cursor. tui.keymap.vim_normal.paste_after | source |
| d | Begin a delete operator and wait for a motion. tui.keymap.vim_normal.start_delete_operator | source |
| y | Begin a yank operator and wait for a motion. tui.keymap.vim_normal.start_yank_operator | source |
| c | Begin a change operator and wait for a text object. tui.keymap.vim_normal.start_change_operator | source |
| esc | Cancel a pending Vim operator. tui.keymap.vim_normal.cancel_operator | source |
| d | Repeat delete operator to delete the whole line. tui.keymap.vim_operator.delete_line | source |
| y | Repeat yank operator to yank the whole line. tui.keymap.vim_operator.yank_line | source |
| h | Operator motion left. tui.keymap.vim_operator.motion_left | source |
| l | Operator motion right. tui.keymap.vim_operator.motion_right | source |
| k | Operator motion up. tui.keymap.vim_operator.motion_up | source |
| j | Operator motion down. tui.keymap.vim_operator.motion_down | source |
| w | Operator motion to start of next word. tui.keymap.vim_operator.motion_word_forward | source |
| b | Operator motion to start of previous word. tui.keymap.vim_operator.motion_word_backward | source |
| e | Operator motion to end of word. tui.keymap.vim_operator.motion_word_end | source |
| 0 | Operator motion to line start. tui.keymap.vim_operator.motion_line_start | source |
| $ / shift+$ | Operator motion to line end. tui.keymap.vim_operator.motion_line_end | source |
| i | Select an inner text object. tui.keymap.vim_operator.select_inner_text_object | source |
| a | Select an around text object. tui.keymap.vim_operator.select_around_text_object | source |
| esc | Cancel the pending operator. tui.keymap.vim_operator.cancel | source |
| w | Target the current word. tui.keymap.vim_text_object.word | source |
| shift+w / W | Target the current WORD. tui.keymap.vim_text_object.big_word | source |
| ( / shift+( / ) / shift+) / b | Target enclosing parentheses. tui.keymap.vim_text_object.parentheses | source |
| [ / ] | Target enclosing brackets. tui.keymap.vim_text_object.brackets | source |
| { / shift+{ / } / shift+} / shift+b / B | Target enclosing braces. tui.keymap.vim_text_object.braces | source |
| " / shift+" | Target enclosing double quotes. tui.keymap.vim_text_object.double_quote | source |
| ' | Target enclosing single quotes. tui.keymap.vim_text_object.single_quote | source |
| ` | Target enclosing backticks. tui.keymap.vim_text_object.backtick | source |
| esc | Cancel the pending text object. tui.keymap.vim_text_object.cancel | source |
| f / shift+f / t / shift+t | Find a character forward or backward on the line (f, F) or move up to it (t, T) in Vim normal mode. tui.keymap.vim_normal.find_forwardtui.keymap.vim_normal.find_backwardtui.keymap.vim_normal.till_forwardtui.keymap.vim_normal.till_backward | source |
| shift+g / G | Jump to the bottom of the composer text in Vim normal mode. tui.keymap.vim_normal.jump_bottom | source |
| r | Replace the character under the cursor in Vim normal mode. tui.keymap.vim_normal.replace_char | source |
| shift+r / R | Enter replace mode in Vim normal mode. tui.keymap.vim_normal.enter_replace_mode | source |
| . | Repeat the last change in Vim normal mode. tui.keymap.vim_normal.repeat_last_change | source |
| u | Undo in Vim normal mode. tui.keymap.vim_normal.undo | source |
| ctrl+r | Redo in Vim normal mode. tui.keymap.vim_normal.redo | source |
| f / shift+f / t / shift+t | Operator motion to a character (find or till) after d, y or c. tui.keymap.vim_operator.motion_find_forwardtui.keymap.vim_operator.motion_find_backwardtui.keymap.vim_operator.motion_till_forwardtui.keymap.vim_operator.motion_till_backward | source |
| shift+g / G | Operator motion to the bottom of the text after d, y or c. tui.keymap.vim_operator.motion_jump_bottom | source |
| / or ? | Start a forward (/) or backward (?) search in Vim mode. tui.keymap.vim_search.forwardtui.keymap.vim_search.backward | source |
| n or N | Jump to the next (n) or previous (N) search match in Vim mode. tui.keymap.vim_search.nexttui.keymap.vim_search.previous | source |
Anywhere
| Keys | Does | Src |
|---|---|---|
| ctrl+t | Open the transcript overlay. tui.keymap.global.open_transcript | source |
| ctrl+g | Open the current draft in an external editor ($EDITOR). tui.keymap.global.open_external_editor | source |
| ctrl+o | Copy the last agent response to the clipboard. tui.keymap.global.copy | source |
| ctrl+l | Clear the terminal UI. rl tui.keymap.global.clear_terminal | source |
| alt+r option+r macOS | Toggle raw scrollback mode for copy-friendly transcript selection. tui.keymap.global.toggle_raw_output | source |
| ctrl+/ | Switch between a side conversation and its parent without closing either. tui.keymap.global.toggle_side_conversation | source |
| esc | Interrupt the active turn. tui.keymap.chat.interrupt_turn | source |
| alt+, or shift+down option+, or shift+down macOS | Decrease reasoning effort. tui.keymap.chat.decrease_reasoning_effort | source |
| alt+. or shift+up option+. or shift+up macOS | Increase reasoning effort. tui.keymap.chat.increase_reasoning_effort | source |
| alt+up or shift+left option+up or shift+left macOS | Move forward through async questions, then edit the most recently queued message. tui.keymap.chat.edit_queued_message | source |
| ctrl+c (first press) | Interrupt the active turn if one is running. | source |
| ctrl+c (idle, second/only press) | Quit Codex. | source |
| ctrl+d (composer empty) | Quit Codex. rl | source |
| shift+tab | Cycle the collaboration mode (Default or Plan; those are the only two visible in the TUI). | source |
| alt+left option+left macOS | Switch to the previous agent. | source |
| alt+right option+right macOS | Switch to the next agent. | source |
| ctrl+z | Suspend Codex (SIGTSTP); resume with `fg` in the shell. | source |
| f3 | Find text in the full transcript. tui.keymap.global.find_transcript | source |
| f4 | Focus activity groups in the transcript to inspect their details. tui.keymap.global.focus_activity | source |
| f2 | Open retained warnings without replacing the composer. tui.keymap.global.open_warnings | source |
| alt+down or shift+right option+down or shift+right macOS | Move back through async questions toward the composer. tui.keymap.chat.prompt_stack_back | source |
| ctrl+] | Skip the focused question. tui.keymap.chat.skip_question | source |
Transcript / pager
| Keys | Does | Src |
|---|---|---|
| esc (backtrack step 2) esc macOS | Open the transcript overlay with the last user message highlighted for editing. | source |
| left / esc | Select the previous (older) prior user message to edit. | source |
| right | Select the next (newer) prior user message to edit. | source |
| enter return macOS | Fork the thread before the selected prior message and reopen it for editing. | source |
| up / k | Scroll up by one row (pager/transcript overlay). tui.keymap.pager.scroll_up | source |
| down / j | Scroll down by one row (pager/transcript overlay). tui.keymap.pager.scroll_down | source |
| pageup / shift+space / ctrl+b | Scroll up by one page (pager/transcript overlay). tui.keymap.pager.page_up | source |
| pagedown / space / ctrl+f | Scroll down by one page (pager/transcript overlay). tui.keymap.pager.page_down | source |
| ctrl+u | Scroll up by half a page (pager/transcript overlay). tui.keymap.pager.half_page_up | source |
| ctrl+d | Scroll down by half a page (pager/transcript overlay). tui.keymap.pager.half_page_down | source |
| home | Jump to the beginning (pager/transcript overlay). tui.keymap.pager.jump_top | source |
| end | Jump to the end (pager/transcript overlay). tui.keymap.pager.jump_bottom | source |
| q / ctrl+c | Close the pager overlay. tui.keymap.pager.close | source |
| ctrl+t | Close the transcript overlay. tui.keymap.pager.close_transcript | source |
| f3 or / | Find text in the transcript pager. tui.keymap.pager.find | source |
Dialogs and pickers
| Keys | Does | Src |
|---|---|---|
| up / ctrl+p / ctrl+k / k | Move list selection up (popup pickers). tui.keymap.list.move_up | source |
| down / ctrl+n / ctrl+j / j | Move list selection down (popup pickers). tui.keymap.list.move_down | source |
| left / ctrl+h | Move horizontally left in list pickers (tabs/toolbars). tui.keymap.list.move_left | source |
| right / ctrl+l | Move horizontally right in list pickers (tabs/toolbars). tui.keymap.list.move_right | source |
| pageup / ctrl+b | Move list selection up by one page. tui.keymap.list.page_up | source |
| pagedown / ctrl+f | Move list selection down by one page. tui.keymap.list.page_down | source |
| home | Jump to the first list item. tui.keymap.list.jump_top | source |
| end | Jump to the last list item. tui.keymap.list.jump_bottom | source |
| enter return macOS | Accept the current list selection. tui.keymap.list.accept | source |
| esc | Cancel and close selection views. tui.keymap.list.cancel | source |
| ctrl+c | Cancel the open list picker (resume picker etc.), does not quit Codex. | source |
| ctrl+t | Toggle transcript preview inside the resume/session picker. | source |
| ctrl+e | Toggle expansion inside the resume/session picker. | source |
| ctrl+o | Toggle density inside the resume/session picker. | source |
| tab or shift+tab | Move focus between toolbar controls in the resume picker. | source |
| ctrl+a | Archive the selected session in the resume picker, when archiving is available. | source |
| o | Resume the selected session in the agents dashboard. tui.keymap.agents.resume | source |
| f3 or / | Search the agents dashboard. tui.keymap.agents.search | source |
| n | Start a new task from the agents dashboard. tui.keymap.agents.new_task | source |
| w | Start a new worktree task from the agents dashboard. tui.keymap.agents.new_worktree | source |
| f | Fork the selected session from the agents dashboard. tui.keymap.agents.fork | source |
| r | Rename the selected session in the agents dashboard. tui.keymap.agents.rename | source |
| x | Stop the selected session in the agents dashboard. tui.keymap.agents.stop | source |
| a | Archive the selected session in the agents dashboard. tui.keymap.agents.archive | source |
| backspace | Delete the selected session in the agents dashboard. tui.keymap.agents.delete | source |
| h | Hide the selected session in the agents dashboard. tui.keymap.agents.hide | source |
| p | Pin or unpin the selected session in the agents dashboard. tui.keymap.agents.toggle_pin | source |
| g | Toggle grouping in the agents dashboard. tui.keymap.agents.toggle_grouping | source |
Approval prompts
| Keys | Does | Src |
|---|---|---|
| ctrl+a / ctrl+shift+a | Open approval details fullscreen. tui.keymap.approval.open_fullscreen | source |
| o | Open the approval's source thread, when available. tui.keymap.approval.open_thread | source |
| y | Approve the primary option. tui.keymap.approval.approve | source |
| a | Approve for the rest of the session, when available. tui.keymap.approval.approve_for_session | source |
| p | Approve with an exec-policy prefix, when available. tui.keymap.approval.approve_for_prefix | source |
| d | Choose the explicit deny option, when available. tui.keymap.approval.deny | source |
| esc / n | Decline and provide corrective guidance. tui.keymap.approval.decline | source |
| c | Cancel an elicitation request. tui.keymap.approval.cancel | source |
chat
| Keys | Does | Src |
|---|---|---|
| f8 | Start or stop a voice conversation. tui.keymap.chat.toggle_voice | source |
| f9 | Toggle capture (mute) in the active voice session. tui.keymap.chat.toggle_voice_mute | source |
| ctrl+x p | Open the preset submenu (leader chord: leader key ctrl+x, then p). tui.keymap.chat.open_presets | source |
OpenCode terminal
Input line
| Keys | Does | Src |
|---|---|---|
| <leader>e | editor_open - open the external $EDITOR to compose the current message. editor_open | source |
| ctrl+c | input_clear - clear the input box. input_clear | source |
| ctrl+v | input_paste - paste clipboard contents into the input box. input_paste | source |
| return | input_submit - submit the current message. input_submit | source |
| shift+return,ctrl+return,alt+return,ctrl+j | input_newline - insert a newline in the input box without submitting. input_newline | source |
| left,ctrl+b | input_move_left - move cursor left one character. rl input_move_left | source |
| right,ctrl+f | input_move_right - move cursor right one character. rl input_move_right | source |
| up | input_move_up - move cursor up a line in a multi-line input. input_move_up | source |
| down | input_move_down - move cursor down a line in a multi-line input. input_move_down | source |
| shift+left | input_select_left - extend selection left one character. input_select_left | source |
| shift+right | input_select_right - extend selection right one character. input_select_right | source |
| shift+up | input_select_up - extend selection up one line. input_select_up | source |
| shift+down | input_select_down - extend selection down one line. input_select_down | source |
| ctrl+a | input_line_home - move cursor to the start of the current line. rl input_line_home | source |
| ctrl+e | input_line_end - move cursor to the end of the current line. rl input_line_end | source |
| ctrl+shift+a | input_select_line_home - select from cursor to start of line. input_select_line_home | source |
| ctrl+shift+e | input_select_line_end - select from cursor to end of line. input_select_line_end | source |
| alt+a | input_visual_line_home - move to start of the visual (wrapped) line. input_visual_line_home | source |
| alt+e | input_visual_line_end - move to end of the visual (wrapped) line. input_visual_line_end | source |
| alt+shift+a | input_select_visual_line_home - select to start of the visual line. input_select_visual_line_home | source |
| alt+shift+e | input_select_visual_line_end - select to end of the visual line. input_select_visual_line_end | source |
| home | input_buffer_home - move cursor to the very start of the whole input buffer. input_buffer_home | source |
| end | input_buffer_end - move cursor to the very end of the whole input buffer. input_buffer_end | source |
| shift+home | input_select_buffer_home - select to the start of the whole buffer. input_select_buffer_home | source |
| shift+end | input_select_buffer_end - select to the end of the whole buffer. input_select_buffer_end | source |
| ctrl+shift+d | input_delete_line - delete the entire current line. input_delete_line | source |
| ctrl+k | input_delete_to_line_end - delete from cursor to end of line (kill-line). rl input_delete_to_line_end | source |
| ctrl+u | input_delete_to_line_start - delete from cursor to start of line (unix-line-discard). rl input_delete_to_line_start | source |
| backspace,shift+backspace | input_backspace - delete character before cursor. input_backspace | source |
| ctrl+d,delete,shift+delete | input_delete - delete character after cursor (forward delete). rl input_delete | source |
| ctrl+-,super+z cmd+z (super+z),ctrl+- macOS | input_undo - undo the last text edit in the input box. input_undo | source |
| ctrl+.,super+shift+z cmd+shift+z,ctrl+. macOS | input_redo - redo the last undone text edit in the input box. input_redo | source |
| alt+f,alt+right,ctrl+right | input_word_forward - move cursor forward one word. rl input_word_forward | source |
| alt+b,alt+left,ctrl+left | input_word_backward - move cursor backward one word. rl input_word_backward | source |
| alt+shift+f,alt+shift+right | input_select_word_forward - extend selection forward one word. input_select_word_forward | source |
| alt+shift+b,alt+shift+left | input_select_word_backward - extend selection backward one word. input_select_word_backward | source |
| alt+d,alt+delete,ctrl+delete | input_delete_word_forward - delete word after cursor (kill-word). rl input_delete_word_forward | source |
| ctrl+w,ctrl+backspace,alt+backspace | input_delete_word_backward - delete word before cursor (unix-word-rubout). rl input_delete_word_backward | source |
| super+a cmd+a macOS | input_select_all - select all text in the input box. input_select_all | source |
| up | history_previous - recall the previous submitted prompt from history. history_previous | source |
| down | history_next - recall the next submitted prompt from history. history_next | source |
| up,ctrl+p | prompt.autocomplete.prev - move to previous autocomplete suggestion (e.g. @file references). rl prompt.autocomplete.prev | source |
| down,ctrl+n | prompt.autocomplete.next - move to next autocomplete suggestion. rl prompt.autocomplete.next | source |
| escape | prompt.autocomplete.hide - dismiss the autocomplete popup. prompt.autocomplete.hide | source |
| return | prompt.autocomplete.select - accept the highlighted autocomplete suggestion. prompt.autocomplete.select | source |
| tab | prompt.autocomplete.complete - complete/accept via Tab. prompt.autocomplete.complete | source |
| <leader>q | session_queued_prompts - open the queued-prompts menu. session_queued_prompts | source |
Anywhere
| Keys | Does | Src |
|---|---|---|
| ctrl+x | Leader key. Activates leader mode for leader_timeout ms (default 2000); the next key pressed is interpreted as a leader combo, e.g. ctrl+x then n = new session. leader | source |
| ctrl+c,ctrl+d,<leader>q | app_exit - quit OpenCode. app_exit | source |
| ctrl+p | command_list - open the command palette. command_list | source |
| <leader>t | theme_list - open theme picker. theme_list | source |
| <leader>b | sidebar_toggle - show/hide the sidebar. sidebar_toggle | source |
| <leader>s | status_view - open status view. status_view | source |
| <leader>x | session_export - export current conversation to Markdown and open in $EDITOR. session_export | source |
| <leader>n | session_new - start a new session. session_new | source |
| <leader>l | session_list - list and switch between saved sessions. session_list | source |
| <leader>g | session_timeline - open session timeline view. session_timeline | source |
| ctrl+r | session_rename - rename the current session. session_rename | source |
| ctrl+d | session_delete - delete the currently selected/open session. session_delete | source |
| escape | session_interrupt - interrupt/cancel the model's in-flight response. session_interrupt | source |
| <leader>c | session_compact - compact/summarize the current session. session_compact | source |
| <leader>down | session_child_first - jump to the first child (subagent) session. session_child_first | source |
| right | session_child_cycle - cycle to the next child/subagent session. session_child_cycle | source |
| left | session_child_cycle_reverse - cycle to the previous child/subagent session. session_child_cycle_reverse | source |
| up | session_parent - go to the parent session. session_parent | source |
| ctrl+d | stash_delete - delete a stashed prompt. stash_delete | source |
| <leader>m | model_list - list/switch available models. model_list | source |
| f2 | model_cycle_recent - cycle to the next recently-used model. model_cycle_recent | source |
| shift+f2 | model_cycle_recent_reverse - cycle to the previous recently-used model. model_cycle_recent_reverse | source |
| <leader>a | agent_list - list/switch agents. agent_list | source |
| tab | agent_cycle - cycle to the next agent. agent_cycle | source |
| shift+tab | agent_cycle_reverse - cycle to the previous agent. agent_cycle_reverse | source |
| ctrl+t | variant_cycle - cycle the active model's reasoning/thinking variant (e.g. effort level). variant_cycle | source |
| ctrl+z | terminal_suspend - suspend OpenCode to the background (POSIX SIGTSTP, like any terminal job-control suspend; resume with `fg` in the shell). terminal_suspend | source |
| <leader>h | tips_toggle - toggle the tips panel. tips_toggle | source |
| ctrl+alt+k | which_key_toggle - toggle the 'which-key' style help overlay listing available leader combos. which_key_toggle | source |
| ctrl+alt+shift+k | which_key_layout_toggle - toggle the which-key overlay's layout. which_key_layout_toggle | source |
| ctrl+alt+shift+p | which_key_pending_toggle - toggle showing only pending/available combos in the which-key overlay. which_key_pending_toggle | source |
| ctrl+alt+left,ctrl+alt+[ | which_key_group_previous - previous group in the which-key overlay. which_key_group_previous | source |
| ctrl+alt+right,ctrl+alt+] | which_key_group_next - next group in the which-key overlay. which_key_group_next | source |
| ctrl+alt+up,ctrl+alt+p | which_key_scroll_up - scroll the which-key overlay up. which_key_scroll_up | source |
| ctrl+alt+down,ctrl+alt+n | which_key_scroll_down - scroll the which-key overlay down. which_key_scroll_down | source |
| ctrl+alt+pageup | which_key_page_up - page up in the which-key overlay. which_key_page_up | source |
| ctrl+alt+pagedown | which_key_page_down - page down in the which-key overlay. which_key_page_down | source |
| ctrl+alt+home | which_key_home - jump to top of the which-key overlay. which_key_home | source |
| ctrl+alt+end | which_key_end - jump to bottom of the which-key overlay. which_key_end | source |
| ctrl+b | session_background - background running synchronous subagents. session_background | source |
| <leader>1 | session_quick_switch_1 - switch to the session pinned in quick slot 1. session_quick_switch_1 | source |
| <leader>2 | session_quick_switch_2 - switch to the session pinned in quick slot 2. session_quick_switch_2 | source |
| <leader>3 | session_quick_switch_3 - switch to the session pinned in quick slot 3. session_quick_switch_3 | source |
| <leader>4 | session_quick_switch_4 - switch to the session pinned in quick slot 4. session_quick_switch_4 | source |
| <leader>5 | session_quick_switch_5 - switch to the session pinned in quick slot 5. session_quick_switch_5 | source |
| <leader>6 | session_quick_switch_6 - switch to the session pinned in quick slot 6. session_quick_switch_6 | source |
| <leader>7 | session_quick_switch_7 - switch to the session pinned in quick slot 7. session_quick_switch_7 | source |
| <leader>8 | session_quick_switch_8 - switch to the session pinned in quick slot 8. session_quick_switch_8 | source |
| <leader>9 | session_quick_switch_9 - switch to the session pinned in quick slot 9. session_quick_switch_9 | source |
Transcript / pager
| Keys | Does | Src |
|---|---|---|
| pageup,ctrl+alt+b | messages_page_up - scroll transcript up one page. messages_page_up | source |
| pagedown,ctrl+alt+f | messages_page_down - scroll transcript down one page. messages_page_down | source |
| ctrl+alt+y | messages_line_up - scroll transcript up one line. messages_line_up | source |
| ctrl+alt+e | messages_line_down - scroll transcript down one line. messages_line_down | source |
| ctrl+alt+u | messages_half_page_up - scroll transcript up half a page. messages_half_page_up | source |
| ctrl+alt+d | messages_half_page_down - scroll transcript down half a page. messages_half_page_down | source |
| ctrl+g,home | messages_first - jump to the first message in the transcript. messages_first | source |
| ctrl+alt+g,end | messages_last - jump to the last message in the transcript. messages_last | source |
| <leader>y | messages_copy - copy message(s) from the transcript. messages_copy | source |
| <leader>u | messages_undo - undo the last conversation turn (git-based; reverts file changes too). Requires the project to be a git repo. messages_undo | source |
| <leader>r | messages_redo - redo a previously undone turn. messages_redo | source |
| <leader>h | messages_toggle_conceal - toggle concealment of message content. messages_toggle_conceal | source |
Dialogs and pickers
| Keys | Does | Src |
|---|---|---|
| ctrl+a | model_provider_list - open the model provider list. model_provider_list | source |
| ctrl+f | model_favorite_toggle - toggle a model as favorite. model_favorite_toggle | source |
| up,ctrl+p | dialog.select.prev - move selection up in an open dialog/list. rl dialog.select.prev | source |
| down,ctrl+n | dialog.select.next - move selection down in an open dialog/list. rl dialog.select.next | source |
| pageup | dialog.select.page_up - page up within an open dialog/list. dialog.select.page_up | source |
| pagedown | dialog.select.page_down - page down within an open dialog/list. dialog.select.page_down | source |
| home | dialog.select.home - jump to first item in an open dialog/list. dialog.select.home | source |
| end | dialog.select.end - jump to last item in an open dialog/list. dialog.select.end | source |
| return | dialog.select.submit - confirm the selected item in an open dialog/list. dialog.select.submit | source |
| return | dialog.prompt.submit - submit a text-entry dialog/prompt. dialog.prompt.submit | source |
| space | dialog.mcp.toggle - toggle an item in the MCP server dialog. dialog.mcp.toggle | source |
| space | plugins.toggle - toggle a plugin on/off in the plugins dialog. plugins.toggle | source |
| shift+i | dialog.plugins.install - install the selected plugin. dialog.plugins.install | source |
| escape,q | diff_close - close the diff viewer. diff_close | source |
| enter,space | diff_toggle - toggle the selected diff viewer item (e.g. expand/collapse or check off a file). diff_toggle | source |
| right | diff_expand - expand the selected diff viewer item. diff_expand | source |
| E | diff_expand_all - expand all folders in the diff viewer file tree. diff_expand_all | source |
| left | diff_collapse - collapse the selected diff viewer item. diff_collapse | source |
| tab | diff_switch_focus - switch focus between diff viewer panes (e.g. file tree vs diff body). diff_switch_focus | source |
| ] | diff_next_hunk - jump to the next diff hunk. diff_next_hunk | source |
| [ | diff_previous_hunk - jump to the previous diff hunk. diff_previous_hunk | source |
| n | diff_next_file - jump to the next file in the diff viewer. diff_next_file | source |
| p | diff_previous_file - jump to the previous file in the diff viewer. diff_previous_file | source |
| b | diff_toggle_file_tree - show/hide the diff viewer's file tree pane. diff_toggle_file_tree | source |
| s | diff_single_patch - toggle single-patch view in the diff viewer. diff_single_patch | source |
| d | diff_switch_source - switch the diff viewer's source. diff_switch_source | source |
| v | diff_toggle_view - toggle diff viewer split vs unified view. diff_toggle_view | source |
| ? | diff_help - show more diff viewer shortcuts. diff_help | source |
| ctrl+f | session_pin_toggle - pin or unpin a session inside the session-list dialog. session_pin_toggle | source |
| ctrl+m | dialog.move_session.new - create a new project copy from the move-session dialog. dialog.move_session.new | source |
| ctrl+d | dialog.move_session.delete - delete a project copy from the move-session dialog. dialog.move_session.delete | source |
| ctrl+r | dialog.move_session.refresh - refresh project copies in the move-session dialog. dialog.move_session.refresh | source |
Permission prompts
| Keys | Does | Src |
|---|---|---|
| ctrl+f | permission.prompt.fullscreen - expand the permission prompt to fullscreen. permission.prompt.fullscreen | source |
Pi terminal
Input line
| Keys | Does | Src |
|---|---|---|
| up | Move cursor up tui.editor.cursorUp | first-hand |
| down | Move cursor down tui.editor.cursorDown | first-hand |
| left, ctrl+b | Move cursor left rl tui.editor.cursorLeft | first-hand |
| right, ctrl+f | Move cursor right rl tui.editor.cursorRight | first-hand |
| alt+left, ctrl+left, alt+b option+left, ctrl+left, option+b (terminal-dependent Alt/Option mapping) macOS | Move cursor one word left rl tui.editor.cursorWordLeft | first-hand |
| alt+right, ctrl+right, alt+f option+right, ctrl+right, option+f (terminal-dependent) macOS | Move cursor one word right rl tui.editor.cursorWordRight | first-hand |
| home, ctrl+a | Move to line start rl tui.editor.cursorLineStart | first-hand |
| end, ctrl+e | Move to line end rl tui.editor.cursorLineEnd | first-hand |
| ctrl+] | Jump forward to character tui.editor.jumpForward | first-hand |
| ctrl+alt+] ctrl+option+] macOS | Jump backward to character tui.editor.jumpBackward | first-hand |
| pageUp, ctrl+pageUp fn+up (pageUp, terminal-dependent), ctrl+pageUp macOS | Scroll the transcript up by page (fullscreen, the default); in regular mode or with ctrl+pageUp, page the editor up tui.altScreen.pageUptui.editor.pageUp | first-hand |
| pageDown, ctrl+pageDown fn+down (pageDown, terminal-dependent), ctrl+pageDown macOS | Scroll the transcript down by page (fullscreen, the default); in regular mode or with ctrl+pageDown, page the editor down tui.altScreen.pageDowntui.editor.pageDown | first-hand |
| backspace delete (backspace) macOS | Delete character backward rl tui.editor.deleteCharBackward | first-hand |
| delete, ctrl+d fn+delete (forward delete), ctrl+d macOS | Delete character forward rl tui.editor.deleteCharForward | first-hand |
| ctrl+w, alt+backspace ctrl+w, option+delete macOS | Delete word backward rl tui.editor.deleteWordBackward | first-hand |
| alt+d, alt+delete option+d, option+fn+delete macOS | Delete word forward rl tui.editor.deleteWordForward | first-hand |
| ctrl+u | Delete to line start rl tui.editor.deleteToLineStart | first-hand |
| ctrl+k | Delete to line end rl tui.editor.deleteToLineEnd | first-hand |
| shift+enter, ctrl+j shift+return, ctrl+j macOS | Insert new line (multiline input) tui.input.newLine | first-hand |
| enter return macOS | Submit input; when the agent is already running, Enter instead queues a steering message delivered after the current tool-call turn finishes tui.input.submit | first-hand |
| tab | Tab / autocomplete tui.input.tab | first-hand |
| ctrl+y | Paste (yank) most recently deleted text rl tui.editor.yank | first-hand |
| alt+y option+y macOS | Cycle through deleted text after yank (yank-pop) rl tui.editor.yankPop | first-hand |
| ctrl+- | Undo last edit rl tui.editor.undo | first-hand |
| ctrl+c | Copy selection; if no selection, clear the editor; a second press within 500 ms exits Pi tui.input.copyapp.clear | first-hand |
| ctrl+d | Exit pi when the editor is empty (EOF-style exit) rl app.exit | first-hand |
| ctrl+g | Open current input in an external editor ($VISUAL, $EDITOR, Notepad on Windows, or nano elsewhere) app.editor.external | first-hand |
| ctrl+v cmd+v (native paste)/ctrl+v; alt+v on Windows macOS | Paste files (macOS), images, or text from the clipboard app.clipboard.pasteImage | first-hand |
| ctrl+p | Cycle to next model (when --models patterns configured); also toggles path display in the session list, and toggles all models for the current provider in the scoped-models selector app.model.cycleForwardapp.session.togglePathapp.models.toggleProvider | first-hand |
| shift+ctrl+p | Cycle to previous model app.model.cycleBackward | first-hand |
| ctrl+l | Open model selector app.model.selectapp.tree.filter.labeledOnly | first-hand |
| shift+tab | Cycle thinking level (off/minimal/low/medium/high/xhigh/max) app.thinking.cycle | first-hand |
| alt+enter option+return macOS | Queue a follow-up message, delivered after the agent finishes all current work app.message.followUp | first-hand |
| alt+up option+up macOS | Restore queued messages back to the editor app.message.dequeueapp.models.reorderUp | first-hand |
Anywhere
| Keys | Does | Src |
|---|---|---|
| escape esc macOS | Cancel / abort current agent turn; in dialogs/selectors, cancels the selection app.interrupttui.select.cancel | first-hand |
| ctrl+z | Suspend to background (job control) rl app.suspend | first-hand |
Transcript / pager
| Keys | Does | Src |
|---|---|---|
| ctrl+t | Collapse or expand thinking blocks app.thinking.toggleapp.tree.filter.noTools | first-hand |
| ctrl+o | Collapse or expand tool output app.tools.expandapp.tree.filter.cycleForward | first-hand |
| ctrl+x | Copy the last assistant message (the selected message in /tree; the active text selection in fullscreen when fullscreenCopyOnSelect is false; the sign-in URL on OAuth sign-in screens) app.message.copyapp.models.clearAll | first-hand |
| ctrl+home | Scroll the transcript to the beginning (fullscreen mode) tui.altScreen.top | source |
| ctrl+end | Scroll the transcript to the end and follow new output (fullscreen mode) tui.altScreen.bottom | source |
| ctrl+shift+up, ctrl+up | Jump to the previous marked message in the transcript (fullscreen mode) tui.altScreen.previousPrompt | source |
| ctrl+shift+down, ctrl+down | Jump to the next marked message in the transcript (fullscreen mode) tui.altScreen.nextPrompt | source |
| ctrl+shift+f | Search the rendered transcript (fullscreen mode) tui.altScreen.search | source |
| enter, ctrl+g | Select the next transcript search match while searching tui.altScreen.searchNext | source |
| shift+enter, ctrl+shift+g | Select the previous transcript search match while searching tui.altScreen.searchPrevious | source |
| escape esc macOS | Close the transcript search tui.altScreen.searchClose | source |
Dialogs and pickers
| Keys | Does | Src |
|---|---|---|
| ctrl+left, alt+left ctrl+left, option+left macOS | Fold current tree branch segment, or jump to previous segment start app.tree.foldOrUp | first-hand |
| ctrl+right, alt+right ctrl+right, option+right macOS | Unfold current tree branch segment, or jump to next segment/branch end app.tree.unfoldOrDown | first-hand |
| shift+l | Edit the label on the selected tree node app.tree.editLabel | first-hand |
| shift+t | Toggle label timestamps in the tree app.tree.toggleLabelTimestamp | first-hand |
| ctrl+a | Toggle tree filter that shows all entries (inside /tree); also enables all models in the scoped-models selector app.tree.filter.allapp.models.enableAll | first-hand |
| ctrl+s | Toggle sort mode in the session list; saves the selected model (scoped-models selector) or the current thinking level (app.thinking.save) to settings app.session.toggleSortapp.models.save | first-hand |
| ctrl+n | Toggle named-only filter in the session list app.session.toggleNamedFilter | first-hand |
| ctrl+r | Rename session app.session.rename | first-hand |
| ctrl+backspace ctrl+delete (backspace) macOS | Delete session when the session-list query is empty app.session.deleteNoninvasive | first-hand |
| shift+ctrl+o | Cycle tree filter backward app.tree.filter.cycleBackward | first-hand |
| alt+down option+down macOS | Move the selected model down in the cycle order (scoped-models selector) app.models.reorderDown | first-hand |
Cursor editor extension
Anywhere
| Keys | Does | Src |
|---|---|---|
| ctrl+i cmd+i macOS | Toggle Sidepanel (opens the Chat/Agent panel) - unless bound to a specific mode | docs |
| ctrl+l cmd+l macOS | Toggle Sidepanel (opens the Chat/Agent panel) - unless bound to a specific mode | docs |
| ctrl+. cmd+. macOS | Mode Menu (open the Agent/Ask/Plan mode selector) | docs |
| ctrl+/ cmd+/ macOS | Loop between AI models | docs |
| ctrl+shift+j cmd+shift+j macOS | Cursor settings | docs |
| ctrl+shift+space cmd+shift+space macOS | Toggle Voice Mode | docs |
| ctrl+, cmd+, macOS | General settings | docs |
| ctrl+shift+p cmd+shift+p macOS | Command palette | docs |
| ctrl+k cmd+k macOS | Toggle Sidepanel (unless bound to mode); with code selected, add selection to new chat | docs |
agent
| Keys | Does | Src |
|---|---|---|
| ctrl+e cmd+e macOS | Toggle Agent layout | docs |
chat
| Keys | Does | Src |
|---|---|---|
| enter | Queue message (default) - send/submit the chat message | docs |
| ctrl+enter cmd+enter macOS | Force send message (when typing) | docs |
| ctrl+shift+backspace cmd+shift+backspace macOS | Cancel generation | docs |
| ctrl+shift+l cmd+shift+l macOS | Add selected code as context (with code selected) | docs |
| ctrl+v cmd+v macOS | Add clipboard as context (with code or log in clipboard) | docs |
| ctrl+shift+v cmd+shift+v macOS | Add clipboard to input box (with code or log in clipboard) | docs |
| ctrl+enter cmd+enter macOS | Accept all changes (with suggested changes pending) | docs |
| ctrl+backspace cmd+backspace macOS | Reject all changes | docs |
| tab | Cycle to next message | docs |
| shift+tab | Rotate between Agent modes | docs |
| ctrl+alt+/ cmd+opt+/ macOS | Model toggle | docs |
| ctrl+n cmd+n macOS | New chat | docs |
| ctrl+r cmd+r macOS | New chat | docs |
| ctrl+t cmd+t macOS | New chat tab | docs |
| ctrl+[ cmd+[ macOS | Previous chat | docs |
| ctrl+] cmd+] macOS | Next chat | docs |
| ctrl+w cmd+w macOS | Close chat | docs |
| esc | Unfocus field | docs |
| @ | @-mentions - trigger the context-attachment picker (files, docs, symbols, etc.) | docs |
| / | Shortcut Commands - trigger the slash-command menu in chat/agent input | docs |
| ctrl+enter cmd+enter macOS | Search codebase in chat | docs |
| ctrl+c then ctrl+v cmd+c then cmd+v macOS | Add copied reference code as context | docs |
| ctrl+c then ctrl+shift+v cmd+c then cmd+shift+v macOS | Add copied code as text context | docs |
editor
| Keys | Does | Src |
|---|---|---|
| ctrl+shift+l cmd+shift+l macOS | Add selection to Chat | docs |
| ctrl+l cmd+l macOS | Add selection to new chat | docs |
| ctrl+right cmd+right macOS | Accept next word of suggestion | docs |
| tab | Accept suggestion (Tab completion) | docs |
| ctrl+right cmd+right macOS | Accept next word (Tab completion, partial accept) | docs |
Cursor terminal
Anywhere
| Keys | Does | Src |
|---|---|---|
| shift+tab | Rotate between modes (Agent, Plan, Ask) | docs |
| shift+enter | Insert a newline instead of submitting (multi-line prompts) | docs |
| ctrl+d | Exit the CLI (double press) | docs |
| ctrl+j | Insert a newline (universal alternative that works in all terminals) | docs |
| ctrl+r | Review changes | docs |
| i | Add follow-up instructions (while in the review flow) | docs |
| up/down | Cycle through previous messages (Navigation) / scroll (during review) | docs |
| left/right | Switch files (during the review flow) | docs |
| @ | Select files/folders to include in context | docs |
| ctrl+g | Open the prompt in $EDITOR | docs |
| ctrl+l | Clear the screen and scrollback; the session keeps running rl | docs |
| ctrl+v | Paste a clipboard image into the prompt | docs |
| ctrl+y | Open the /resume session picker | docs |
| ctrl+b ctrl+b | Send a running shell command to the background (double press) | docs |
| ctrl+z | Suspend the CLI to the shell; fg resumes it rl | docs |
| ctrl+o | Expand truncated output (Shell Mode) and subagent rows | docs |
| ctrl+c | Cancel (shell command hang, prompts, goal); exit Shell Mode on empty input | docs |
| esc | Exit Shell Mode when the input is empty (Backspace/Delete on empty input also exits) | docs |
| enter | In the / menu, attach the highlighted skill to one message | docs |
| alt+enter opt+enter macOS | In the / menu, invoke the highlighted skill as a Custom Mode that stays active until you exit it | docs |
| y / n | Approve or reject a terminal command before it runs | docs |
| & then message | Prefix a message with & to send it to a Cloud Agent | docs |
Copilot vscode extension
chat
| Keys | Does | Src |
|---|---|---|
| ctrl+alt+i ctrl+cmd+i macOS | Open/focus the Copilot Chat view (side panel) workbench.action.chat.open | docs |
| ctrl+shift+alt+l cmd+opt+shift+l macOS | Open Quick Chat (transient inline chat popover, not the full panel) workbench.action.quickchat.toggle | docs |
| ctrl+n cmd+n macOS | Start a new chat session (clears current Chat view thread) | docs |
| ctrl+shift+i (win) / ctrl+shift+alt+i (linux) cmd+shift+i macOS | Switch the Chat view into Agent mode | source |
| ctrl+alt+. option+cmd+. macOS | Open the model picker in the Chat view workbench.action.chat.openModelPicker | source |
| ctrl+alt+up opt+cmd+up macOS | Go to the previous prompt in the current chat session | docs |
| ctrl+alt+down opt+cmd+down macOS | Go to the next prompt in the current chat session | docs |
| ctrl+alt+pageup opt+cmd+pageup macOS | Go to the previous code block in the chat session | docs |
| ctrl+alt+pagedown opt+cmd+pagedown macOS | Go to the next code block in the chat session | docs |
| ctrl+. (chat input) cmd+. (chat input) macOS | Open the Agent picker (chat mode picker) with focus in the Chat input | source |
| ctrl+shift+enter (chat input) cmd+shift+enter (chat input) macOS | Send the message to a new chat workbench.action.chat.sendToNewChat | source |
| ctrl+enter (chat input) cmd+enter (chat input) macOS | Send with #codebase | source |
| alt+backspace (win) / ctrl+escape (linux) ctrl+escape macOS | Cancel the in-progress chat request | source |
| ctrl+f cmd+f macOS | Search the whole chat conversation (Chat view, chat editor tabs, Agents window) | docs |
completion
| Keys | Does | Src |
|---|---|---|
| tab | Accept the full ghost-text inline suggestion (or its first line if multi-line) editor.action.inlineSuggest.commit | docs |
| escape | Dismiss the current inline suggestion editor.action.inlineSuggest.hide | docs |
| alt+] option+] macOS | Show next inline suggestion (cycle forward) editor.action.inlineSuggest.showNext | docs |
| alt+[ option+[ macOS | Show previous inline suggestion (cycle backward) editor.action.inlineSuggest.showPrevious | docs |
| alt+\ option+\ macOS | Manually trigger an inline suggestion editor.action.inlineSuggest.trigger | docs |
| ctrl+right cmd+right macOS | Partially accept the suggestion: next word (docs also say next line) editor.action.inlineSuggest.acceptNextWord | docs |
| none (no default) | Accept the suggestion one line at a time editor.action.inlineSuggest.acceptNextLine | docs |
| ctrl+enter | Open the Copilot completions panel showing multiple suggestions in a new editor tab github.copilot.generate | docs |
inline-chat
| Keys | Does | Src |
|---|---|---|
| ctrl+i cmd+i macOS | Open inline chat at the cursor position in the editor inlineChat.start | docs |
terminal
| Keys | Does | Src |
|---|---|---|
| ctrl+i cmd+i macOS | Open inline chat in the integrated terminal workbench.action.terminal.chat.start | docs |
Copilot terminal
Anywhere
| Keys | Does | Src |
|---|---|---|
| shift+tab | Cycle between Standard, Plan, and Autopilot session modes | docs |
| esc | Cancel the current operation; press twice to interrupt the running turn, or to stop background agents when the main agent is idle | docs |
| ctrl+c | Cancel operation / clear input. Press twice to exit rl | docs |
| ctrl+d | Shutdown rl | docs |
| ctrl+l | Clear the screen rl | docs |
| ctrl+enter or ctrl+q cmd+enter or ctrl+q macOS | Queue a message to send while the agent is busy | docs |
| ctrl+r | Reverse search through command history rl | docs |
| up / down | Navigate the command history rl | docs |
| ctrl+a | Move to beginning of the line (when typing) rl | docs |
| ctrl+e | Move to end of the line (when typing); when the prompt input is empty instead, this same key expands all items in the response timeline rl | docs |
| ctrl+b | Move to the previous character rl | docs |
| ctrl+f | Move to the next character (when typing); when the prompt input is empty instead, this same key opens timeline search rl | docs |
| ctrl+h | Delete the previous character rl | docs |
| ctrl+k | Delete from cursor to end of the line. If the cursor is at the end of the line, delete the line break rl | docs |
| ctrl+u | Delete from cursor to beginning of the line rl | docs |
| ctrl+w | Delete the previous word rl | docs |
| ctrl+v cmd+v macOS | Paste from clipboard as an attachment | docs |
| ctrl+z | Suspend the process to the background (Unix) rl | docs |
| ctrl+x then / | Run a slash command after you have already started typing a prompt | docs |
| ctrl+x then e | Edit the prompt in an external editor ($EDITOR) | docs |
| ctrl+x then b | Promote the running task or shell command to the background | docs |
| ctrl+x then o | Open the most recent link from the response timeline | docs |
| ctrl+g | Edit the prompt in an external editor ($EDITOR) | docs |
| ctrl+o | With an empty prompt input, expand the most recent item in the response timeline to show more detail | docs |
| ctrl+t | Expand/collapse the display of the model's reasoning in responses | docs |
| shift+enter or alt+enter shift+enter or option+enter macOS | Insert a newline in the prompt input without submitting | docs |
| @ then filename | Include a file's contents as context (input prefix, not a modifier-key binding) | docs |
| # then number | Include a GitHub issue or pull request as context | docs |
| ! then command | Execute a shell command directly, bypassing Copilot; '!' alone on an empty prompt enters shell mode for running multiple shell commands in sequence, exited via Esc or Ctrl+C | docs |
| $ | Hand the terminal over to a real interactive shell ($SHELL on Unix, %COMSPEC% on Windows), suspending the CLI UI entirely so job control, full-screen apps, tab completion, and colors work natively | docs |
| ? | Open quick help, when the prompt input is empty; press again to dismiss and insert a literal '?' | docs |
| ctrl+space | Toggle voice dictation on or off | docs |
| ctrl+x then v | Toggle voice dictation on or off | docs |
| alt+v | Paste an image from the clipboard as an attachment | docs |
| ctrl+x then g | Collapse or expand the autopilot goal panel | docs |
| ctrl+x then h | Hide the current-session sidebar | docs |
| ctrl+x then x | Close the current session | docs |
| ctrl+p | Navigate submitted command history without triggering queued-prompt recall rl | docs |
| up (empty prompt) | Recall the most recently queued or steering prompt for editing | docs |
| left / right (empty prompt) | Walk the sidebar focus cycle: closed, timeline-focused, sidebar-focused | docs |
| ctrl+e (empty prompt, new session) | Before the first message, choose a local or cloud environment | docs |
| home / end | Move to the start / end of the current visual line rl | docs |
| alt+left / alt+right opt+left / opt+right macOS | Move the cursor by a word rl | docs |
| pageup / pagedown | Scroll the timeline by one page | docs |
completion
| Keys | Does | Src |
|---|---|---|
| tab or ctrl+y | Accept the current inline completion suggestion | docs |
How it works in each tool
Section titled “How it works in each tool”Showing: Claude Code pick a tab to change
Verified against 2.1.222 on 2026-08-07. Bindings below were read from the official keybindings reference and cross-checked against action strings in the installed binary.
The input line is readline-based. Ctrl+A / Ctrl+E move to line start and end, Ctrl+U and Ctrl+K kill backwards and forwards, Ctrl+W deletes the previous word, and Ctrl+Y yanks the last killed text back. None of these touch your system clipboard.
Ctrl+X is a chord prefix. Pressed alone it does nothing visible - it arms a two-key sequence (Ctrl+X Ctrl+K, and others). If a keystroke seems to vanish, this is usually why.
Stopping the agent: press Esc. It interrupts mid-turn and keeps the work done so far. Double-tapping Esc does one of two things depending on the prompt: with text in it, it clears the prompt and saves the draft to history (Up recalls it); with the prompt empty, it opens the rewind menu to restore or summarize from an earlier point. Ctrl+C also interrupts a running operation, or clears the input when nothing is running, but Esc is the one that transfers to every other terminal agent here.
Session control: Ctrl+D on an empty input exits, requiring a double press. Ctrl+Z suspends the process to the shell - fg brings it back.
Images: Ctrl+V pastes an image from the clipboard, inserting an [Image #N] chip into the prompt.
Views: Ctrl+O toggles the verbose transcript, Ctrl+T toggles the to-do checklist, Ctrl+B backgrounds a running Bash task, Ctrl+R opens reverse history search over your previous prompts.
Multi-line: Ctrl+J inserts a newline without submitting.
Modes: Shift+Tab cycles permission modes - default → acceptEdits → plan, plus any additional modes you have enabled, such as auto or bypassPermissions.
Rebinding: ~/.claude/keybindings.json maps keys to action ids such as chat:submit, app:interrupt, app:exit. The action id is the stable identifier; defaults move between releases. Eleven documented actions ship with no default key at all, so they are only reachable if you bind them yourself.
A vim mode exists for the input line, with its own normal/insert bindings.
Verified against 0.146.0 on 2026-08-07, read from the keymap source rather than documentation - Codex has no prose docs for its keymap, but it ships a complete action table in source that also backs the in-app /keymap picker.
Esc is the interrupt key, not Ctrl+C. Esc also drives a distinctive two-stage backtrack: press once to prime, again to open the transcript, then Left/Right to pick an earlier prompt and Enter to fork the conversation from there.
Ctrl+C when idle quits immediately, with no confirmation prompt. The double-press-to-quit guard exists in the code but is compiled off (DOUBLE_PRESS_QUIT_SHORTCUT_ENABLED = false). While a turn is running it interrupts instead. Ctrl+D behaves the same way when the composer is empty, and deletes the character under the cursor when it isn’t.
Line editing is readline-style: Ctrl+A/Ctrl+E, Ctrl+U/Ctrl+K, Ctrl+W, Ctrl+Y, plus Alt+B/Alt+F for word movement.
Useful non-obvious ones: Ctrl+G opens the current draft in $EDITOR. Ctrl+O copies the last agent response to the clipboard - not “open.” Ctrl+R opens reverse history search. Ctrl+V pastes an image from the clipboard as an attachment; pasting text is a separate path.
Multi-line: Ctrl+J, Shift+Enter and Alt+Enter all insert a newline. Shift+Tab cycles the collaboration mode.
Rebinding: the whole keymap is user-remappable under tui.keymap.*, and /keymap opens a picker in-app. Twenty-two bindings are reserved and cannot be remapped, including Ctrl+C, Ctrl+D, Ctrl+V, Shift+Tab and Esc.
Two actions ship with no default key: toggle_vim_mode and toggle_fast_mode. They are real and bindable, just invisible until you bind them.
Verified against v1.18.13 on 2026-08-07 from the keybind definitions and dispatcher source; the keybinds docs page is unchanged at v1.19.4 (2026-10). OpenCode has by far the largest keymap here - roughly 140 named actions, around 40 of which ship unbound.
Ctrl+X is the leader key. It arms a two-second window in which a second key selects from a whole command vocabulary (<leader>m for the model list, and so on). This is a broader mechanism than a chord prefix, and it means Ctrl+X never cuts anything.
Esc interrupts the model’s in-flight response (session_interrupt). Ctrl+C clears the input box (input_clear) rather than copying or cancelling.
Ctrl+R renames the session. It is not reverse history search - OpenCode has no reverse-search binding. If you have muscle memory from Claude Code or Codex, this is the most surprising divergence in the set.
Ctrl+D is context-scoped and can be destructive. In the input line it forward-deletes a character; in dialogs it resolves to session_delete, stash_delete or dialog.move_session.delete depending on what has focus.
Keys are resolved by focus layer, not by a precedence table. Several keys appear against multiple actions in the config and do not actually conflict: a managed text-area layer is active only while the prompt has focus and wins there, and the history-recall handler declines the keystroke unless the cursor is already at the buffer edge, falling through to plain cursor movement otherwise.
Multi-line: Shift+Enter, Ctrl+Enter, Alt+Enter and Ctrl+J all insert a newline.
Rebinding: every binding is user-configurable through tui.json, which also sets the leader key and its timeout, supports disabling a binding, and merges with the defaults rather than replacing them.
No modal/vim editing was found in the TUI source as of the commit checked. Unverified: a third-party claim of a personal implementation exists; treat it as neither confirmed nor supported by the source checked.
Two separate surfaces, two unrelated keymaps. Cursor is a VS Code fork whose headline shortcuts are editor commands, and it also ships agent (also installed as cursor-agent), a terminal agent with its own small binding set. Nothing transfers between them.
Sourced from Cursor’s official shortcut reference and checked in October 2026. Cursor does not version-stamp its docs, and its defaults have shifted between releases more than once, so a lot of third-party shortcut content is stale.
In the editor.
Cmd/Ctrl+K opens Inline Edit at the cursor. In stock VS Code that combination is a chord prefix - it waits for a second key - so this is a silent override of one of the most-used bindings in the editor.
Cmd/Ctrl+L toggles the chat side panel (with code selected it adds the selection to a new chat), overriding the near-universal terminal convention where Ctrl+L clears the screen.
Cmd/Ctrl+I also toggles the side panel unless you have bound it to a mode; the docs list no separate agent shortcut. Anyone arriving from Copilot has this in their fingers for a different panel.
Shift+Tab rotates agent modes. Tab in the chat input cycles to the next message rather than indenting.
In agent (terminal).
Shift+Enter inserts a newline, Shift+Tab rotates between Agent, Plan and Ask, Ctrl+D exits, Ctrl+R opens review, and @ attaches context. There is no dedicated shortcuts reference page for the CLI - these are scattered across the CLI docs, and of this list only Shift+Tab (to Plan mode) was confirmed in the October 2026 pass.
In the terminal prompt bar (Cmd/Ctrl+K there), Cursor’s keyboard reference says Esc accepts the generated command rather than cancelling it. That inverts the near-universal cancel convention; we have not tested it first-hand.
Rebinding: everything goes through VS Code’s own keybindings UI and keybindings.json. Cursor does not publish command ids for most of its AI features, so rebinding them means finding the command in the keyboard-shortcuts UI rather than looking up an identifier.
Two separate surfaces. The VS Code extension and the Copilot CLI have completely different keymaps, and the CLI’s is the larger of the two.
In VS Code.
Tab accepts the ghost-text suggestion. This is the single most consequential rebinding in any tool here, because Tab already meant “indent” to every developer alive. When a suggestion is showing, indentation is not what you get.
Esc dismisses the active suggestion rather than doing nothing. Alt+] / Alt+[ cycle through alternative suggestions. Ctrl/Cmd+Enter opens a side-by-side panel of full completions instead of inserting a newline. Ctrl/Cmd+→ accepts the suggestion one word at a time, hijacking word-navigation while ghost text is visible.
Ctrl/Cmd+I opens inline chat, in the editor or the terminal.
Most of these are contributed keybindings and are rebindable through VS Code’s keyboard-shortcuts UI. Several have no officially published command id, which makes those the ones most likely to drift silently between releases.
In the Copilot CLI.
The input line is readline-based - Ctrl+A, Ctrl+E, Ctrl+B, Ctrl+F, Ctrl+K, Ctrl+U, Ctrl+W all behave as standard Unix line editing.
Ctrl+Y breaks that pattern. Instead of yanking back killed text, it accepts the current inline completion - the same action as Tab. If you have just killed a line with Ctrl+U, the key you would reach for to undo it does something else entirely.
Esc cancels the current operation. Ctrl+C cancels or clears the prompt on the first press, and exits on a second. Ctrl+X is a chord prefix - Ctrl+X E opens $EDITOR. Ctrl+R opens reverse search over the CLI’s own history. Shift+Tab cycles between Standard, Plan and Autopilot modes.
Unverified: treat Ctrl+D with care. The documentation lists it as bare “Shutdown,” with no press-count qualifier or confirmation language - unlike Ctrl+C, which explicitly says press twice. The docs also say nothing about whether an in-flight turn is recoverable.
Rebinding: no configuration mechanism for the CLI’s keys is documented. Assume they are fixed.
Re-checked October 2026 against Pi’s keybindings documentation (1.4.0). Run /hotkeys for the bindings active in your session. Despite being the most minimal harness in this set, Pi ships a full keymap - roughly a third of it inherited readline editing, the rest its own.
Esc cancels the current agent turn. In dialogs and selectors it closes or backs out instead.
Clipboard keys behave unusually here, more so than in any other tool:
Ctrl+Ccopies the selection if one exists; otherwise it clears the editor, and a second press exits. It does not send SIGINT.Ctrl+Vpastes files (macOS), images, or text from the clipboard.Ctrl+Xcopies the last assistant message (or the selected message in/tree). It does not cut.
Ctrl+R renames a session in the session picker (/resume), a different job from the reverse history search it does in a shell. /name renames the current session directly.
Line editing is readline-style: Ctrl+A/Ctrl+E, Ctrl+B/Ctrl+F, Ctrl+W, Ctrl+K, Ctrl+U, Ctrl+Y, with Alt+B/Alt+F/Alt+D for word operations. Ctrl+Z suspends the process to the shell (not on native Windows); undo is Ctrl+-.
Useful ones: Ctrl+G opens the current input in $VISUAL or $EDITOR. Ctrl+L opens the model selector and Ctrl+P cycles through the models in scope (/scoped-models). Shift+Tab cycles the thinking level, and Ctrl+O / Ctrl+T expand tool output and thinking blocks. Shift+Enter and Ctrl+J insert a newline.
Rebinding: ~/.pi/agent/keybindings.json maps keys onto namespaced action ids (tui.editor.*, tui.altScreen.*, app.*), and every default is remappable. Run /reload after editing it.
Prompt history: Up / Down browse older and newer prompts when the cursor is at the top or bottom of the buffer; dedicated tui.editor.historyPrevious / historyNext actions exist but are unbound by default. Fullscreen mode (the default as of 1.0) adds transcript bindings such as PageUp / PageDown to scroll, Ctrl+Up / Ctrl+Down to jump between prompts, and Ctrl+Shift+F to search the transcript. There is no reverse-incremental history search.
Comparison
Section titled “Comparison”| Task | Claude Code | Codex | OpenCode | Cursor | Copilot | Pi |
|---|---|---|---|---|---|---|
| Stop the current run | Esc |
Esc |
Esc |
Enter again (CLI); Cmd/Ctrl+Shift+Backspace (IDE) |
Esc twice |
Esc |
| Insert a newline | Ctrl+J |
Ctrl+J |
Ctrl+J |
Ctrl+J or Shift+Enter (CLI); host editor (IDE) |
Shift+Enter, Option+Enter or Alt+Enter (CLI); host editor (IDE) |
Ctrl+J |
| Rebind defaults | ~/.claude/keybindings.json |
TUI keymap settings | tui.json |
VS Code keybindings | VS Code keybindings | ~/.pi/agent/keybindings.json |
| Main caveat | readline and Claude chords share a line editor | TUI actions vary by mode | leader/chord prefixes change context | IDE and terminal layers overlap | surface-specific keymaps | extensions can add bindings |
Name collisions
Section titled “Name collisions”- “Keybindings” means a user config file of action ids in Claude Code and Pi; in Cursor and Copilot it means VS Code’s keybindings UI, a different system with different precedence.
Ctrl+Xis a leader key in OpenCode and a chord prefix in Claude Code and Copilot CLI. A leader arms a timed window for a whole command vocabulary; a chord prefix waits for one specific completion. Neither cuts.Ctrl+Rsplits the field: reverse history search in Claude Code, Codex and Copilot CLI; rename the session in OpenCode and Pi.- “Vim mode” is not one feature. Claude Code ships one, and Copilot CLI has
/vim. Codex has the action but no default key. Nothing equivalent was found in OpenCode’s source.