LingCode ships sensible default shortcuts, but if your muscle memory comes from Cursor, VS Code, JetBrains, or Vim, those defaults will fight you for weeks. Five minutes editing ~/.claude/keybindings.json saves years of friction.
Most editors hide keybindings behind a settings UI with a search box and a tiny "edit" button per row. That's fine for one rebind, painful for ten, and unportable when you move machines.
LingCode keeps keybindings in a plain JSON file at ~/.claude/keybindings.json. You can:
The format is small: an array of {keys, command} objects. That's it. Once you've seen one, you've seen them all.
In a terminal:
mkdir -p ~/.claude
touch ~/.claude/keybindings.json
open -e ~/.claude/keybindings.json
If the file is new and empty, paste this skeleton and save:
[
]
Empty array = "use all defaults, override nothing." Every entry you add either replaces a default or registers a new binding. LingCode hot-reloads the file on save β no restart.
Each binding is an object with two fields:
{
"keys": "cmd+k",
"command": "chat.focus"
}
keys β the keystroke. Modifiers are cmd, shift, alt (= Option), ctrl. Join with +. Key names are lowercase (k, enter, escape, tab, up, down, left, right, f1β¦f12).command β the action to fire. You can see the full list by asking LingCode in chat: "list all keybinding commands."That's the whole grammar. Examples for common rebinds:
[
{ "keys": "cmd+p", "command": "file.quickOpen" },
{ "keys": "cmd+shift+p", "command": "command.palette" },
{ "keys": "cmd+b", "command": "sidebar.toggle" },
{ "keys": "cmd+j", "command": "terminal.toggle" },
{ "keys": "cmd+enter", "command": "chat.submit" },
{ "keys": "cmd+l", "command": "chat.focus" }
]
The single most-asked rebind: how chat messages get sent. Default is Return sends, Shift+Return inserts newline. If you came from a multi-line-first editor, you might want the opposite β Return for newline, Cmd+Return to send:
[
{ "keys": "enter", "command": "chat.newline" },
{ "keys": "cmd+enter", "command": "chat.submit" }
]
Save the file, focus the chat input, and the binding is live. No need to restart LingCode.
A chord is two key combos in sequence: press the first, then the second within a short window. Useful when single-keystroke shortcuts are running out. Separate the two with a space:
[
{ "keys": "cmd+k cmd+s", "command": "settings.open" },
{ "keys": "cmd+k cmd+t", "command": "theme.pick" },
{ "keys": "cmd+k z", "command": "zenMode.toggle" },
{ "keys": "cmd+k cmd+r", "command": "keybindings.open" }
]
VS Code users will recognize the cmd+k prefix convention β it's there because there's literally nothing else mnemonic left after a decade of editor history.
You don't need to translate by hand. Ask LingCode:
I came from Cursor. Read ~/.claude/keybindings.json and add the
core Cursor shortcuts I'm probably missing β at minimum:
- cmd+k for the inline AI prompt
- cmd+l for chat focus
- cmd+i for inline suggestions
- cmd+. for quick fix
- cmd+; for the model picker
Don't remove any existing bindings. Show me the diff before
saving.
Same prompt works for "I came from VS Code," "I came from JetBrains," "I came from Vim." LingCode knows the standard sets and will append rather than overwrite β but only if you ask it to show the diff first, which catches accidental clobbers.
cmd+k for inline AI and LingCode's default cmd+k chord prefix conflicts, the last entry wins. Re-read the file after edits to confirm what's actually bound.
The file is plain JSON β drop it into your dotfiles repo:
cd ~/dotfiles
ln -s ~/.claude/keybindings.json claude-keybindings.json
git add claude-keybindings.json
git commit -m "Add LingCode keybindings"
On a new Mac, symlink it back the other way:
mkdir -p ~/.claude
ln -sf ~/dotfiles/claude-keybindings.json ~/.claude/keybindings.json
Your bindings travel with your shell, your editor configs, and your aliases. Treat them as one set.
Three likely causes, in order of frequency:
python3 -m json.tool ~/.claude/keybindings.json.cmd+space, cmd+tab) and global utilities (Raycast, Alfred, Rectangle) take precedence. Check System Settings β Keyboard β Keyboard Shortcuts.Don't suspect the rebinding itself until you've ruled out those three.
The whole workflow β locate, edit, rebind, chord, sync β is packaged as a skill. Drop it into your skills folder and ask LingCode for "rebind a shortcut" or "customize keybindings" to invoke it:
---
name: keybindings-help
description: Use when the user wants to customize keyboard shortcuts, rebind keys, add chord bindings, or modify ~/.claude/keybindings.json. Triggers: 'rebind ctrl+s', 'add a chord shortcut', 'change the submit key', 'customize keybindings', 'remap key', 'I'm used to Cursor / VS Code / Vim keys', 'keyboard shortcuts'. Actions: edit ~/.claude/keybindings.json, add {keys, command} entry, import Cursor/VS Code/Vim conventions, sync to dotfiles, debug malformed JSON / focus-context issues / OS-level shortcut grabs.
---
Customize LingCode's keyboard shortcuts by editing
~/.claude/keybindings.json directly.
Format: a JSON array of objects, each with two fields:
- keys: the keystroke. Modifiers cmd, shift, alt, ctrl joined with +.
Key names lowercase (k, enter, escape, tab, arrows, f1..f12).
Chords are two combos separated by a space ("cmd+k cmd+s").
- command: the action to fire. Run "list all keybinding commands" in
chat to discover them.
Workflow:
1. Create ~/.claude/keybindings.json if it doesn't exist; seed with
an empty array [].
2. Identify the user's source-editor convention (Cursor, VS Code,
JetBrains, Vim) so the proposed bindings match their muscle
memory.
3. Append entries β never silently replace existing ones unless
asked. Show a diff first.
4. Validate with `python3 -m json.tool` before declaring done.
5. The file hot-reloads on save β no restart needed.
If a binding doesn't fire, check: JSON validity, focus context (chat
input vs editor vs terminal), and OS/global app shortcuts (Raycast,
Alfred, System Settings β Keyboard Shortcuts) that may grab the key
first.
Save as ~/.lingcode/skills/keybindings-help/SKILL.md β see Install a skill for the exact location and how skills get discovered.