Claude Codeのキー操作は、~/.claude/keybindings.json で丸ごと差し替えられます。Ctrl+Sやショートカットが端末や手癖とぶつかるなら、上書きか無効化で解ける。設定ファイルの構造と、割り当てが効かない時の切り分けを公式仕様に沿って整理します。
keybindings.jsonの基本構造
カスタムキーバインドは Claude Code v2.1.18 で入った機能です。/keybindings を実行すると、~/.claude/keybindings.json が無ければ作られ、あれば開く。中身は bindings 配列を持つ1つのオブジェクト。
/keybindingsで開く
ファイルの最上位に置けるキーは $schema(エディタ補完用のURL)、$docs(ドキュメントURL)、本体の bindings。bindings の各ブロックが「どのcontextで、どのキーをどのactionに割り当てるか」を持ちます。
contextとactionの対応
キーはcontextごとに解釈が変わります。チャット入力欄は Chat、権限ダイアログは Confirmation、どこでも効くものは Global。actionは chat:submit や app:toggleTodos のように namespace:action 形式で書きます。contextは他にも Transcript(transcriptビューア)、DiffDialog(差分表示)、ModelPicker(モデル選択)など、画面の状態ごとに分かれている。同じ Escape でも Chat では入力キャンセル、Confirmation では拒否と、contextで別のactionにひも付きます。次は公式ドキュメント “Configuration file” に載る最小例です。
{
"$schema": "https://www.schemastore.org/claude-code-keybindings.json",
"bindings": [
{
"context": "Chat",
"bindings": {
"ctrl+e": "chat:externalEditor",
"ctrl+u": null
}
}
]
}
結果は保存した瞬間に反映されます。公式は “Changes to the keybindings file are automatically detected and applied without restarting Claude Code” と明記していて、再起動は不要。上の例は Ctrl+E を外部エディタ起動に割り当て、Ctrl+U の既定を無効化しています。
デフォルトを上書き・無効化する
既定のキーが自分の環境で邪魔になることがあります。Ctrl+S は chat:stash(入力中のプロンプト退避)に割り当て済み。ただ端末のフロー制御(XOFF)に吸われて画面が固まる環境では、別キーに逃がしたい。
既存のキーを別のactionへ
同じキーに別のactionを書けば上書きになります。fast modeのトグルは既定で Meta+O(macOSでOption+O)。Option修飾が押しにくいなら、Ctrl+F に寄せられます。
{
"bindings": [
{
"context": "Chat",
"bindings": {
"ctrl+f": "chat:fastMode"
}
}
]
}
これで Ctrl+F でfast modeをトグルできます。chat:fastMode は Chat のactionなので、contextも Chat で揃える。既定の Meta+O は残るため、両方から叩けます。
nullで無効化する
actionに null を指定すると、その既定キーを無効化できます。公式の “Unbind default shortcuts” セクションが挙げる書き方です。
{
"bindings": [
{
"context": "Chat",
"bindings": {
"ctrl+s": null
}
}
]
}
これで Ctrl+S は素通しになり、端末側のショートカットとして使えます。無効化はchordにも効く。
chord(2ストローク)を書く
VS Codeでおなじみの「Ctrl+Kを押してからCtrl+S」のような連続入力も書けます。記法はスペース区切り。
スペース区切りで連続キーを表す
{
"bindings": [
{
"context": "Chat",
"bindings": {
"ctrl+k ctrl+e": "chat:externalEditor"
}
}
]
}
ctrl+k ctrl+e は「Ctrl+Kを離してからCtrl+E」の意味。プレフィックスを押している間は、次のキー待ちに入ります。単独の ctrl+k に何も割り当てが無ければ、chordの起点としてだけ働く。
プレフィックスを1キーに戻す
プレフィックスの扱いには癖があります。Ctrl+X は既定で3つのchordのプレフィックスに予約済み。ctrl+x ctrl+k と ctrl+x ctrl+e が Chat、ctrl+x ctrl+b が Task。Ctrl+X を単独キーとして使うには、この3つを全部unbindする必要があります。
{
"bindings": [
{ "context": "Task", "bindings": { "ctrl+x ctrl+b": null } },
{
"context": "Chat",
"bindings": {
"ctrl+x ctrl+k": null,
"ctrl+x ctrl+e": null,
"ctrl+x": "chat:newline"
}
}
]
}
1つでも残すと、Ctrl+X を押した時点でchord待ちに入り、単独キーとしては発火しません。ctrl+x ctrl+b のchord自体は v2.1.169 以降で、tmuxのprefix衝突を避ける目的で足されたものです。
主要ショートカットの一覧
Chat と Global でよく触るactionと既定キーを並べます。どのactionをどのキーから動かすか、この表で確かめられます。
| action | 既定キー | 動作 |
|---|---|---|
chat:submit | Enter | メッセージ送信 |
chat:newline | Ctrl+J | 送信せず改行 |
chat:cycleMode | Shift+Tab | 権限モードの切替 |
chat:modelPicker | Meta+P | モデル選択を開く |
chat:fastMode | Meta+O | fast modeのトグル |
chat:thinkingToggle | Meta+T | 拡張思考のトグル |
app:toggleTodos | Ctrl+T | ToDoリスト表示 |
history:search | Ctrl+R | 履歴検索 |
修飾キーの読み替えも押さえておくと、表がそのまま使えます。Meta+ はmacOSでOption、それ以外でAltを指す。大文字1文字はShift付きと同じ意味で、K は shift+k と等価です。
割り当てが効かない時に見る所
書いたのに反応しない。原因は予約キー・端末の競合・検証エラーに大別できます。順に見ます。
予約キーは変更できない
いくつかのキーはハードコードで、上書きの対象外です。公式の “Reserved shortcuts” が挙げるのは Ctrl+C(中断)、Ctrl+D(終了)、Ctrl+M、Caps Lock。Ctrl+M が変えられないのは、端末上ではEnterと同じCR(復帰)を送るためです。ここにbindingを書いても黙って無視されます。
tmux / screenのプレフィックスと衝突する
端末multiplexerを噛ませていると、キーがそちらに吸われます。Ctrl+B はtmuxのprefixで、Claude Codeに届けるには2回押しが要る。Ctrl+A はGNU screenのprefix、Ctrl+Z はUNIXのプロセス停止(SIGTSTP)。この3つは割り当てても素直に効きません。task:background に ctrl+x ctrl+b のchordが用意されたのも、この Ctrl+B 衝突を避けるためでした。
もう1つ、macOSで cmd+ 系を書いても無反応なことがあります。cmdグループはKittyキーボードプロトコルやxtermの modifyOtherKeys に対応した端末でしか検出されない。多くの端末はSuperを送らないので、どこでも効かせたいなら ctrl か meta を使います。私は最初 cmd+enter を送信に割り当てて全く効かず、端末のプロトコル対応を疑うまで15分かかりました。
–debugで検証warningを読む
Claude Codeは読み込み時にkeybindingsを検証し、問題を警告として出します。検証されるのは次の項目。
- JSONのパースエラーや構造の不正
- 存在しないcontext名
- 予約キーとの衝突
- multiplexerとの衝突
- 同一context内の重複binding
警告はdebug logに書かれます。claude --debug で起動すると、次のように内訳が読めます(表記は環境で多少変わります)。
$ claude --debug
[keybindings] duplicate binding "ctrl+e" in context "Chat"
[keybindings] unknown context "Chatt" (ignored)
"Chatt" のようなタイプミスは、context名ごと無視されるだけでエラーになりません。効かない時は、この警告を先に見れば原因のあたりがつきます。
Vimモードとの関係
Vimモードを /config のEditor modeで有効にしていても、keybindingsとは独立して動きます。公式の “Vim mode interaction” いわく、Vimモードは入力レベル(カーソル移動・モード遷移)、keybindingsはコンポーネントレベル(送信・ToDo表示)を担当。NORMALモードへ戻すEscは chat:cancel を発火させません。
jj でEscのような、INSERTモードの2キー変換だけはkeybindingsの管轄外です。こちらは vimInsertModeRemaps 設定で書く。Vimモード側の詳しい設定はClaude Code Vimモードの使い方にまとめています。
まとめ
keybindings.jsonは設定ファイル1枚で、端末や手癖に合わせてキーを組み替える仕組みです。押さえどころを並べます。
/keybindingsで~/.claude/keybindings.jsonを開き、bindings配列にcontextごとのキー割り当てを書く(v2.1.18以降)- 既存キーは同じキーへの再割り当てで上書き、
nullで無効化。保存すると再起動なしで反映 - chordはスペース区切り。プレフィックスを単独キーに戻すには、それを共有するchordを全部unbindする
Ctrl+C/Ctrl+D/Ctrl+M/ Caps Lockは予約キーで変更不可- 効かない時は予約キー・tmux/screen競合・cmdグループ未対応を疑い、
claude --debugで検証warningを読む
FAQ
設定をデフォルトに戻すには?
該当するbindingブロックを消せば、そのキーは既定に戻ります。全部戻すなら ~/.claude/keybindings.json ごと削除。次回の読み込みで既定のキーマップが適用されます。
変更したのに反映されないときは?
保存直後に自動で読み直されるので、待っても変わらないならファイル側の問題です。claude --debug でパースエラー・context名の誤り・予約キー衝突の警告を確認してください。

