Skip to main content
Claude Code supports customizable keyboard shortcuts. Run /keybindings to create or open your configuration file at ~/.claude/keybindings.json.

Configuration file

The keybindings configuration file is an object with a bindings array. Each block specifies a context and a map of keystrokes to actions.
Changes to the keybindings file are automatically detected and applied without restarting Claude Code.
This example binds Ctrl+E to open an external editor in the chat context, and unbinds Ctrl+S:

Contexts

Each binding block specifies a context where the bindings apply: Before v2.1.205, a Doctor context and a doctor:fix action existed for the /doctor diagnostics screen.

Available actions

Actions follow a namespace:action format, such as chat:submit to send a message or app:toggleTodos to show the task list. Each context has specific actions available.

App actions

Actions available in the Global context:

History actions

Actions for navigating command history:

Chat actions

Actions available in the Chat context: *On Windows without VT mode (Node <24.2.0/<22.17.0, Bun <1.2.23), defaults to Meta+M.

Autocomplete actions

Actions available in the Autocomplete context:

Confirmation actions

Actions available in the Confirmation context: *On Windows without VT mode (Node <24.2.0/<22.17.0, Bun <1.2.23), defaults to Meta+M. Before v2.1.257, a confirm:toggleExplanation action, bound to Ctrl+E by default, showed a model-generated explanation of the command on Bash and PowerShell permission prompts. Dialogs use confirm:yes and confirm:no to accept and cancel even when they don’t ask a yes-or-no question. If you bind a bare letter such as y or n in this context, the letter also acts on dialogs that never show it as a key. A dialog that shows y and n as its keys reads those letters itself and needs no binding. In most dialogs, pressing Ctrl+C or Ctrl+D twice closes the dialog instead of exiting Claude Code. The hint after the first press says whether the second press closes the dialog or exits. Both keys are reserved and can’t be rebound. This example binds y to confirm:yes and n to confirm:no:
With these bindings, y and n still type as letters while a text field has focus. Before v2.1.280, y was also bound to confirm:yes and n to confirm:no by default. If you created your keybindings.json with /keybindings before v2.1.280, the file lists both bindings and they stay in effect until you delete those two lines.

Permission actions

Actions available in the Confirmation context for permission dialogs:

Transcript actions

Actions available in the Transcript context: transcript:toggleShowAll applies in the classic renderer only; in fullscreen rendering, the transcript viewer doesn’t offer a show-all toggle.

History search actions

Actions available in the HistorySearch context: The historySearch:next, historySearch:accept, historySearch:cancel, and historySearch:execute defaults apply to the inline history search in the classic renderer, which always searches prompts from all projects. historySearch:cycleScope takes effect only in fullscreen rendering, where Ctrl+R opens a search dialog instead and Ctrl+S cycles its scope. The dialog’s other keys are fixed and can’t be rebound: Enter or Tab places the highlighted match in the prompt input and Esc cancels.

Task actions

Actions available in the Task context:

Theme actions

Actions available in the ThemePicker context:

Help actions

Actions available in the Help context:

Tabs actions

Actions available in the Tabs context: In a tabbed dialog, tabs:next and tabs:previous switch tabs while the tab row has focus. In some dialogs, such as /help and /sandbox, the tab-switching keys also work from inside the tab’s content. Up and Down move focus between the tab row and the tab’s content, and a list in the content responds to keys only while it has focus.

Attachments actions

Actions available in the Attachments context: Actions available in the Footer context: While a footer item is selected, such as a row in the agent panel below the prompt, Enter opens it even when you rebind Enter in the Chat context to chat:queueSubmit or chat:newline. Chat bindings on keys the Footer context doesn’t bind, such as Shift+Tab for chat:cycleMode, keep working while an item is selected.

Message selector actions

In the message list of the rewind menu, you move through messages and pick one with the Select actions and their default keys. Your Select bindings for those actions apply there too. The MessageSelector context has no actions or default bindings of its own. Use it to change a key for this list alone, by binding a Select action such as select:accept in a MessageSelector block. This example binds o to pick the highlighted message in the rewind menu, without changing any other list:
Before v2.1.283, this list ignored Select bindings and had its own actions: messageSelector:up, messageSelector:down, messageSelector:top, messageSelector:bottom, and messageSelector:select. If your keybindings.json binds one of those names, the binding keeps working in this list as the Select action that does the same thing. Home and End jump to either end of the list; before v2.1.283, keys such as Shift+K and Shift+J did that by default.

Diff actions

These actions reach only Claude Code’s earlier diff viewer, which /diff opens outside fullscreen rendering after you disable the cc-plugin-diff mod in /plugin. While that mod is enabled, /diff opens the diff dialog instead. A keybindings.json that names these actions loads without errors either way. Actions available in the DiffDialog context: The file list also responds to the Select actions, through their default keys and your Select bindings. select:previous and select:next move to the previous and next file, and Enter opens the selected file’s diff through select:accept. To change one of those keys for the file list alone, bind the Select action in a DiffDialog block. Before v2.1.283, the file list ignored Select bindings, and Enter opened the selected file’s diff through a separate diff:viewDetails action. If your keybindings.json binds diff:viewDetails, the binding keeps working in the file list as select:accept. The diff detail view also binds pager-style keys to the standard scroll actions. These bindings are part of the DiffDialog context and apply only in the detail view; the Scroll context defaults listed under Scroll actions are unchanged.

Diff panel actions

Actions for the diff panel that /diff opens in fullscreen rendering. app:cycleDiffBase is in the DiffPanel context, which is active while the panel is open; the others are Global. The built-in cc-plugin-diff mod draws this panel and handles app:cycleDiffBase, app:diffFileListUp, and app:diffFileListDown. app:toggleReplTab, app:toggleDiffNoiseFilter, and app:toggleDiffPreSession reach only Claude Code’s earlier panel, which /diff opens after you disable cc-plugin-diff in /plugin.

Model picker actions

Actions available in the ModelPicker context:

Effort slider actions

Actions available in the EffortSlider context, the slider that opens when you run /effort with no arguments. The slider’s Enter and Escape keys can’t be rebound.

Select actions

Actions available in the Select context: In list panels such as /skills, /mcp, and /tasks, Claude Code applies your select:pageUp, select:pageDown, select:first, and select:last bindings. In most other lists, such as the /model picker, your select:first and select:last bindings apply. PageUp and PageDown page through the options in those lists regardless of your bindings. Before v2.1.280, those other lists ignored Home, End, and your select:first and select:last bindings. Before v2.1.283, the /mcp tool list paged with fixed PageUp and PageDown keys regardless of your bindings.

Plugin actions

Actions available in the Plugin context:

Settings actions

Actions available in the Settings context. The select:accept and confirm:no actions are reused from the Select and Confirmation contexts with Settings-specific behavior: changes apply to each setting as soon as you change it, so Escape closes the panel with your changes saved rather than declining.

Agents actions

Actions available in the Agents context, which applies in agent view, opened with claude agents. Requires v2.1.257 or later. While agent view is open, Claude Code uses the Agents binding for any key the Agents context binds, and it ignores a Chat or Global binding on the same key. For example, pressing Ctrl+S in agent view switches the session grouping rather than triggering the default chat:stash. The dispatch input’s external-editor shortcut isn’t an Agents action. Agent view follows the Chat context’s chat:externalEditor binding, Ctrl+G by default. Bindings fire on single keystrokes in agent view, so the Ctrl+X Ctrl+E chord bound to chat:externalEditor doesn’t open the editor there.

Voice actions

Actions available in the Chat context when voice dictation is enabled:

Scroll actions

Actions available in the Scroll context when fullscreen rendering is enabled:

Keystroke syntax

Modifiers

Use modifier keys with the + separator:
  • ctrl or control - Control key
  • shift - Shift key
  • alt, opt, option, or meta - Alt key on Windows and Linux, Option key on macOS
  • cmd, command, super, or win - Command key on macOS, Windows key on Windows, Super key on Linux
The cmd group is only detected in terminals that report the Super modifier, such as those supporting the Kitty keyboard protocol or xterm’s modifyOtherKeys mode. Most terminals do not send it, so use ctrl or meta for bindings you want to work everywhere. For example:

Uppercase letters

Claude Code parses key names case-insensitively, so K is the same binding as k and ctrl+K is the same as ctrl+k. To bind Shift and a letter, write shift+k.

Non-US keyboard layouts

Write the key names of Ctrl shortcuts as Latin characters even when your active keyboard layout types other characters. How Claude Code matches the key you press to a binding depends on the kind of layout:
  • Under a non-Latin layout such as Cyrillic, Claude Code matches Ctrl shortcuts by the key’s US-layout position when the terminal uses the Kitty keyboard protocol and reports that position. In such a terminal, with a Russian layout active, pressing Ctrl and the physical W key triggers ctrl+w. In a terminal that doesn’t report the position, Claude Code matches whatever the terminal sends for the keypress: an ASCII control code triggers the Latin shortcut, and a keypress that arrives as the Cyrillic character matches no binding
  • Under layouts that rearrange Latin letters, such as AZERTY, Claude Code matches the letter that the key types, so pressing Ctrl and the key labeled A triggers ctrl+a

Chords

Chords are sequences of keystrokes separated by spaces:
Press each keystroke within 3 seconds of the one before it. If you wait longer, Claude Code cancels the chord and shows a brief notice saying so.

Special keys

  • escape or esc - Escape key
  • enter or return - Enter key
  • tab - Tab key
  • space - Space bar
  • up, down, left, right - Arrow keys
  • pageup, pagedown - Page Up and Page Down keys
  • home, end - Home and End keys
  • backspace, delete - Delete keys
  • wheelup, wheeldown - Mouse wheel scroll events

Unbind default shortcuts

Set an action to null to unbind a default shortcut:
This also works for chord bindings. Unbinding every chord that shares a prefix frees that prefix for use as a single-key binding. A chord in any active context keeps its prefix reserved, so you must unbind each chord in the context that defines it. Claude Code binds these default chords on the ctrl+x prefix, by context:
  • Chat: ctrl+x ctrl+k, ctrl+x ctrl+e, ctrl+x enter, ctrl+x ctrl+a, ctrl+x ctrl+s, and ctrl+x tab
  • Task: ctrl+x ctrl+b
  • DiffPanel: ctrl+x b
  • Pane: ctrl+x left, ctrl+x right, ctrl+x up, ctrl+x down, and ctrl+x x
  • PaneField: ctrl+x x
The ctrl+x enter chord requires v2.1.247 or later, ctrl+x b, ctrl+x ctrl+a, and ctrl+x tab require v2.1.260 or later, and ctrl+x ctrl+s requires v2.1.275 or later. To reclaim ctrl+x itself as a single-key binding, unbind all of them:
If you unbind some but not all chords on a prefix, pressing the prefix still enters chord-wait mode for the remaining bindings.

Reserved shortcuts

These shortcuts cannot be rebound:

Terminal conflicts

Some shortcuts may conflict with terminal multiplexers:

Text fields

If you bind a bare letter, digit, or Space, you can still type that character in a text field inside a dialog or panel. One such field is the Other answer to a question Claude asks. While the field has focus, a printable key you press without Ctrl, Alt, or Cmd goes to the field, and Claude Code doesn’t match it against your bindings. These keys still run their bindings while the field has focus:
  • Keys that don’t type a character, such as Enter, Escape, Tab, and the arrow keys
  • Any key pressed with Ctrl, Alt, or Cmd
  • The second keystroke of a chord already in progress
At the main prompt, Claude Code matches every key against the active contexts, such as Chat, and types the key only when no binding takes it.

Vim mode interaction

When vim mode is enabled via /config → Editor mode, keybindings and vim mode operate independently:
  • Vim mode handles input at the text input level (cursor movement, modes, motions)
  • Keybindings handle actions at the component level (toggle todos, submit, etc.)
  • The Escape key in vim mode switches INSERT to NORMAL mode; it does not trigger chat:cancel
  • Most Ctrl+key shortcuts pass through vim mode to the keybinding system
  • Vim keys aren’t remappable through the keybindings file. To map a two-key INSERT-mode sequence such as jj to Escape, use the vimInsertModeRemaps setting
  • In vim NORMAL mode, ? shows the help menu (vim behavior)
  • In vim NORMAL mode, / opens history search, the same as Ctrl+R in standard mode

Validation

Claude Code validates your keybindings and writes a warning to the debug log for:
  • Parse errors (invalid JSON or structure)
  • Misspelled modifiers, such as ctl+k. Claude Code drops the part it doesn’t recognize and applies the binding to the keystroke that remains, k in this example.
  • Invalid context names
  • Invalid action values, such as an action that isn’t a string or null
  • Unknown action names, such as a typo of a registered action. Claude Code skips the binding and keeps any default binding for that key in effect.
  • Reserved shortcut conflicts
  • Duplicate bindings in the same context
Start Claude Code with --debug to see the details.