跳转至

Claude Code 自定义快捷键

目的:让 Shift + Enter 在 Windows Terminal 里真正发送出去,实现换行不发送。 最后更新:2026-10-06


一句话总结

Claude Code 内部已经支持 Shift + Enter 换行(chat:newline),但绝大多数终端默认不会把 Shift + Enter 作为独立按键序列发给程序,终端只会告诉程序"这是 Enter"。所以要让 Shift + Enter 生效,必须在终端这一层手动把一段转义序列注入给 Claude Code。

问题不在 Claude Code,在 Windows Terminal。


为什么需要这一步

层次 默认行为 问题
Claude Code shift+enter → chat:newline(换行) ✅ 支持
终端 只上报"Enter 被按下"(\r) ❌ 丢掉 shift 信息
结果 Shift + Enter 触发的还是发送消息 换行失败

Windows Terminal 的键盘增强协议(Kitty keyboard protocol)里,Shift + Enter 对应的 CSI 序列是:

ESC [ 13 ; 2 u

即 JSON 中的 "\u001b[13;2u"。让终端把这个序列发给 Claude Code,问题就解决了。


方案一:改 Windows Terminal(推荐)

打开 settings.json

不要用 VS Code 的 Preferences: Open Default Settings (JSON),那条命令打开的是只读的默认配置。要改的是用户实际配置。

打开设置面板(Ctrl + ,)→ 左下角点「打开 JSON 文件」按钮,即可跳到真实文件。

文件路径分两种安装方式:

安装方式 路径
Microsoft Store / 预装(打包版) %LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json
独立安装版 / 预览版 %LOCALAPPDATA%\Microsoft\Windows Terminal\settings.json

打开后建议「用 VS Code 打开」,方便格式化、查错。

修改原则

用「插入」,不要全选替换。 这个文件里还有主题、配色、profiles 等等全部配置,覆盖掉等于全部归零。

第一步:加 Action(动作)

找到 "actions" 字段(通常是一个 [] 中括号)。如果整个文件都没有这个字段,可以在顶层 {} 里加上 "actions": []。

在 "actions": [ 里面插入:

1
2
3
4
5
6
7
{
  "command": {
    "action": "sendInput",
    "input": "\u001b[13;2u"
  },
  "id": "User.sendInput.shiftEnter"
}

第二步:加 Keybinding(键绑定)

找到 "keybindings" 字段(同样通常是 [])。在 "keybindings": [ 里面插入:

1
2
3
4
{
  "id": "User.sendInput.shiftEnter",
  "keys": "shift+enter"
}

两段的 id 必须完全一致——keybindings 靠 id 找到 actions 里对应的动作,对不上就等于没配。

⚠️ JSON 格式注意

Windows Terminal 的 settings.json 通常长这样:

{
  "$help": "https://aka.ms/terminal-documentation",
  "actions": [
    // 把第一段粘贴到这里,注意前后要有逗号
  ],
  "keybindings": [
    // 把第二段粘贴到这里,注意前后要有逗号
  ],
  "profiles": {
    // ...
  }
}

千万不要漏逗号。

  • 如果 actions / keybindings 里已经有其他项,每个 {} 之间用英文逗号 , 隔开
  • 如果是空数组,直接放进去,不用加逗号
  • input 的值必须写成 "\u001b[13;2u" 这种转义写法,不要真的打出 ESC 控制字符——JSON 里放裸 ESC 会导致整个文件解析失败,Terminal 会静默回退到默认配置

验证

改完保存,Terminal 会自动热重载(不用重启)。回到 Claude Code 里按 Shift + Enter,出现新行而不发送,即成功。

如果没生效,打开 PowerShell 执行:

# 确认 JSON 没写坏(能输出内容就说明解析通过)
Get-Content "$env:LOCALAPPDATA\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json" | ConvertFrom-Json | Select-Object -ExpandProperty keybindings

解析报错 = JSON 语法有问题(多半是逗号)。


方案二:改 Claude Code 的 keybindings.json

什么是 keybindings.json

Claude Code 支持自定义快捷键。配置文件位于:

~/.claude/keybindings.json

在 Claude Code 里运行 /keybindings 可以直接创建或打开它。

文件格式

{
  "$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"
      }
    }
  ]
}

顶层必须是 "bindings" 数组,里面每项按 context(生效场景)分组,一个 context 只需要写你真正要改的键。

常用场景 context

context 生效时机
Global 任何时候,无视焦点
Chat 输入框聚焦时
Confirmation 权限确认弹窗
Transcript 查看历史对话时
Scroll 可滚动区域聚焦(全屏布局)

键位写法

类别 写法
修饰键 ctrl alt shift meta(alt 与 meta 在终端里等价,用 meta 代表 Win/Cmd)
特殊键 escape enter tab space backspace delete up down left right
组合 + 连接,如 ctrl+shift+p、alt+enter
和弦 空格分隔,如 ctrl+x ctrl+s(两键间隔 1 秒内)

常用动作

动作 默认键 context
chat:newline ctrl+j Chat
chat:submit enter Chat
chat:clearInput ctrl+l Chat
chat:externalEditor ctrl+x ctrl+e Chat
chat:cycleMode shift+tab Chat
app:toggleTodos ctrl+t Global
app:toggleTranscript ctrl+o Global
history:search ctrl+r Global

完整列表见 官方 keybindings 文档。

解绑默认键

值设为 null 即解除绑定:

1
2
3
4
5
6
{
  "context": "Chat",
  "bindings": {
    "ctrl+s": null
  }
}

改键 vs 加键

用户绑定是追加在默认绑定之后的。想换掉某个默认键,必须两个一起写:旧键设 null,新键写目标动作。

1
2
3
4
5
6
7
{
  "context": "Chat",
  "bindings": {
    "ctrl+g": null,
    "ctrl+e": "chat:externalEditor"
  }
}

只写 ctrl+e 的话,ctrl+g 依然能用——两个都会触发。

关于 Shift + Enter

本机 ~/.claude/keybindings.json 的 Chat context 里已经有:

"shift+enter": "chat:newline"

也就是说 Claude Code 侧不用改,缺的只是终端侧那层注入(方案一)。方案一做完后该绑定才会真正收到按键。

常见报错

报错 原因 修复
keybindings.json must have a "bindings" array 少了外层包装 包成 { "bindings": [...] }
"bindings" must be an array bindings 不是数组 改成 [{ context, bindings }]
Unknown context "X" context 名拼错 用官方表里的原名,Chat 首字母大写
Duplicate key "X" in Y bindings 同一 context 里键重复 删掉重复项
Invalid action for "X" 动作值不是字符串 动作要是 "app:help" 这类字符串,或 null

错误(error)会让绑定完全不生效,警告(warning)一般还能用。

不可改的键

键 原因
ctrl+c 中断/退出,硬编码
ctrl+d 退出,硬编码
ctrl+m 在终端里等同于 Enter(都是 CR)
ctrl+i 在终端里等同于 Tab
ctrl+[ 在终端里等同于 Escape
ctrl+h 在终端里等同于 Backspace
capslock Caps Lock 不会传给终端程序

两套系统的分工

想改的东西 改哪里
让 Shift + Enter 换行 Windows Terminal settings.json(方案一)
换 Ctrl + L、Ctrl + R 之类 ~/.claude/keybindings.json(方案二)
终端的复制粘贴、分屏 Windows Terminal keybindings(ctrl+c 复制等)

一句话:终端负责"把什么送进来",Claude Code 负责"收到之后干什么"。


本机当前状态(已验证)

%LOCALAPPDATA%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json 中实际内容:

1
2
3
"actions": [
  { "command": { "action": "sendInput", "input": "\u001b[13;2u" }, "id": "User.sendInput.shiftEnter" }
]
1
2
3
4
5
6
"keybindings": [
  { "id": "Terminal.CopyToClipboard", "keys": "ctrl+c" },
  { "id": "User.sendInput.shiftEnter", "keys": "shift+enter" },
  { "id": "Terminal.PasteFromClipboard", "keys": "ctrl+v" },
  { "id": "Terminal.DuplicatePaneAuto", "keys": "alt+shift+d" }
]

本机装的是 Store/打包版(只有 _8wekyb3d8bbwe 一个包目录,没有 Preview 版),所以配置在 LocalState 下。


参考资料