QR Send

スマホとPCのChrome間で、URLやテキストをQRコード1回のペアリングで送り合える自作Chrome拡張。アカウント不要・無料。

使ってみる →

Claude Codeのキーバインドをkeybindings.jsonで自分好みに変える:chordバインドで既存の割り当てと衝突せずに増やせる話

Selenium・自動化

Claude Codeを使っていて、割り当てたいショートカットがあるのに、もう良さそうなキーの組み合わせが埋まっている、ということはないでしょうか。私はあります。Ctrl+何かに好きな操作を割り当てようとすると、大抵は既に別の役割が入っています。単キーの組み合わせは有限なので、使っているうちに枯渇していくのは当然といえば当然です。

実はClaude Codeにはkeybindings.jsonというキーバインドのカスタマイズ機能があり、しかも「1回のキー入力」だけでなく「複数キーを連続で押す」chord(コード)バインドが公式にサポートされています。今回はこの仕組みを、公式ドキュメントを読み込んで裏取りしながら紹介します。

まずは/keybindingsで開いてみる

設定ファイルの実体は~/.claude/keybindings.jsonです。手で作る必要はなく、Claude Code上で/keybindingsと打つと、ファイルが無ければ作成、あれば既存の内容を開いてくれます。

中身はbindingsという配列を持つオブジェクトです。配列の各要素が「どのcontext(画面・場面)で」「どのキーに」「どのactionを」割り当てるかのブロックになっています。公式docsに載っている例はこうです。

{
  "$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+u": null
      }
    }
  ]
}

Chatコンテキスト(メインの入力欄)で、Ctrl+Eに外部エディタを開くactionを割り当て、逆にCtrl+Uはnullを指定して割り当てを外しています。書き換えたら保存するだけで、Claude Codeを再起動しなくても即座に反映されます。地味にありがたいポイントです。

namespace:action形式で「何を割り当てているか」がわかる

actionの値はchat:submit(メッセージ送信)やapp:toggleTodos(タスクリストの表示切り替え)のように、namespace:actionという形式になっています。chatapphistoryautocompleteconfirmtranscriptなど、contextごとに使えるnamespaceが決まっていて、公式docsには対応表が細かく載っています。

例えばChatコンテキストのデフォルト割り当てだけでもこれだけあります。

  • chat:submit: Enter(メッセージ送信)
  • chat:newline: Ctrl+J(改行のみ、送信しない)
  • chat:stash: Ctrl+S(入力中のプロンプトを一時退避)
  • chat:externalEditor: Ctrl+G、Ctrl+X Ctrl+E(外部エディタを開く)
  • chat:killAgents: Ctrl+X Ctrl+K(実行中のバックグラウンドsubagentを全部止める)

ここで気付くのが、chat:externalEditorchat:killAgentsはどちらも単キーではなく「Ctrl+Xの後に別のキー」という形になっている点です。これがchordバインドです。

本題: chordバインドでキーを使い切っても増やせる

chordは、スペース区切りで複数のキーストロークを並べたものです。書き方はこうなります。

ctrl+k ctrl+s

これは「Ctrl+Kを押して離し、そのあとCtrl+Sを押す」という意味です。1つの単キーに対して1つのactionしか割り当てられませんが、chordなら「あるキーを押した後、次に何を押すか」で分岐できるので、実質的に使えるキーの組み合わせが大きく増えます。単キーのCtrl+何かを使い切っていても、Ctrl+X直後の2打目としてならまだ空きがある、というわけです。

実際、Claude Code自身もこの手を使っています。Ctrl+Xを起点に、Chatコンテキストでctrl+x ctrl+k(subagent停止)、ctrl+x ctrl+e(外部エディタ)、ctrl+x enter(順番待ちで送信するqueueSubmit)の3つを割り当て、Taskコンテキストではctrl+x ctrl+b(タスクをバックグラウンドへ)まで割り当てています。1つのプレフィックスキーから4方向に枝分かれさせている計算です。

自分で増やす場合も同じ発想が使えます。例えば、まだ空いているプレフィックスを選んで、そこに複数の操作をぶら下げていく形です。

{
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "ctrl+k ctrl+t": "app:toggleTodos",
        "ctrl+k ctrl+o": "app:toggleTranscript"
      }
    }
  ]
}

本当に「既存の割り当てと衝突しない」のか

ここが今回一番確かめたかったところです。公式docsの「Validation」の節に、Claude Codeがkeybindings.jsonを読み込む際にチェックする項目が書かれています。パースエラー、無効なcontext名、無効なaction値に加えて、「同じcontext内での重複バインド」もちゃんと警告対象になっています。つまり、うっかり同じキー(同じchordの組み合わせも含む)に2つのactionを割り当てても、黙って片方が消えるのではなく警告が出る設計です。

ただし、この警告は画面に出るわけではなく、デバッグログに書き込まれる仕組みでした。確認するには--debugフラグを付けて起動する必要があります。ここは知らないと気付きにくいところなので、キーバインドをいじった後は一度--debugで立ち上げて警告が出ていないか見ておくと安心です。

もう一つ、chordのプレフィックスに関する仕様も注意が必要でした。あるcontextでctrl+x ctrl+kのようなchordを1つでも定義すると、そのcontextではctrl+xというプレフィックス自体が「chord待ち」として予約されます。もしctrl+xを単キーのactionとして使いたい場合は、そのプレフィックスに紐づくchordを全部nullで解除しないといけません。公式docsのサンプルはこうなっています。

{
  "bindings": [
    {
      "context": "Task",
      "bindings": {
        "ctrl+x ctrl+b": null
      }
    },
    {
      "context": "Chat",
      "bindings": {
        "ctrl+x ctrl+k": null,
        "ctrl+x ctrl+e": null,
        "ctrl+x enter": null,
        "ctrl+x": "chat:newline"
      }
    }
  ]
}

Taskコンテキストのctrl+x ctrl+bも含めて全部解除しないと、Chat側でctrl+x単体に割り当てても「まだ他のchordが残っている」という扱いになり、プレフィックスとしての予約が外れません。ここは私も最初、Chat側だけ直せば済むと思っていたのですが、公式docsを読み直して「contextをまたいだ全chordの解除が要る」ことに気付きました(わかっていないと地味にハマるところだと思います)。

そもそも変更できないキーもある

chordで自由自在に増やせるとはいえ、Ctrl+C(強制中断)やCtrl+D(終了)のようにハードコードされていて再割り当てできないキーもいくつかあります。公式docsの「Reserved shortcuts」に一覧があり、Ctrl+M(Enter扱い)やCtrl+I(Tab扱い)、Ctrl+H(バックスペース)なども、ターミナル側の都合でこの動作になっているとのことでした。これらをbindings側でどう書いても上書きはされません。

あと、tmuxのプレフィックス(Ctrl+B)やGNU screenのプレフィックス(Ctrl+A)は、Claude Code側の話ではなくターミナルマルチプレクサ側の予約なので、multiplexerを使っている場合はそちらとの衝突にも気を配る必要があります。

まずどう使うのが現実的か

自分でしばらく仕様を追ってみた感触としては、いきなり大量にカスタムするより、まず/keybindingsで空のファイルを開き、よく使うのに単キーが埋まっている操作を1つか2つ、空いてそうなプレフィックスの下にchordで足していくのが現実的だと思います。--debug起動での警告確認も忘れずに一度やっておくと、意図せず二重定義していないか安心できます。

正直、私自身はまだ日常的にガリガリカスタマイズしているわけではなく、今回は仕様を裏取りしながら試した段階です(実際にどのchordが手に馴染むかは、しばらく使ってみないとわからない部分だと思っています)。ただ、単キーが枯渇しても詰まないという設計は、地味だけど息の長い改善だと感じました。

Claude Codeの「地味だけど効く」設定は他にも紹介してきました。ツール実行のログをたたんで要点だけ見るFocus viewや、プロンプトのタイプミスに下線を引いてくれるスペルチェックもこの系譜です。承認を毎回求めなくなったオートモードのデフォルト化とあわせて、自分の運用に合いそうなものから試してみてください。

実際に自分のkeybindings.jsonをこう組んだ、という事例があれば、コメントで教えてもらえるとうれしいです。

コメント

タイトルとURLをコピーしました