Skip to content

Feature request: emit a distinct CSI-u sequence for Ctrl+Enter in terminal blocks #3355

@jetnet

Description

@jetnet

Feature description

Please add terminal-block handling for Ctrl+Enter so WaveTerm emits a distinct key sequence instead of collapsing it to the same byte as Enter/newline.

A practical default would be to send the CSI-u representation for Ctrl+Enter:

ESC [ 13 ; 5 u

or, as a JavaScript string:

"\x1b[13;5u"

This would let terminal applications distinguish Ctrl+Enter from plain Enter and Shift+Enter.

Why this matters

Many interactive terminal applications and coding/chat CLIs support configurable input behavior such as:

  • Enter inserts a newline
  • Ctrl+Enter submits/sends the message

This is useful for multi-line prompts in AI/coding tools and other REPL-like terminal UIs.

Today, WaveTerm can already special-case modified Enter keys. PR #2523 added related handling for Shift+Enter newline support in frontend/app/view/term/term-model.ts. This request is the analogous missing case for Ctrl+Enter.

Current behavior

Testing in WaveTerm with a raw byte reader shows:

Enter        -> 0a
Shift+Enter  -> 0a
Ctrl+Enter   -> 0a
Alt+Enter    -> 1b 0a

So Enter, Shift+Enter, and Ctrl+Enter are indistinguishable to the program running inside the terminal. Alt+Enter is distinguishable because it carries an ESC prefix.

Expected behavior

Ctrl+Enter should produce a distinct sequence, for example:

Ctrl+Enter -> 1b 5b 31 33 3b 35 75

which is:

\x1b[13;5u

Terminal applications that understand CSI-u can then bind ctrl+enter separately from enter.

Suggested implementation

In frontend/app/view/term/term-model.ts, inside handleTerminalKeydown(), add a Ctrl:Enter branch near the existing Shift:Enter branch:

if (keyutil.checkKeyPressed(waveEvent, "Ctrl:Enter")) {
    this.sendDataToController("\x1b[13;5u");
    event.preventDefault();
    event.stopPropagation();
    return false;
}

This mirrors the existing approach used for Shift:Enter, but sends a standard CSI-u modified-key sequence instead of a newline byte.

Validation

After applying this locally, the raw-byte test becomes:

Enter        -> 0a
Shift+Enter  -> 0a
Ctrl+Enter   -> 1b 5b 31 33 3b 35 75
Alt+Enter    -> 1b 0a

With that output, applications such as Pi can configure:

{
  "tui.input.newLine": ["enter", "shift+enter", "ctrl+j"],
  "tui.input.submit": ["ctrl+enter"]
}

and get the intended behavior without local WaveTerm binary patching.

Related work

Acceptance criteria

  • Ctrl+Enter in a terminal block emits \x1b[13;5u or another documented distinct Ctrl+Enter sequence.
  • Enter and Shift+Enter behavior remains unchanged.
  • The behavior works on Linux, macOS, and Windows where the browser/Electron key event exposes Ctrl+Enter.
  • The behavior is documented if WaveTerm has terminal key handling documentation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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