8000 fix(terminal): Shift+Enter inserts a newline in TUI apps (Claude Code) by AvoChang · Pull Request #111 · amirlehmam/wmux · GitHub
[go: up one dir, main page]

Skip to content

fix(terminal): Shift+Enter inserts a newline in TUI apps (Claude Code) - #111

Merged
amirlehmam merged 1 commit into
amirlehmam:masterfrom
AvoChang:fix/shift-enter-newline
Jul 22, 2026
Merged

amirlehmam merged 1 commit into
amirlehmam:masterfrom
AvoChang:fix/shift-enter-newline

Conversation

@AvoChang
Copy link
Copy Markdown
Contributor

Problem

In a wmux terminal running Claude Code, Shift+Enter does not insert a newline — it submits the prompt instead. This works in cmux but was broken in wmux.

Root cause

xterm.js emits a plain \r (carriage return) for both Enter and Shift+Enter, so a TUI app can't distinguish them and treats Shift+Enter as submit. wmux's custom key handler in useTerminal.ts had no mapping for Shift+Enter.

Claude Code recognizes ESC + CR (\x1b\r) as a newline — the same sequence Alt/Option+Enter produces, and exactly what Claude Code's /terminal-setup configures for iTerm2/VSCode.

Fix

Intercept Shift+Enter in the terminal's attachCustomKeyEventHandler and write \x1b\r to the PTY, returning false to suppress xterm's default \r.

  • Excludes Ctrl/Alt/Meta, so Ctrl+Shift+Enter (zoom pane) and Alt+Enter are left untouched.
  • No effect on plain Enter (submit) behavior.

Testing

  • npm run build:renderer passes.
  • Manual: in Claude Code, Shift+Enter now inserts a newline; Enter still submits; Ctrl+Shift+Enter still zooms the pane.

🤖 Generated with Claude Code

xterm.js emits a plain \r for both Enter and Shift+Enter, so TUI apps
like Claude Code can't distinguish them and treat Shift+Enter as submit.
Intercept Shift+Enter in the custom key handler and write ESC+CR — the
same sequence Alt/Option+Enter produces and that Claude Code's
/terminal-setup wires up — so it inserts a newline instead of submitting.
Ctrl/Alt/Meta are excluded so Ctrl+Shift+Enter (zoom pane) is untouched.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@arnonuem
Copy link
Copy Markdown

i use another harness than claude code and for me shift enter works (windows)

@amirlehmam
amirlehmam merged commit 894bd41 into amirlehmam:master Jul 22, 2026
amirlehmam added a commit that referenced this pull request Jul 22, 2026
…roadcast mode

Follow-up to #111: sending ESC+CR via pty.write bypassed broadcast-input
mode (issue #64) — Shift+Enter only reached the focused pane while every
other keystroke fanned out. terminal.input() feeds onData, which owns the
broadcast fan-out, so the newline now behaves like any other key.

Also bump to 0.29.0.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UWsKzWVX4PXbYeymcMSDP3
@amirlehmam
Copy link
Copy Markdown
Owner

Merged — thanks @AvoChang, this is a clean fix and the choice of ESC CR is exactly right: it's the same sequence Alt+Enter produces and the one Claude Code's /terminal-setup wires up in other terminals, so TUI input parsers already treat it as "insert newline". The modifier guards keeping Ctrl+Shift+Enter (zoom pane) untouched were appreciated too.

One small follow-up landed on master (2b7202f): the sequence is now sent via terminal.input() instead of pty.write() directly, so it flows through onData and respects broadcast-input mode (#64) — otherwise Shift+Enter would only reach the focused pane while every other keystroke fans out to all panes.

@arnonuem re: "shift enter works for me in another harness" — worth noting that xterm.js (which wmux embeds) doesn't support modifyOtherKeys or the kitty keyboard protocol, so before this PR every app in wmux received a plain \r for both Enter and Shift+Enter; nothing could actually distinguish them. If your harness appeared to handle Shift+Enter, it was treating plain \r contextually. After this change it will receive ESC CR (the standard Alt+Enter encoding) instead — virtually all terminal input parsers handle that atomically as "newline", but if you see any regression in your harness after v0.29.0, please open an issue and we'll gate it.

Shipping in v0.29.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

0