Omniscio

OmniscioGuidesClaude Code keyboard shortcuts

Claude Code keyboard shortcuts and keybindings.json

Claude Code ships a fixed set of keystrokes and one file that changes them: ~/.claude/keybindings.json. The file is an object with a bindings array, each block naming a context such as Chat and mapping a keystroke to an action such as chat:submit. Setting an action to null removes a default binding, and a saved change applies without restarting. This page is the keystroke layer: the shortcut tables by context, the action names you can bind, the keys that cannot be rebound, the terminal settings several shortcuts depend on, and what the file quietly ignores.

Checked against Anthropic’s Claude Code 2.1.312. Sources read October 29, 2026. By the Omniscio team.

The short version

Three facts answer most of what people arrive with. The default keystrokes are documented and stable enough to learn. The file at ~/.claude/keybindings.json changes them, and a saved change applies without restarting Claude Code. And a shortcut that still does nothing is usually a mismatch between the context you bound and the context you are in, or a key Claude Code reserves.

Then pick the line that matches your situation:

The shortcuts, by where you are

Claude Code matches a keypress against the context that currently has focus, which is why the same key can mean two things. The tables below start with the keys that work everywhere, then the ones that only work inside a particular surface. Anthropic’s own note leads the list: shortcuts vary by platform and terminal, and in fullscreen rendering you can press ? in the transcript viewer to see the ones available there.

General controls

ShortcutWhat it does
Ctrl+CInterrupts a running operation. With nothing running, the first press clears the prompt and a second press exits.
EscStops the current response or tool call so you can redirect, keeping the work done so far. With a dialog open it closes the dialog; on a permission prompt it declines.
Esc EscWith text in the prompt, clears it and keeps the draft in history. With an empty prompt, opens the rewind menu.
Ctrl+DExits the session: first press shows a confirmation hint, a second within 800ms exits. With text in the prompt it deletes the character after the cursor instead.
Ctrl+LForces a full terminal redraw, keeping your input and the conversation.
Ctrl+OToggles the transcript viewer, which shows detailed tool usage and a timestamp and model on each assistant message.
Ctrl+TToggles Claude’s to-do checklist in the status area. This is not the background-task view, which is /tasks.
Ctrl+RReverse-searches your command history.
Ctrl+BBackgrounds a Bash command or an agent. In tmux you press it twice, because it is tmux’s prefix.
Ctrl+SStashes the prompt. On an empty prompt, restores the stashed text, cursor position and input mode.
Ctrl+G / Ctrl+X Ctrl+EOpens your prompt in your default text editor. Ctrl+X Ctrl+E is the readline-native form.
Ctrl+VPastes an image from the clipboard as an [Image #N] chip. On Windows the key is Alt+V; on WSL both Ctrl+V and Alt+V are bound, so use Alt+V if your terminal takes Ctrl+V for itself. In iTerm2 it is Cmd+V.
Ctrl+ZSuspends Claude Code to your shell on Unix only. Run fg to resume.
Shift+TabCycles permission modes. On Windows without VT input mode the default becomes Alt+M.
Option+P / Alt+PSwitches model without clearing your prompt.
Option+T / Alt+TToggles extended thinking. It has no effect on Opus 5.5, Sonnet 5.5, Haiku 5.5 or the Fable models, which always use it.
Option+O / Alt+OToggles fast mode.
Ctrl+X Ctrl+KStops every running background subagent in this session and turns off artifact auto-replies for the rest of it. Press twice within 3 seconds to confirm.
Ctrl+Enter / Ctrl+X Ctrl+SSends your queued messages right away, plus the draft. Terminals that do not report extended keys deliver Ctrl+Enter as plain Enter, so the chord is the one that works anywhere.
Up / Down / Ctrl+P / Ctrl+NMoves the cursor inside a multi-row prompt first, then walks command history once the cursor is on the first or last row.
Left / RightCycles tabs in permission dialogs and menus while the tab row has focus.
?On an empty prompt, toggles the shortcut help panel. In fullscreen rendering this also works inside the transcript viewer.

The keys you type with

ShortcutWhat it does
Ctrl+A / Ctrl+EMove the cursor to the start or end of the current logical line.
Ctrl+KDeletes to the end of the line and stores the text for pasting.
Ctrl+UDeletes from the cursor to the line start. Repeat across lines in a multiline prompt.
Ctrl+WDeletes back to the previous whitespace, so one press removes a whole path or --flag=value.
Ctrl+YPastes the text you last deleted with one of the shortcuts above.
Alt+YAfter pasting, cycles through earlier deleted text.
Alt+B / Alt+FMoves the cursor back or forward one word.
Alt+DDeletes to the end of the word.
Ctrl+_ / Ctrl+Shift+-Undoes the last input edit, restoring the previous text and cursor position.

Two details matter when a word shortcut surprises you. A word is a run of letters and digits, so punctuation separates words: with src/utils/foo.ts in the prompt, Alt+B stops at the start of ts, foo, utils and src, while Ctrl+W ignores punctuation and removes the whole path in one press. From 2.1.261 onwards the word shortcuts follow these readline rules, and the earlier keybindingFlavor setting is deprecated and has no effect. The word shortcuts cannot be remapped, because the keybindings file has no actions for them; undo can, through chat:undo.

Five ways to start a new line

MethodKeysWhen it works
Quick escape\ then EnterEvery terminal, no setup.
Control sequenceCtrl+JEvery terminal, no setup.
ShiftShift+EnterNative in iTerm2, WezTerm, Ghostty, Kitty, Warp, Apple Terminal and Windows Terminal. Elsewhere it needs a terminal setting or /terminal-setup.
OptionOption+EnterAfter turning on Option as Meta on macOS.
Pastepaste directlyFor a code block or a log.

Quick keys and the surfaces behind them

Where you areKeys worth knowing
The prompt/ for commands and skills, ! for shell mode, @ for a file path, : for an emoji shortcode, ? on an empty prompt for the help panel.
Autocomplete openTab accepts the suggestion, Esc dismisses the menu, Up and Down move through it.
A confirmation dialogEnter confirms, Esc declines, Up and Down move between the options, and Space toggles a selection. On most permission prompts, Tab opens a comment field on the focused Yes or No. In the /fast dialog, Tab turns fast mode on or off.
Any listDown, J or Ctrl+N moves down, Up, K or Ctrl+P moves up, Home and End jump to either end, Enter picks.
The transcript viewerCtrl+E toggles show-all in the classic renderer, { and } jump between prompts in fullscreen, [ writes the conversation to native scrollback, v opens it in your editor, and q, Ctrl+C or Esc exits.
The footer under the promptLeft and Right move between items, Enter opens the selected one, Esc clears the selection, x stops the selected agent or workflow.
The settings panel/ enters search mode, Enter or Space changes a setting or opens its submenu, Esc closes with your changes already saved.
Scrolled up in fullscreenPgUp and PgDn scroll half a screen, Ctrl+Home jumps to the start, Ctrl+End returns to the latest message and re-enables auto-follow.

Rebind one: the file, in ninety seconds

Run /keybindings and Claude Code opens ~/.claude/keybindings.json, creating it if it is not there yet. That is your Claude Code configuration directory, which is ~/.claude unless you moved it with CLAUDE_CONFIG_DIR; on Windows the default is %USERPROFILE%\.claude. The file is an object with a bindings array. Each entry names one context and holds a map from a keystroke to an action, and the action names follow a namespace:action shape such as chat:submit.

{
  "$schema": "https://www.schemastore.org/claude-code-keybindings.json",
  "$docs": "https://code.claude.com/docs/en/keybindings",
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "ctrl+e": "chat:externalEditor",
        "ctrl+s": null
      }
    }
  ]
}

That example does two useful things at once. ctrl+e is given to chat:externalEditor, and ctrl+s is set to null, which removes the default stash binding rather than replacing it. The optional $schema line gives your editor autocompletion for the action names, and $docs is a documentation pointer for whoever opens the file next. Save it, and the change applies without restarting Claude Code, because the file is watched.

The context decides when your key fires

A context is a place that can hold keyboard focus, and a binding in one context does nothing in another. These are the ones Anthropic documents, and the list is the fastest way to see why a binding feels dead:

ContextWhere focus is
GlobalEverywhere in the app. The interrupt and exit keys live here.
ChatThe main prompt. Most bindings people write belong here.
AutocompleteWhile a suggestion menu is open over the prompt.
ConfirmationPermission and confirmation dialogs.
SettingsThe settings panel.
Tabs and HelpA tabbed dialog’s tab row, and the help menu while it is visible.
TranscriptThe transcript viewer behind Ctrl+O.
HistorySearchHistory search, the Ctrl+R surface.
TaskA task running in the foreground.
ThemePickerThe theme dialog.
AttachmentsNavigating attached images in a select dialog.
FooterThe indicator row under the prompt: tasks, teams, diff, artifacts.
MessageSelectorChoosing a message in the rewind and summarize dialog.
DiffDialog and DiffPanelThe diff viewer, and the diff panel that /diff opens in fullscreen.
ModelPicker and EffortSliderThe model picker, and the slider /effort opens with no argument.
SelectAny generic list, including the ones the other contexts borrow from.
PluginThe plugin dialog.
AbovePrompt, AbovePromptInput, AbovePromptSelectThe band above the prompt, and the fields and selects in it.
Pane and PaneFieldA pane a mod drew, and the fields inside it.
AgentsAgent view, which claude agents opens.
ScrollScrolling and text selection in fullscreen rendering.

Two footnotes keep that table honest. Agent view arrived with Claude Code 2.1.257, and while it is open it takes its own bindings ahead of a Chat or Global binding on the same key, so Ctrl+S switches the session grouping there instead of stashing your prompt. And a handful of action names still load without error even though Claude Code does nothing with them, such as confirm:previousField and permission:toggleDebug, so an old file can name one and keep working.

What you can bind: the action names

You cannot invent an action. The file accepts the names Anthropic documents, and binds them by namespace, so the list is worth skimming before you reach for a key. Every row below is bindable today, and the default column is what happens if you never touch the file.

ActionDefaultWhat it does
app:interruptCtrl+CCancel the current operation.
app:exitCtrl+DExit Claude Code, twice within 800ms to confirm.
app:redrawunboundForce a terminal redraw.
app:toggleTodosCtrl+TToggle the to-do checklist.
app:toggleTranscriptCtrl+OToggle the verbose transcript.
history:searchCtrl+ROpen history search.
history:previous / history:nextUp / DownWalk command history.
chat:submitEnterSubmit the message.
chat:queueSubmitCtrl+X EnterSubmit the draft to wait its turn instead of interrupting. Needs 2.1.247 or later.
chat:sendNowCtrl+Enter, Ctrl+X Ctrl+SSend the queued messages and the draft immediately. Needs 2.1.275 or later.
chat:newlineCtrl+JInsert a newline without submitting.
chat:cancelEscCancel the current input.
chat:clearInput / chat:clearScreenCtrl+L / Cmd+KRedraw the screen, keeping the input and the conversation.
chat:killAgentsCtrl+X Ctrl+KStop every background subagent in the session, twice within 3 seconds to confirm.
chat:cycleModeShift+TabCycle permission modes.
chat:modelPickerMeta+POpen the model picker.
chat:fastMode / chat:thinkingToggleMeta+O / Meta+TToggle fast mode, and extended thinking.
chat:undoCtrl+_, Ctrl+Shift+-Undo the last input edit.
chat:externalEditorCtrl+G, Ctrl+X Ctrl+EOpen the prompt in your editor.
chat:stashCtrl+SStash the current prompt.
chat:imagePasteCtrl+V (Alt+V on Windows and WSL)Paste an image from the clipboard.
command:<name>unboundRun any slash command. meta+g bound to command:compact makes Meta+G run /compact.
autocomplete:acceptTabAccept the highlighted suggestion.
confirm:yes / confirm:noEnter / EscConfirm or decline a dialog. Before 2.1.280 the letters y and n were bound to these as well, and a file created before then keeps both lines until you delete them.
select:next / select:previousDown / UpMove through a list, with J, K, Ctrl+N and Ctrl+P accepted too.
settings:search/Enter search mode in the settings panel.
task:backgroundCtrl+B, Ctrl+X Ctrl+BBackground the running task.
transcript:toggleShowAllCtrl+EShow all content in the classic transcript renderer.
voice:pushToTalkSpaceDictate a prompt, when voice dictation is enabled.

Chords, modifiers and the odd key you forgot you had

A keystroke is written in lowercase with + between modifiers. ctrl and control both work, as do alt, opt, option and meta for the same physical key, which is Alt on Windows and Linux and Option on macOS. Case does not matter to the parser, so K is k; to require Shift with a letter, write shift+k.

Two traps sit in that paragraph. The cmd, command, super and win names only work in a terminal that reports the Super modifier, such as one using the Kitty keyboard protocol or xterm’s modifyOtherKeys mode; most terminals never send it, so a cmd binding is invisible on them and ctrl or meta is the portable choice. And the special key names are a fixed list: escape or esc, enter or return, tab, space, the four arrows, pageup, pagedown, home, end, backspace, delete, and the mouse-wheel events wheelup and wheeldown.

A chord is a sequence of keystrokes separated by spaces, such as ctrl+k ctrl+s. Press each part within 3 seconds of the one before it: wait longer and Claude Code cancels the chord and says so. Unbinding every chord that shares a prefix frees that prefix, which is the only way to reuse ctrl+x as a single key, because Claude Code ships several ctrl+x chords across different contexts.

What the file cannot change

Anthropic’s reserved table has seven rows. Ctrl+C is the hardcoded interrupt and Ctrl+D the hardcoded exit. Ctrl+M always arrives as Enter. Ctrl+[ always arrives as Escape, which needs 2.1.242 or later in a terminal using the Kitty protocol. Ctrl+I always arrives as Tab. Ctrl+H sends the ASCII backspace byte, and how Claude Code reads it on Windows depends on your terminal and the CLAUDE_CODE_BS_AS_CTRL_BACKSPACE environment variable. Caps Lock is the seventh: a terminal application never receives it.

Three more keys are not reserved but are likely to be taken by something else. Ctrl+B is the tmux prefix, so inside tmux you press it twice to send it through. Ctrl+A is the GNU screen prefix. Ctrl+Z is the Unix suspend signal, which is why it stops Claude Code rather than doing anything inside it.

And the whole text-editing table is out of reach: the keybindings file carries no actions for Ctrl+A, Ctrl+E, Ctrl+K, Ctrl+U, Ctrl+W, Ctrl+Y, Alt+B, Alt+F and Alt+D, so there is nothing to map them to. The undo row of that table is the one exception with an action of its own, chat:undo. Vim mode works the same way in reverse: when you turn it on with the Editor mode setting in /config, vim handles input at the text level and the keybindings file handles actions at the component level, and the two do not overlap. In vim mode Esc leaves INSERT for NORMAL and does not trigger chat:cancel, and vim keys themselves cannot be remapped through the file; a two-key INSERT-mode sequence such as jj needs the vimInsertModeRemaps setting instead.

When a binding does nothing

Claude Code checks the file every time it loads and writes a warning to the debug log rather than failing loudly, which is why a broken binding feels like silence. Start it with --debug to read those warnings. The causes Anthropic lists, in the order worth checking:

What you wroteWhat Claude Code doesThe fix
Invalid JSON, or the wrong structureWrites a warning to the debug logCheck the braces, then the bindings array inside the object
A misspelled modifier such as ctl+kDrops the part it does not recognise and binds what is left, so the key becomes plain kSpell the modifier in full
A space beside the plus, such as ctrl+ kReads it as a chord of ctrl+ then k, and no keypress ever matches ctrl+Remove the space
A context name that does not existWrites a warning to the debug logUse a name from the context table above
An action that is not a string or nullWrites a warning to the debug logQuote the action name
A misspelled action nameSkips the binding and keeps the default for that keyCheck the name against the action table
A reserved keyWrites a warning to the debug log, and the key keeps its reserved behaviourBind a different key to the action
Two bindings for one key in one contextWrites a warning to the debug logKeep one line

One case looks like a bug and is not. A binding on a bare letter, digit or Space does not steal typing inside a text field, such as the Other answer to a question Claude asks: while that field has focus, a printable key without Ctrl, Alt or Cmd goes to the field and never reaches your binding. Keys that type nothing, like Enter and Esc, and any key pressed with a modifier, still fire.

The terminal settings several shortcuts depend on

On macOS, most terminals do not send Option as a modifier by default, which is why Option+P, Option+Enter and the Alt+B, Alt+F and Alt+D word keys do nothing on a fresh setup. The terminal setting is usually labelled “Use Option as Meta Key”, and the location differs by terminal:

  • Apple Terminal: Settings, then Profiles, then Keyboard, then “Use Option as Meta Key”. Accepting Claude Code’s first-run prompt does this for you through /terminal-setup, which also turns off the audible bell.
  • iTerm2: Settings, then Profiles, then Keys, then General, and set both the Left and Right Option key to “Esc+”. Running /terminal-setup here also lets applications read the clipboard, which the /copy command needs.
  • VS Code: add "terminal.integrated.macOptionIsMeta": true to your settings.
  • Ghostty, Kitty and others: look for an Option-as-Alt or Option-as-Meta setting in the terminal’s own configuration.

Shift+Enter has its own map. It works with no setup in Ghostty, Kitty, iTerm2, WezTerm, Warp, Apple Terminal and Windows Terminal, and in other terminals that speak the kitty keyboard protocol, such as foot and Alacritty 0.16 or later, from Claude Code 2.1.269 onwards. In VS Code, Cursor, Devin Desktop, Alacritty before 0.16 and Zed it needs /terminal-setup once, which writes a Shift+Enter keybinding into that terminal’s own configuration file; in Zed it backs up your keymap.json first if it has to change it. It is not available at all in gnome-terminal or the JetBrains IDEs, where Ctrl+J and the backslash trick remain. And inside tmux, Shift+Enter needs the tmux configuration even when the outer terminal supports it.

Fullscreen rendering brings its own scroll keys, and a MacBook keyboard is a known gap. PgUp and PgDn move half a screen, Ctrl+Home jumps to the start and Ctrl+End returns to the latest message, and on a keyboard without those keys you send them with Fn plus an arrow. Ctrl+Fn+Right does not reach Claude Code on macOS, so a MacBook has no working jump-to-bottom chord unless you bind scroll:bottom to something your keyboard can send. Cmd+K behaves like Ctrl+L wherever the terminal passes it through, while iTerm2 and Terminal.app handle Cmd+K themselves and clear their own screen.

In the VS Code extension

The extension ships its own command shortcuts, and several of them depend on which panel has focus: your cursor in a code file means the editor is focused, your cursor in the prompt box means Claude is. These are the ones worth learning.

CommandmacOSWindows and Linux
Move focus between the editor and ClaudeCmd+EscCtrl+Esc
Open a new conversation as an editor tabCmd+Shift+EscCtrl+Shift+Esc
Start a new conversationCmd+NCtrl+N
Reopen the last closed Claude session tabCmd+Shift+TCtrl+Shift+T
Insert a reference to the current file and selectionOption+KAlt+K
Hide or show tool activityCtrl+Option+FCtrl+Alt+F

Two of those rows are conditional. Cmd+N or Ctrl+N only starts a conversation while Claude has focus and the enableNewConversationShortcut setting is on, because it is off by default; the reopen shortcut is on by default and can be turned off with enableReopenClosedSessionShortcut. On macOS Tahoe and later the system Game Overlay is bound to Cmd+Esc and intercepts it before VS Code sees it, so either clear the Game Overlay checkbox under System Settings, then Keyboard, then Keyboard Shortcuts, then Game Controllers, or rebind “Claude Code: Focus input” in the editor’s own Keyboard Shortcuts editor.

The extension also reads your keybindings.json, from version 2.1.309 onwards. That is what makes the common “stop Ctrl+J adding a newline” fix work: set "ctrl+j": null in a Chat block, save, and the prompt box stops inserting the line. If it still inserts one, reload the editor window and check the extension log for a warning that names the file it read, because an older extension ignores the file entirely.

What other people are reporting

The issue tracker carries the same confusion this page is about, and the reports below are their authors’ own descriptions, linked with the state and counts the issue showed on the day this page was checked. None of them is an Anthropic statement.

  • Issue 25087, opened 2026-02-11 and closed 2026-08-18, 56 reactions and 18 comments: keybindings.json ignored in the Claude desktop app, with Enter and Shift+Enter both submitting. It is a reminder that the file configures the surfaces that read it, and the desktop app is not the CLI.
  • Issue 90878, opened 2026-08-31 and still open, 8 reactions and 3 comments: the same complaint, filed again and marked by its author as a duplicate of the closed report and of #33034.
  • Issue 64804, opened 2026-06-02 and still open, 7 reactions and 12 comments: Enter inserts a newline instead of submitting, and the keybindings.json override is ignored.
  • Issue 87888, opened 2026-08-19 and still open, 3 reactions and 3 comments: Ctrl+Enter and Shift+Enter never reach the keybinding matcher under Windows Terminal, and a Ctrl+J rebind is ignored. That is the terminal-delivery problem, not a file problem.
  • Issue 3464, opened 2025-07-14 and closed the next day, 15 reactions and 9 comments: Shift+Tab not working in Windows Terminal, which is the same class as the Alt+M fallback on Windows without VT input mode.

Read together they split in two. The first three are about a surface not reading the file at all, and the last two are about a terminal not delivering the key, which no binding can fix. Both halves point at the same first check: confirm the surface, then confirm the terminal, before editing the file a third time.

Where this page stops

  • Which settings file wins. keybindings.json is not one of the four settings files, and it has no precedence question of its own. The locations and the order that decides a collision are covered by the settings.json guide.
  • What each permission mode does. Shift+Tab appears here as one row, because it is a keystroke. The modes themselves belong to the permission modes guide and, for the planning half, to the plan mode guide.
  • Queueing, dictation and copy-paste. The chords that queue and force a message are one row in each table; the copy and paste guide owns the clipboard; the message queue guide covers queueing, and the voice dictation guide covers speech input.
  • Why the app misbehaves. A key that fails inside the extension is an extension problem rather than a binding problem, which is the VS Code extension guide.

Omniscio, and the other set of shortcuts

Omniscio runs Claude Code sessions, and it has a shortcut system of its own. The two are separate: ~/.claude/keybindings.json configures Claude Code’s own interface, while Omniscio’s keys drive the app around it, and rebinding one does not change the other. Omniscio collects its bindings in a registry with a default per action, and you rebind them in Settings → Keyboard Shortcuts.

  • Its own registry. Every Omniscio shortcut is a declared action with a default binding, gathered into one action list, and your overrides are merged over the defaults at runtime rather than editing them in place. The full list, grouped by where each key applies, is on the keyboard shortcuts page.
  • What the backup carries. The backup mirror captures ~/.claude/settings.json and ~/.claude/keybindings.json under a narrow allowlist, so a restore on another machine brings your Claude Code bindings with it. A Replace restore overwrites them with the backed-up copies; a Merge restore leaves any settings.json or keybindings.json already on this machine untouched, whether you edited it or not. Omniscio’s own shortcuts never go into either file.
  • Only the home folder. The mirror only reads ~/.claude in your home folder and ignores CLAUDE_CONFIG_DIR, so a keybindings.json kept in a moved config folder is never backed up, and a restore cannot bring it back. The backup mirror page covers what the allowlist carries and what it deliberately leaves out.
  • The inbuilt terminal is a shell, not a prompt. Omniscio’s inbuilt terminal, off until its Labs flag is on, translates Alt plus Left or Right, and Alt plus Backspace or Delete, into the readline sequences that word-wise editing uses, so those keys work in a shell running inside it. It does not turn that shell into Claude Code’s prompt, and no Omniscio setting changes what keybindings.json does.

If you came here looking for one place to change every shortcut on your machine, that place does not exist: Claude Code’s file covers Claude Code, and Omniscio’s Settings covers Omniscio. The good news is that neither needs a restart, and running several sessions at once does not change either one, because the bindings follow the surface rather than the window.

Sources

Every Claude Code behaviour on this page rests on one of these, and each was read on the date beside it.

  • Customize keyboard shortcuts, for the file, the contexts, every action and its default, the keystroke syntax, the reserved keys, the terminal conflicts and the validation warnings. Read October 29, 2026.
  • Interactive mode, for the general controls, the text-editing keys and their word rules, the multiline methods, the quick keys, the transcript viewer keys and the macOS Option note. Read October 29, 2026.
  • Terminal configuration, for Option as Meta in each terminal, the Shift+Enter support table, what /terminal-setup writes, and the tmux requirement. Read October 29, 2026.
  • Fullscreen rendering, for the scroll keys, the MacBook keyboard gap and how Cmd+K behaves in iTerm2 and Terminal.app. Read October 29, 2026.
  • VS Code extension, for the extension’s command shortcuts, the settings that gate two of them, the macOS Tahoe interception and the 2.1.309 floor for reading keybindings.json. Read October 29, 2026.
  • Commands, for what /keybindings does. Read October 29, 2026.
  • Settings, for what ~/.claude means on Windows. Read October 29, 2026.
  • The five issue pages linked above, each read on October 29, 2026, with its state, reaction count and comment count taken from the issue itself.
  • Omniscio’s own keyboard shortcuts page, backup mirror page and inbuilt terminal page, read on October 29, 2026, and the source files named in the fact ledger.
  • Three captures on this machine on October 29, 2026: claude --version, which printed 2.1.312 (Claude Code); claude --help, whose 314 lines list -d, --debug [filter]; and a file check of ~/.claude, which holds 11 entries including CLAUDE.md but neither settings.json nor keybindings.json.

This layer moves with every release. Anthropic adds actions, retires a context, and changes a default for a version or two, so treat the version at the top of this page as the one the table describes and re-read the keybindings page before trusting a copy from last month.

How we tested this

Every statement about Anthropic’s Claude Code was read from Anthropic’s own documentation on October 29, 2026, on the keybindings, interactive mode, terminal configuration, fullscreen, VS Code, settings and commands pages, against the release the npm registry listed that day, 2.1.312, which is also what claude --version printed on this machine. No keybindings file was edited to write the page and no session was reconfigured, so the behaviour described is Anthropic’s account of it rather than a run of our own. The five issue reports are quoted from their authors. The Omniscio statements were read from the library pages and source files the fact ledger names.

Common questions

Which file holds Claude Code keyboard shortcuts?

~/.claude/keybindings.json. Running /keybindings inside a session creates the file if it is missing and opens it if it is not. On Windows that path is %USERPROFILE%\.claude\keybindings.json, and CLAUDE_CONFIG_DIR moves it with the rest of the config directory. The file is an object with a bindings array, and each block in that array names a context such as Chat and maps a keystroke to an action such as chat:submit. It is a separate file from settings.json, which holds permissions, hooks and the model.

How do I rebind a Claude Code shortcut?

Open ~/.claude/keybindings.json, add a block whose context is the one you are in, and map a keystroke to an action name, such as ctrl+e to chat:externalEditor in the Chat context. Save the file and the change applies without restarting Claude Code. Set the action to null to remove a default binding. You cannot invent an action: the file only accepts the action names Anthropic documents, and a misspelling is skipped with a warning in the debug log.

Why does a binding in keybindings.json do nothing?

Two kinds of cause. Claude Code writes a debug-log warning, visible when you start it with --debug, for eight problems: invalid JSON or structure, a misspelled modifier, a space next to a plus sign, an invalid context name, an action that is not a string or null, an unknown action name, a reserved-shortcut conflict, and a duplicate binding in one context. The other kind is a binding in a valid context you are not in: it logs nothing, because it is not an error. The key simply means something else in the context that has focus.

Can I remap Ctrl+C, Ctrl+D or Ctrl+M?

No. Anthropic lists seven reserved shortcuts: Ctrl+C is the hardcoded interrupt, Ctrl+D the hardcoded exit, Ctrl+M always arrives as Enter, Ctrl+[ as Escape, Ctrl+I as Tab, Ctrl+H sends the backspace byte, and Caps Lock is never delivered to a terminal application. All seven are outside the keybindings file, so the fix for an awkward shortcut is to bind a different key to the action rather than to move the reserved one.

Do the shortcuts work in the VS Code extension?

The extension has its own command shortcuts, such as Cmd+Esc or Ctrl+Esc to move focus between the editor and Claude, Cmd+Shift+Esc or Ctrl+Shift+Esc for a new conversation tab, and Option+K or Alt+K to insert a reference to the current file and selection. It reads the keybindings file from version 2.1.309 or later, which is why unbinding Ctrl+J there needs an up-to-date extension first.

Keep the keystrokes you already know

Omniscio runs Claude Code sessions side by side, with its own rebindable keys in Settings, and a backup mirror that carries your keybindings.json with the rest of your Claude config — as long as the file lives in your home ~/.claude folder. The features page covers the rest, and you can download it for Windows, macOS or Linux. If the shortcut you are missing is about what you can type, the settings guide covers the files beside this one, and the tmux guide covers the terminal multiplexer whose prefix, Ctrl+B, you press twice to reach Claude Code.