Claude Code keybindings 完整教學 — 你綁的那個鍵,可能連終端機都沒放它出來
你在 Claude Code 裡按下 Ctrl+Shift+R,它到底收到了什麼?
這個問題不是修辭。答案可能是「一個明確的 Ctrl+Shift+R 事件」,也可能是「什麼都沒收到」,還可能是「收到了但被別的東西先吃掉了」。而這三種結果決定了你寫在 ~/.claude/keybindings.json 裡的那行設定會不會生效。
所以先別急著決定要綁什麼。把一次按鍵從你的手指走到「Claude Code 執行某個動作」的路徑拆開,中間有四道關卡,每一道都會攔掉一部分組合。搞懂路徑之後,該綁什麼幾乎是自動浮現的。
(本文的機制與表格出自 Claude Code 官方 keybindings 文件,我本機跑的是 2.1.220。文中我沒實測的部分會明講。)
第一關:終端機願不願意載這個組合
鍵盤不是直接跟 Claude Code 講話的。你按下的組合會先被終端機轉成一串位元組,Claude Code 讀到的只是那串位元組。這個中間人有它自己的規矩,而規矩比大多數人想的嚴格。
最好懂的例子是 Ctrl+M。在終端機的世界裡,Ctrl+M 送出的位元組跟 Enter 一模一樣(都是 CR)。所以官方文件直接把它列進不能重綁的清單,不是因為 Claude Code 佔用了它,而是因為沒有任何程式能分辨這兩者。同一份清單裡還有 Caps Lock,理由更乾脆:它根本不會被送到終端機應用程式。
Ctrl+C 和 Ctrl+D 也在清單上,但原因不同,它們是被硬編碼成中斷和離開,不開放重綁。
再來是 cmd 這一組修飾鍵(cmd、command、super、win)。文件寫得很清楚:只有支援 Kitty 鍵盤協定或 xterm 的 modifyOtherKeys 模式的終端機才會回報 Super 修飾鍵,多數終端機不送。所以你在 macOS 上綁 cmd+k,在自己的終端機可能好用,換一台就靜靜失效。想要到處都能用,就用 ctrl 或 meta。
這關可以想成寄信。你寫的地址再正確,如果郵局不收這種尺寸的信封,收件人永遠不會知道你寄過。
第二關:同一個鍵,在不同房間是不同的意思
過了終端機,Claude Code 拿到按鍵之後不會直接查一張全域表格。它先問:現在前景是哪個元件?
官方定義了 19 個 context:Global、Chat、Autocomplete、Settings、Confirmation、Tabs、Help、Transcript、HistorySearch、Task、ThemePicker、Attachments、Footer、MessageSelector、DiffDialog、ModelPicker、Select、Plugin、Scroll。每個 context 有自己的一組動作。
Ctrl+E 是最好的示範。它在三個地方是三件不同的事:權限對話框裡是 confirm:toggleExplanation(叫模型解釋這個指令要幹嘛),逐字稿檢視裡是 transcript:toggleShowAll,而在 Chat 裡它預設根本沒綁 Ctrl+E,開外部編輯器的 chat:externalEditor 預設是 Ctrl+G 和 Ctrl+X Ctrl+E 這個 chord。
所以設定檔的結構長成這樣,context 是必要的:
1 | { |
動作名稱一律是 namespace:action 格式。app: 開頭的那組住在 Global,所以像 app:toggleTodos(Ctrl+T,開關 Claude 的待辦清單)不管你在哪都有效;chat: 開頭的只在輸入框那層有效。
這裡有個實務上的分水嶺:如果你的目標是「不管在什麼畫面都要能按」,就綁 Global;如果只是打字時要用,綁 Chat 才不會在對話框裡誤觸。
第三關:chord 會佔住整個前綴
Claude Code 支援 chord,也就是 VS Code 那種「先按 Ctrl+K,放掉,再按 Ctrl+S」的兩段式按法,寫法是中間空一格:ctrl+k ctrl+s。
機制本身很單純:按下前綴之後,它進入等待模式,等你按第二個鍵。但這個等待模式帶來一個非常容易踩的後果——只要還有任何一條 chord 用這個前綴,前綴本身就不能當單鍵綁定用。
官方文件把這個坑寫得很細。預設的 Ctrl+X 家族跨了兩個 context:Chat 裡有 ctrl+x ctrl+k(停掉所有背景 subagent)和 ctrl+x ctrl+e(開外部編輯器),Task 裡有 ctrl+x ctrl+b(把當前任務丟到背景)。你想把 Ctrl+X 自己拿來當單鍵,得把這三條全部解掉:
1 | { |
只解掉其中兩條,按下 Ctrl+X 仍然會進入等待模式,等那條沒解掉的。這時候的症狀是「我明明綁了,按了卻沒反應」,而你去看設定檔會覺得自己寫得完全正確。
想像電話總機:按 0 之後要等你撥分機,所以 0 本身沒辦法直接當一個功能鍵。要讓 0 變成功能鍵,得先確認沒有任何分機是 0 開頭。
第四關:大寫字母的兩種意思
最後一道是最不起眼、但最容易讓人以為文件寫錯的規則。
單獨的大寫字母隱含 Shift,K 等於 shift+k。這是為了 vim 風格的綁定,因為在那個世界裡 j 和 J 本來就是兩個不同指令。
但大寫字母帶了修飾鍵之後就不隱含 Shift:ctrl+K 跟 ctrl+k 是同一個東西,那個大寫只是你打字的風格。想要 Ctrl+Shift+K,就得老實寫 ctrl+shift+k。
特殊鍵一律小寫單字:escape/esc、enter/return、tab、space、up/down/left/right、backspace、delete。
拆完之後,該綁什麼變得很明顯
四道關卡走完,回頭看「該綁什麼」,會發現值得改的多半不是「我想要更快」,而是「這個預設在我的環境裡撞到了別的東西」。
撞得最兇的是終端機多工器。tmux 的前綴是 Ctrl+B,而 Claude Code 的 task:background 預設就是 Ctrl+B,所以在 tmux 裡你得按兩次才送得進去。官方後來補了 ctrl+x ctrl+b 這個 chord 當替代(需要 v2.1.169 以上)。GNU screen 用 Ctrl+A,Unix 的 Ctrl+Z 是把行程丟到背景(SIGTSTP),這三個都在文件的衝突清單裡。
第二種是肌肉記憶。chat:stash(暫存目前的 prompt)預設綁 Ctrl+S,而 Ctrl+S 在多數人手指裡就是「存檔」。如果你每天下意識按它十次,把它解掉或搬走比訓練手指便宜。
第三種是那些預設根本沒綁的動作。app:redraw(強制重畫終端機)預設是空的,畫面被別的程式輸出弄花的時候很有用。fullscreen 模式下的 scroll:halfPageUp/scroll:halfPageDown 也預設沒綁,文件明說它們存在的理由就是給 vi 風格的人重綁用(行為跟 scroll:pageUp/pageDown 相同)。
第四種是 model picker 裡的 effort 調整:modelPicker:decreaseEffort/increaseEffort 預設是左右鍵,modelPicker:thisSessionOnly 是 s。知道有這幾個動作,比記得要按哪裡有用。
動手:三步
跑 /keybindings,它會建立或打開 ~/.claude/keybindings.json。改完存檔就生效,不用重開 Claude Code,它會自己偵測檔案變動。
要解掉某個預設,把值寫成 null:
1 | { |
寫錯的話它會警告你。載入時會檢查 JSON 解析錯誤、無效的 context 名稱、撞到保留鍵、撞到多工器前綴、以及同一個 context 裡的重複綁定。警告會寫進 debug log,用 claude --debug 啟動才看得到細節。這部分我沒有實際觸發過(我的檔案太乾淨),所以警告訊息長什麼樣我沒看過。
vim mode 是另一層,不要在這裡找它
如果你開了 vim 模式(/config → Editor mode),要記得它跟 keybindings 是兩層獨立的系統。
vim 管的是文字輸入層:游標移動、模式切換、motion。keybindings 管的是元件層:開關待辦清單、送出訊息、切模型。所以在 vim NORMAL 模式下按 Escape 只是從 INSERT 切回 NORMAL,不會觸發 chat:cancel。大部分 Ctrl+ 組合會穿過 vim 那層,交給 keybindings 處理。
但 vim 自己的鍵不能用這個檔案重綁。想把 INSERT 模式的 jj 映射成 Escape,要用 vimInsertModeRemaps 設定,不是 keybindings.json。這條規則我覺得是整份文件裡最值得先知道的一句,因為找錯地方會浪費很多時間。
我自己的檔案,是個反面教材
老實說,我打開自己的 ~/.claude/keybindings.json 之後有點尷尬。裡面只有一條:
1 | { "context": "Chat", "bindings": { "ctrl+j": "chat:newline" } } |
而 chat:newline 的預設就是 Ctrl+J。也就是說我當初綁的東西跟原廠設定一模一樣,等於什麼都沒做,還多維護一個檔案。
這件事的教訓比它看起來大:動手綁之前先查預設表。文件裡那幾張表已經列了每個動作現在綁在哪,很多人以為要自己綁的功能,其實原廠就給了鍵,只是沒人翻過那張表。
帶走的模型
一個按鍵能不能生效,取決於三個獨立的問題:終端機肯不肯送、當下的 context 有沒有接、以及這個鍵有沒有被某條 chord 的前綴佔住。
這三層不只解釋 Claude Code。你的 tmux 前綴吃掉 vim 的快捷鍵、IDE 的組合鍵在遠端 SSH 裡失效、某個組合在 iTerm 好用換 Terminal.app 就死掉,全部都是這三層裡的某一層在作用。下次遇到「快捷鍵沒反應」,照這個順序問一遍,通常第二個問題就找到答案了。
要自己確認的話有個省事的做法:先只綁一條你確定終端機送得出來的組合(例如 ctrl+g),確認生效之後再往上加,一次加一條。比一口氣貼二十行進去然後猜哪行壞掉快得多。
參考來源
- Customize keyboard shortcuts — Claude Code Docs(context 清單、動作表、chord 與保留鍵規則皆出自此)
- 本機環境:Claude Code 2.1.220,macOS































































































































































