Detect the terminal and adapt Claude Code's own keybindings/hints to its stock keytab — retire /terminal-setup

Status Open
Maintainer reply None cached
Activity 3 comments · opened Jul 19, 2026

Summary

Flip the terminal-setup model. Instead of writing into the user's terminal config to fit a fixed keymap — and telling users on "unsupported" terminals that their terminal is deficient — detect the terminal and adapt Claude Code's own keybindings and on-screen hint to the sequences that terminal already emits by default. No setup step, no mutation of user files. Deprecate /terminal-setup.

Current behavior

For any terminal outside the hardcoded native-CSI-u allowlist, /terminal-setup either writes into user files (VS Code settings.json, alacritty.toml, Apple Terminal plist — with backup/restore code to recover when that breaks) or dead-ends with a "your terminal can't do Shift+Enter, use backslash+return" message. The framing reads as the terminal being at fault, and the mechanism mutates config the user never asked it to touch.

Technical reality (from the shipped parser, v2.1.215)

The input decoder already resolves several distinct Enter-with-modifier events, and the native allowlist is narrower than the set of capable terminals:

  • Native CSI-u allowlist is hardcoded to {ghostty, kitty, iTerm.app, WezTerm, Warp, windows-terminal}. This omits foot, rio, and Alacritty, all of which speak the kitty keyboard protocol — so even the "supported" path leaves capable terminals dead-ended.
  • The decoder understands more than Shift+Enter:
  • \x1b\r (ESC+CR — i.e. Alt/Meta+Enter on any terminal where Alt is meta-sends-escape) → {name: "return", meta: true}. Already a distinct, bindable key.
  • CSI-u \x1b[13;2u and modifyOtherKeys \x1b[27;2;13~ → return + shift.
  • Why Shift+Enter can't be bound on XFree4-keytab terminals: Konsole's stock keytab (keyboard "Default (XFree 4)", shared with qtermwidget) maps key Return+Shift : "\EOM", i.e. Shift+Enter emits \x1bOM. The decoder resolves OM → "return" with no modifier bits — a token identical to plain \r. So on Konsole, Shift+Enter and Enter are literally indistinguishable to Claude, which is exactly why both submit. No keybinding can separate them; the shift bit never reaches the wire.
  • The chat:newline action already exists; any decoded chord can be bound to it today.

Proposal

  1. Ship a per-terminal profile: given the detected terminal and its stock keytab, pick the chord that yields a newline/submit split which both the terminal emits distinctly and the decoder resolves distinctly. For XFree4-keytab terminals that is Alt+Enter (\x1b\r → return+meta), not Shift+Enter.
  2. Auto-apply the matching default binding (e.g. alt+enter → chat:newline) — Claude-side only, zero writes to the user's terminal files.
  3. Make the newline hint dynamic: show the chord for the detected terminal ("Alt+Enter for newline"), not a hardcoded Shift+Enter or backslash fallback.
  4. Reframe the messaging: "on <terminal> the newline chord is <Y>" instead of "your terminal doesn't support Shift+Enter."
  5. Deprecate /terminal-setup and retire the config-mutation + plist backup/restore machinery.

Why it's better

With terminal detection driving the binding, Konsole, GNOME Terminal (and the VTE family — Tilix, Terminator, XFCE Terminal, MATE Terminal), Alacritty, foot, st, and rxvt-unicode get correct newline/submit UX out of the box with zero setup — Alt+Enter is already a distinct, decodable key on all of them under stock config. Terminals already emitting the kitty protocol (kitty, Ghostty, WezTerm, iTerm2, rio, Warp, Windows Terminal) keep Shift+Enter. No terminal needs its config mutated.

Alt-for-newline also pairs naturally with the Alt+Arrow navigation many users already rely on, and it works out of the box for the majority who never change their terminal's defaults.

Caveat (for accuracy)

xterm ships metaSendsEscape: false by default — Alt sets the 8th bit rather than prefixing ESC — so xterm does not emit \x1b\r for Alt+Enter until the user flips that resource. It is deliberately excluded from the zero-config list above.

Verification notes

  • Konsole Return+Shift : "\EOM" and plain Return : "\r" confirmed from the stock Default (XFree 4) keytab.
  • xterm metaSendsEscape default-off: SysTutorials, frequal.
  • kitty keyboard protocol supporters: kitty docs, Rio docs.
  • Alacritty Alt-sends-ESC by default: alacritty#8248.

View original on GitHub ↗

3 Comments

aleksandr-proof · 2 months ago

OK... I suppose the almighty we're gonna replace you in 18 months people are having a very human problem.

vladysta · 2 months ago

Confirming this from a real Konsole user (KDE, Kubuntu 24.04). Ran into exactly the described symptom: Shift+Enter submits the message instead of inserting a newline, and /terminal-setup correctly reports it can't configure Konsole ("Terminal setup cannot be run from konsole").

After being told about the \ + Enter escape, I tried Alt+Enter and it worked immediately, with zero configuration — matching the proposal's diagnosis that Konsole's stock XFree4 keytab sends \x1bOM for Shift+Enter (indistinguishable from plain Enter) but \x1b\r for Alt+Enter (resolved as return+meta). So the fix in point 1 (default to Alt+Enter for XFree4-keytab terminals, surfaced dynamically instead of a hardcoded Shift+Enter hint) would have saved me the trial-and-error — the current /terminal-setup dead-end message doesn't mention Alt+Enter as an alternative.

aleksandr-proof · 1 month ago

Bumping, because Anthropic might get the bright idea to close this for inactivitiy.