Cursor Basics
Cursor keybindings.json: When Clauses, Chords and Recipes
Cursor reads the same keybindings.json as VS Code: run Preferences: Open Keyboard Shortcuts (JSON) from the command palette. Each entry pairs a key with a command and an optional when clause that scopes it by context. One Cursor-specific difference matters most: the chord leader is ⌘R on Mac (CtrlM on Windows/Linux), because ⌘K drives inline edit.

On this page
Where is keybindings.json in Cursor?
Cursor is a VS Code fork, so the whole keybinding system carries over: a Keyboard Shortcuts UI for point-and-click remapping, and a keybindings.json file for anything precise. Open either from the command palette (⌘Ctrl⇧P):
- 1Run Preferences: Open Keyboard Shortcuts for the searchable UI. Every Cursor binding, including the AI features, can be remapped here.
- 2Run Preferences: Open Keyboard Shortcuts (JSON) to edit
keybindings.jsondirectly. Entries in this file win over the defaults. - 3Right-click any row in the UI and choose Copy Command ID when you need the exact command name for a JSON entry. That beats guessing.
[
{
"key": "ctrl+alt+r",
"command": "workbench.action.reloadWindow",
"when": "editorTextFocus"
}
]Do those three in that order, even when you already know the command you want.
Copy Command ID gets you the exact string without typing it from memory, and searching the UI by key shows everything already bound to that key with each one's when clause. Neither of those is visible from inside the file.
Where the file lives also decides how a team shares bindings. The obvious move is to send someone your keybindings.json. That is not quite the right unit. It is a per-user file in Cursor's own user-data directory, so what travels well is the three or four entries and their command IDs, pasted wherever your team already reads things. The whole file carries every private remap the sender ever made, and Mac chord keys are not the keys a Windows colleague presses.
Cursor's own shortcut doc confirms the scope: "All Cursor keybindings, including Cursor-specific features, can be remapped in Keyboard Shortcuts settings." What it does not document is the when system that decides when a binding is live. That part comes from the VS Code layer underneath, and it is where most broken bindings go wrong.
This is covered hands-on in Cursor First Hour — 4 short Units, free to read.
Rather do it than read about it? Run 11 interactive Cursor walkthroughs in a simulated editor. Free, no account needed.
How do when clauses work?
A when clause is a boolean expression over context keys: live flags the editor maintains about focus, selection, mode and UI state. No when means the binding is global. With one, the shortcut only fires while the expression is true, which is how the same key can safely mean different things in the editor, the terminal and a chat input.
- Operator
- &&
- Meaning
- and
- Example
- editorTextFocus && editorHasSelection
- Operator
- ||
- Meaning
- or (lowest precedence)
- Example
- terminalFocus || panelFocus
- Operator
- !
- Meaning
- not
- Example
- editorTextFocus && !editorReadonly
- Operator
- == / !=
- Meaning
- equality against a value
- Example
- editorLangId == 'typescript'
- Operator
- =~
- Meaning
- regex match
- Example
- resourceFilename =~ /\.test\.ts$/
- Operator
- in / not in
- Meaning
- membership in a list-valued key
- Example
- resourceFilename in supportedFiles
| Operator | Meaning | Example |
|---|---|---|
| && | and | editorTextFocus && editorHasSelection |
| || | or (lowest precedence) | terminalFocus || panelFocus |
| ! | not | editorTextFocus && !editorReadonly |
| == / != | equality against a value | editorLangId == 'typescript' |
| =~ | regex match | resourceFilename =~ /\.test\.ts$/ |
| in / not in | membership in a list-valued key | resourceFilename in supportedFiles |
Operator set from the VS Code when-clause reference; precedence is ! over && over ||.
The precedence line under that table is the part worth slowing down on. Because || binds loosest, editorTextFocus && editorLangId == 'typescript' || terminalFocus parses as (editor and TypeScript) or terminal, so the binding fires in the terminal too. Split an expression like that into two entries with the same key and command and one condition each. Longer file, easier to read six months later.
- editorTextFocus
- Cursor is in editor text; the default guard for editing commands.
- editorHasSelection
- Some text is selected. Pair with commands that act on a selection.
- textInputFocus / inputFocus
- Any text input has focus, including chat and search boxes. Use ! to keep editor keys out of inputs.
- terminalFocus
- The integrated terminal owns the keyboard.
- isInDiffEditor
- The active editor is a diff view, useful for review-time bindings.
- sideBarFocus / panelFocus
- The side bar or bottom panel has focus.
- inDebugMode
- A debug session is running.
- editorLangId
- Language of the active file, compared with == (e.g. 'markdown').
Inherited VS Code keys that behave identically in Cursor.
A binding that works in the editor but also fires inside the chat input (or vice versa) is almost always missing a focus guard. Scope editor commands with editorTextFocus, and keep global commands away from typing surfaces with !textInputFocus.
Guarding too tightly fails the other way, and it is probably the harder one to notice, because the binding does work, just not everywhere you expected. A key scoped to editorTextFocus goes quiet as soon as focus moves to the file tree or a chat box.
How do I find Cursor-specific context keys?
Cursor does not publish a list of its own context keys, so the honest method is to inspect them live in your build, which also future-proofs you against renames between releases. Two built-in developer tools do it:
- 1Run Developer: Inspect Context Keys from the command palette, then click any part of the UI (the chat pane, the editor, a diff). The developer console prints every context key and its current value for that spot. Cursor's AI-surface keys show up here alongside the VS Code ones.
- 2Run Developer: Toggle Keyboard Shortcuts Troubleshooting, then press the shortcut that is not behaving. The log shows each keystroke, every rule it matched and which binding won. That is the fastest way to find what is shadowing your key.
- 3In the Keyboard Shortcuts UI, search by the key you care about (e.g. type "cmd+k") to see every command competing for it and each one's when clause.
Of the two developer tools, the troubleshooting log is the one to open when a key does nothing at all, and the reason is in what it logs. A rule that never matched and a rule that matched and then lost the key feel identical from the keyboard. The log separates them. Read it before you edit the entry.
Cursor ships fast and internal command IDs and context keys can change between versions. The inspect and troubleshooting tools read your running build, so their answer is always current. Treat any hardcoded list of Cursor-internal keys (including from this page's sources) as a starting point to verify, not gospel.
Why did my Cmd+K chords stop working in Cursor?
In VS Code, ⌘CtrlK is the chord leader, the first key of two-step shortcuts like ⌘K ⌘S (open shortcuts) or ⌘K ⌘W (close all). Cursor reassigned ⌘K to inline edit in the editor and to the prompt bar in the terminal, so it moved the chord leader: ⌘R on Mac, CtrlM on Windows and Linux. A Cursor staff answer on the forum states it directly: "⌘CtrlK is used for the inline edits. We therefore changed the keychord leader key to be ⌘R on Mac and CtrlM on Windows and Linux."
- You knew it as (VS Code)
- ⌘K ⌘S
- In Cursor it is
- ⌘R ⌘S
- What it does
- Open Keyboard Shortcuts
- You knew it as (VS Code)
- ⌘K ⌘W
- In Cursor it is
- ⌘R ⌘W
- What it does
- Close all editors
- You knew it as (VS Code)
- ⌘K Z
- In Cursor it is
- ⌘R Z
- What it does
- Zen mode
- You knew it as (VS Code)
- ⌘K (alone)
- In Cursor it is
- ⌘K
- What it does
- Cursor inline edit (editor) / prompt bar (terminal)
| You knew it as (VS Code) | In Cursor it is | What it does |
|---|---|---|
| ⌘K ⌘S | ⌘R ⌘S | Open Keyboard Shortcuts |
| ⌘K ⌘W | ⌘R ⌘W | Close all editors |
| ⌘K Z | ⌘R Z | Zen mode |
| ⌘K (alone) | ⌘K | Cursor inline edit (editor) / prompt bar (terminal) |
Mac keys shown. The staff answer gives Ctrl+M as the Windows/Linux leader; Cursor's help page routes to the shortcuts screen with Ctrl+R then Ctrl+S, so try both on your build.
This is also why imported VS Code keybindings sometimes arrive broken: users on the Cursor forum found imported entries whose when fields read (arbitrary function), a placeholder left when a condition could not be carried across. Those bindings never fire. Delete the broken entries and rebind through Cursor's UI instead of pasting your old file wholesale.
The leader itself is configurable. In the Keyboard Shortcuts UI, search for the keychord leader and set it back to ⌘K. That means you then share the key with inline edit and should scope one of them with a when clause.
Whether to move the leader back depends on how much of your muscle memory sits on two-step chords, and there is a cost the swap does not advertise. The first row of that table is the one that bites. ⌘R ⌘S opens the Keyboard Shortcuts screen, so remapping the leader also moves the front door to the screen you go to when a binding misbehaves. The command palette still gets you there either way.
What are useful keybindings.json recipes for Cursor?
Three patterns cover nearly everything: add a binding with a guard, remove a default you keep hitting by accident, and resolve a conflict by narrowing scope. Removal uses the VS Code convention of prefixing the command with a minus sign.
{
"key": "ctrl+alt+/",
"command": "editor.action.commentLine",
"when": "editorTextFocus && editorLangId == 'typescript'"
}{
"key": "cmd+e",
"command": "-workbench.action.quickOpen"
}{
"key": "cmd+k",
"command": "workbench.action.terminal.clear",
"when": "terminalFocus"
}For Cursor's AI surfaces, get the real command ID first (right-click → Copy Command ID in the Keyboard Shortcuts UI, or the troubleshooting log), then apply the same three patterns. Defaults worth knowing before you remap: ⌘I / ⌘L toggle the side panel, ⌘E toggles the agent layout, ⌘. opens the mode menu, ⌘/ loops between models, and ⇧⌘S opens a side chat.
Frequently asked questions
Where is keybindings.json stored in Cursor?
Open it via the command palette: Preferences: Open Keyboard Shortcuts (JSON). Cursor uses the same per-user file mechanism as VS Code, in Cursor's own user-data directory. Always open it through the command so you edit the file your running build actually reads.
Why don't my VS Code keybindings work after importing into Cursor?
Two causes dominate. Cursor moved the chord leader off ⌘CtrlK (to ⌘R on Mac, CtrlM on Windows/Linux) because ⌘K drives inline edit, so all your two-step ⌘K chords changed. And some imported entries arrive with a broken when field reading '(arbitrary function)'. Those never fire and need to be deleted and rebound.
What is a when clause in a keybinding?
A boolean expression over live context keys (focus, selection, language, mode) that gates the binding. No when clause means the shortcut is global; with one, it only fires while the expression is true, for example editorTextFocus && !editorReadonly.
Why does my when clause fire somewhere I did not intend?
Usually precedence. || binds loosest, so editorTextFocus && editorLangId == 'typescript' || terminalFocus means (editor and TypeScript) or terminal, and the binding fires in the terminal as well. Where an expression needs that kind of reading, write two entries with the same key and command and one condition each.
How do I see which context keys are active in Cursor?
Run Developer: Inspect Context Keys from the command palette and click the UI region you care about, and every key and value prints to the developer console. For misbehaving shortcuts, Developer: Toggle Keyboard Shortcuts Troubleshooting logs each keypress and which binding won.
Can I rebind Cursor's AI shortcuts like inline edit and the agent panel?
Yes. Cursor's documentation states all keybindings, including Cursor-specific features, can be remapped in Keyboard Shortcuts settings. Use the UI's Copy Command ID to get the exact command name, then bind it in keybindings.json with a when guard if the key is shared.
Sources & last verified
- Cursor Docs - Keyboard Shortcuts
- VS Code Docs - Key Bindings
- VS Code Docs - When Clause Contexts
- Cursor Forum - Imported keybindings with '(arbitrary function)' when clauses
- Cursor Forum - How do I change the keyboard shortcuts Cursor uses?
Cursor ships frequently. Last updated July 28, 2026.