Claude Codeのキーバインド変更—keybindings.jsonと競合対処

Claude Codeのキーバインド変更—keybindings.jsonと競合対処 | mohablog

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)、本体の bindingsbindings の各ブロックが「どのcontextで、どのキーをどのactionに割り当てるか」を持ちます。

contextとactionの対応

キーはcontextごとに解釈が変わります。チャット入力欄は Chat、権限ダイアログは Confirmation、どこでも効くものは Global。actionは chat:submitapp: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+Schat: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:fastModeChat の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+kctrl+x ctrl+eChatctrl+x ctrl+bTaskCtrl+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衝突を避ける目的で足されたものです。

主要ショートカットの一覧

ChatGlobal でよく触るactionと既定キーを並べます。どのactionをどのキーから動かすか、この表で確かめられます。

action既定キー動作
chat:submitEnterメッセージ送信
chat:newlineCtrl+J送信せず改行
chat:cycleModeShift+Tab権限モードの切替
chat:modelPickerMeta+Pモデル選択を開く
chat:fastModeMeta+Ofast modeのトグル
chat:thinkingToggleMeta+T拡張思考のトグル
app:toggleTodosCtrl+TToDoリスト表示
history:searchCtrl+R履歴検索

修飾キーの読み替えも押さえておくと、表がそのまま使えます。Meta+ はmacOSでOption、それ以外でAltを指す。大文字1文字はShift付きと同じ意味で、Kshift+k と等価です。

割り当てが効かない時に見る所

書いたのに反応しない。原因は予約キー・端末の競合・検証エラーに大別できます。順に見ます。

予約キーは変更できない

いくつかのキーはハードコードで、上書きの対象外です。公式の “Reserved shortcuts” が挙げるのは Ctrl+C(中断)、Ctrl+D(終了)、Ctrl+MCaps LockCtrl+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:backgroundctrl+x ctrl+b のchordが用意されたのも、この Ctrl+B 衝突を避けるためでした。

もう1つ、macOSで cmd+ 系を書いても無反応なことがあります。cmdグループはKittyキーボードプロトコルやxtermの modifyOtherKeys に対応した端末でしか検出されない。多くの端末はSuperを送らないので、どこでも効かせたいなら ctrlmeta を使います。私は最初 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名の誤り・予約キー衝突の警告を確認してください。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次