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 2 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 ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗