Skip to content

fix(tui): handle Ctrl+Enter and Shift+Enter as newline on WSL/Windows - #29445

Closed
nathanmilot wants to merge 1 commit into
NousResearch:mainfrom
nathanmilot:fix/tui-wsl-ctrl-shift-enter-newline
Closed

fix(tui): handle Ctrl+Enter and Shift+Enter as newline on WSL/Windows#29445
nathanmilot wants to merge 1 commit into
NousResearch:mainfrom
nathanmilot:fix/tui-wsl-ctrl-shift-enter-newline

Conversation

@nathanmilot

Copy link
Copy Markdown

Problem

On WSL, Windows, SSH sessions, and Windows Terminal, pressing Ctrl+Enter or Shift+Enter in the Hermes TUI submits the prompt instead of inserting a newline. The non-TUI CLI handles this correctly via _preserve_ctrl_enter_newline() in cli.py, but the TUI's key parser has no equivalent detection.

Root Cause

Three interrelated issues:

  1. Ctrl+Enter arrives as bare LF (\n) on WSL/Windows platforms, but parseKeypress treats LF identically to CR — both map to return with no modifiers. The textInput handler needs ctrl/shift/meta set to insert a newline.

  2. Terminals without TERM_PROGRAM (like Tabby) never get kitty keyboard protocol or xterm modifyOtherKeys enabled, so Ctrl+Enter and Shift+Enter arrive as undifferentiated CR.

  3. No ESC+CR fallback — some terminals send ESC + CR (\e\r) for Shift+Enter as a legacy fallback when enhanced protocols aren't active. The parser had no handler for this.

Fix

Three layers of defense added to parse-keypress.ts and terminal.ts:

Layer File Change
Platform-aware LF parse-keypress.ts isCtrlEnterAsLF() detects WSL/Windows/SSH/WT environments (mirrors cli.py). On these platforms, bare LF = return+ctrl → newline.
ESC+CR fallback parse-keypress.ts \e\r / \e\n parsed as return+shift → newline for terminals without kitty protocol.
WSL protocol enable terminal.ts supportsExtendedKeys() now also returns true when WSL/Windows/SSH/WT is detected, enabling kitty keyboard protocol on terminals (like Tabby) that don't set TERM_PROGRAM.

Tested on: Tabby (xterm.js) → WSL2 (Ubuntu) → tmux → Hermes TUI, with and without tmux. Ctrl+Enter and Shift+Enter now insert newlines.

Relation to existing PRs

Ctrl+Enter and Shift+Enter insert a newline in the TUI input on
platforms where the terminal collapses modified Enter to bare CR.
Three layers of defense:

1. parse-keypress.ts — isCtrlEnterAsLF() detects WSL/Windows/SSH/WT
   and treats bare LF as return+ctrl (mirrors cli.py's
   _preserve_ctrl_enter_newline). Also adds ESC+CR fallback as
   return+shift for terminals that don't support kitty protocol.

2. terminal.ts — supportsExtendedKeys() now also returns true for
   WSL/Windows/SSH/WT environments so kitty keyboard protocol and
   xterm modifyOtherKeys are enabled on terminals (like Tabby) that
   don't set TERM_PROGRAM.

3. Tabby added to EXTENDED_KEYS_TERMINALS for when TERM_PROGRAM
   is set.
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/tui Terminal UI (ui-tui/ + tui_gateway/) javascript labels May 20, 2026
@nathanmilot

Copy link
Copy Markdown
Author

Closing: this fix is already upstream in main via #22777 (commit 70bc52e).

@nathanmilot
nathanmilot deleted the fix/tui-wsl-ctrl-shift-enter-newline branch May 23, 2026 16:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/tui Terminal UI (ui-tui/ + tui_gateway/) P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants