Skip to content

fix(compose): deliver Enter as a discrete write so wrapping lines submit#101

Merged
gwitko merged 5 commits into
gwitko:devfrom
lakofsth:pr-compose-newline
Jul 2, 2026
Merged

fix(compose): deliver Enter as a discrete write so wrapping lines submit#101
gwitko merged 5 commits into
gwitko:devfrom
lakofsth:pr-compose-newline

Conversation

@lakofsth

@lakofsth lakofsth commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Problem

When composing over a mobile/SSH terminal, submitting a long line that wraps in compose-mode sometimes inserts a newline into the remote app's input instead of submitting it — the line "doesn't send," and the next line gets concatenated onto it.

Root cause

onSend currently does:

activeSession.sendText(line);
activeSession.sendKey(TerminalKey.enter);

Both calls fire in the same tick, so the line text and the Enter/CR are flushed together and arrive at the remote in a single terminal read() (verified with an strace of the receiving app: one read, e.g. "…long line…\r", a single trailing 0x0d, no bracketed-paste markers).

Some remote TUIs — Claude Code and other Ink/readline-style apps — classify a single read that delivers a whole long line ending in CR as a paste, and insert the trailing CR as a literal newline rather than treating it as a submit keypress. A short line (fits one line) is treated as typed input and submits fine; a wrapping line is treated as pasted and its CR becomes a newline. That length/wrap dependence is exactly the observed intermittency.

Fix

Deliver the Enter as a separate write, a short moment after the text, so the remote sees it as an isolated keypress rather than part of a pasted burst:

activeSession.sendText(line);
Future.delayed(const Duration(milliseconds: 120), () {
  activeSession.sendKey(TerminalKey.enter);
});

This is length-independent by construction and has no downside for shells or well-behaved TUIs (an isolated CR is a normal Enter everywhere). The 120 ms is a conservative gap chosen to survive SSH/tmux write coalescing; it can be tuned.

Testing

Validated on-device (Android, over SSH+tmux into a Claude Code session): before, long wrapping compose lines intermittently inserted a newline instead of submitting; after, repeated long wrapping lines submit reliably, and short lines are unaffected.

gwitko and others added 5 commits June 29, 2026 20:17
fix: skip Termux setup in Debian release build
fix:  make release workflow pass under act
A single read carrying <text>+CR is treated as a paste by some remote TUIs
(Claude Code / Ink-style apps), which insert the trailing CR as a literal
newline instead of submitting. Sending Enter as a separate, slightly delayed
write makes it an isolated keypress that submits regardless of line length.
@gwitko
gwitko changed the base branch from master to dev July 1, 2026 17:47
@gwitko
gwitko merged commit f4e3550 into gwitko:dev Jul 2, 2026
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.

2 participants