[idea] Downgrade modified Enter to plain CR for panes that have not enabled an extended keyboard protocol (ssh remotes currently receive ^[[27;5;13~) #1591
ShotaKitazawa
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Current behavior
herdr delivers shift+enter and ctrl+enter to pane applications as the xterm modifyOtherKeys encoding (
CSI 27;2;13~/CSI 27;5;13~) even when the app inside the pane has never enabled modifyOtherKeys (CSI > 4;1m/CSI > 4;2m) or the kitty keyboard protocol (CSI > 1u).Byte-level observation, using a raw-mode stdin dumper running inside a pane with keys injected via
herdr pane send-keys(identical results on 0.7.3 and 0.7.4):CSI > 1 upush\r\r\x1b[27;2;13~\x1b[13;2u\x1b[27;5;13~\x1b[13;5uThe opted-in path is already correct — only the non-opted-in path leaks the escape sequence.
Why this hurts
Any pane app that doesn't speak these protocols receives junk on a modified Enter. The worst case is ssh, because the bytes pass through unchanged and there is no way to fix arbitrary remote hosts:
sshto any host.^[[27;5;13~is inserted as text; the line is not accepted as Enter.Local shells can be patched with
bindkey, but remote machines you don't control cannot, and non-shell remote apps (nano, less, plain vi) are affected too.What I'd like
When the pane's app has not enabled modifyOtherKeys or the kitty keyboard protocol, deliver modified Enter as plain
\r(drop the modifier), the same as plain Enter today. Keep the current behavior for opted-in panes — that path already works.Because opt-in sequences travel in-band, a remote agent's opt-in still reaches herdr's pane parser through ssh, so shift+enter newline in a remote Claude Code / vim keeps working after this change.
Prior art
tmux does exactly this: its pane-output parser records the XTMODKEYS state per pane (
input.c),input_key()selects the encoding from the pane's screen mode, and the legacy branchinput_key_vt10x()explicitly strips Ctrl from CR/LF/TAB before writing the single byte (input-keys.c). Verified on tmux 3.7b: a non-opted-in pane receives\rfor all three keys above; after the app sendsCSI > 4;2m, it receives the sameCSI 27;m;13~sequences herdr sends unconditionally.I'm aware the current behavior likely comes from the ghostty-vt encoder and matches Ghostty's own legacy-mode choice (ghostty-org/ghostty#3151, ghostty-org/ghostty#7780). A standalone terminal can argue it cannot know what the app understands. A multiplexer is in a better position: it tracks each pane's opt-in state precisely (herdr demonstrably does — see the kitty column above), so it can afford the tmux behavior.
Environment
herdr pane send-keys, which does not involve the outer terminalAll reactions