Skip to content

TUI Shift+Enter submits instead of newline when terminal sends LF #18228

@morozsm

Description

@morozsm

Bug Description

In the modern Hermes TUI, some terminal stacks can distinguish plain Enter from Shift+Enter/Ctrl+J only by the raw byte received:

  • plain Enter sends CR (\r, byte 13)
  • Shift+Enter / Ctrl+J sends LF (\n, byte 10)

Hermes already has TUI input logic that can treat raw LF as “insert newline”, but the lower-level hermes-ink key parser clears keypress.raw for both CR and LF when it normalizes them to key.return. As a result, TextInput cannot see event.keypress.raw === '\n', so LF falls through as a normal return/submit instead of multiline input.

Steps to Reproduce

  1. Use a terminal stack where raw-mode input reports:
    • Enter → 13 / \r
    • Shift+Enter → 10 / \n
  2. Start the modern TUI: hermes --tui
  3. Type text in the composer.
  4. Press Shift+Enter.

Expected Behavior

Shift+Enter inserts a newline in the current draft while plain Enter submits.

Actual Behavior

Shift+Enter is normalized as return with no raw byte preserved, so it submits like plain Enter.

Environment

Observed on macOS terminal stack using Warp/tmux over SSH, where raw-mode byte testing confirms Enter and Shift+Enter arrive as distinct CR/LF bytes.

Proposed Fix

Preserve keypress.raw for CR/LF in ui-tui/packages/hermes-ink/src/ink/parse-keypress.ts so ui-tui/src/components/textInput.tsx can distinguish LF and insert a newline.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/tuiTerminal UI (ui-tui/ + tui_gateway/)sweeper:implemented-on-mainSweeper: behavior already present on current maintype/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions