keybindings: ctrl+enter / shift+enter never reach the keybinding matcher on Windows Terminal; ctrl+j rebind ignored

Status Open
Reported on v2.1.235
Maintainer reply None cached
Activity 0 comments · opened Aug 19, 2026

Follow-up to #2054, which was closed as completed.

Environment

  • Claude Code 2.1.235 (native install)
  • Windows 11 Pro 26200, Windows Terminal, PowerShell 7.6.4

Expected

Per #2054 and the 2.1.141 changelog entry — "Fixed alternative chat:submit keybindings (e.g. meta+enter, ctrl+enter) not working when enter is rebound to chat:newline" — this should make Enter insert a newline and Ctrl+Enter submit:

{
  "bindings": [
    {
      "context": "Chat",
      "bindings": {
        "enter": "chat:newline",
        "ctrl+enter": "chat:submit"
      }
    }
  ]
}

Actual

Enter inserts a newline (that part works). Ctrl+Enter inserts a newline. Shift+Enter inserts a newline. There is no way to submit at all.

Bindings tried in the same file, one at a time:

| binding | result |
| --- | --- |
| "ctrl+enter": "chat:submit" | ignored — inserts newline |
| "shift+enter": "chat:submit" | ignored — inserts newline |
| "cmd+enter": "chat:submit" | ignored — inserts newline |
| "ctrl+j": "chat:submit" | ignored — inserts newline |
| "ctrl+s": "chat:submit" | works |

The file loads cleanly, no validation warnings (claude --debug):

[keybindings] Loaded 2 user bindings from C:\Users\carlo\.claude\keybindings.json
[keybindings] KeybindingSetup initialized with 182 bindings, 0 warnings
[keybindings] Watching for changes to C:\Users\carlo\.claude\keybindings.json

The terminal does report the modifiers

Windows Terminal reports modifiers through win32-input-mode (enabled with ESC [ ? 9001 h). The format is ESC [ Vk ; Sc ; Uc ; Kd ; Cs ; Rc _ — virtual key, scan code, unicode char, key-down, control key state, repeat count.

Captured with a small raw-input probe (console in ENABLE_VIRTUAL_TERMINAL_INPUT, win32-input-mode requested, bytes dumped verbatim):

| key pressed | sequence | Vk | Uc | Cs |
| --- | --- | --- | --- | --- |
| enter | ESC[13;28;13;1;0;1_ | 13 VK_RETURN | 13 | 0 |
| shift+enter | ESC[13;28;13;1;16;1_ | 13 VK_RETURN | 13 | 16 SHIFT_PRESSED |
| ctrl+enter | ESC[13;28;10;1;8;1_ | 13 VK_RETURN | 10 | 8 LEFT_CTRL_PRESSED |
| ctrl+j | ESC[74;36;10;1;8;1_ | 74 'J' | 10 | 8 |
| ctrl+s | ESC[83;31;19;1;8;1_ | 83 'S' | 19 | 8 |

So shift+enter and ctrl+enter are fully distinguishable from enter: the control key state is right there in the sequence. Note that ctrl+enter carries Uc=10, the same character ctrl+j produces.

For comparison, without win32-input-mode Windows Terminal collapses them — enter and shift+enter both send 0D, ctrl+enter sends 0A. The kitty keyboard protocol (ESC[>1u) and xterm modifyOtherKeys (ESC[>4;2m) change nothing here: Windows Terminal does not implement them. win32-input-mode is the channel that carries the modifiers on Windows.

Diagnosis (best guess)

The keystroke handed to the keybinding matcher looks like it is derived from Uc alone, with Cs discarded:

  • ctrl+enter (Uc=10) is flattened onto ctrl+j, so the ctrl+enter keystroke never exists and the binding can never match.
  • shift+enter is recognised somewhere — it has always inserted a newline with no config at all, which plain enter semantics would not produce — but it appears to be handled inside the text input, ahead of the matcher, so binding it is a no-op.
  • ctrl+j looks hard-wired to newline: rebinding it to chat:submit is ignored, while ctrl+s on what should be the same code path works fine.

If that is right, the 2.1.141 fix can only help on terminals that speak the kitty protocol (typically macOS, which is the setup in the #2054 thread). On Windows Terminal it cannot, because the keystroke is never constructed in the first place.

Suggested fix

On Windows, build the keystroke from the win32-input-mode record's Vk + Cs rather than from Uc, so that ctrl+enter and shift+enter become real, matchable keystrokes; and let a user binding on ctrl+j override the built-in newline handling.

Workaround for other Windows users

Bind submit to a key that survives the flattening, and translate ctrl+enter to it in Windows Terminal's settings.json:

"actions": [
  { "command": { "action": "sendInput", "input": "\^S" }, "keys": "ctrl+enter" }
]
{
  "bindings": [
    { "context": "Chat", "bindings": { "enter": "chat:newline", "ctrl+s": "chat:submit" } }
  ]
}

View original on GitHub ↗