2026-06-06 Shift+Enter Across the Terminal Stack

What I set out to do

Figure out why Shift+Enter stopped inserting a newline in Claude Code “as of yesterday.” It used to work; now it submits.

What I actually did

Peeled the terminal stack one layer at a time, and got the diagnosis wrong twice before getting it right.

  • Root of the regression: five weeks ago I dropped a Ghostty keybind (shift+enter=text:\x1b\r) in 682203d, on the theory that anthropics/claude-code#1282 made it unnecessary. The keybind had been masking a gap; removing it (and a recent hm switch regenerating the live Ghostty config) is what surfaced the break.
  • First fix (correct): the Claude Code docs say tmux needs set -s extended-keys on for Shift+Enter, and I only had allow-passthrough + the extkeys terminal-feature. Added extended-keys on (98cf3ec). This fixed the direct ghostty → tmux → claude case.
  • Second fix (wrong): for ghostty → tmux → nvim terminal → claude I theorized Neovim’s terminal doesn’t forward the kitty protocol and added a <S-CR> keymap. Committed it, then “corrected” the root cause in a follow-up commit. Both were built on a guess.
  • Actually inspecting the live system: driving the running Neovim over the MCP showed claudecode.nvim already maps <S-CR> (snacks provider, backslash+Enter trick). A keymap was never missing. The real cause was stale kitty negotiation: the Neovim had started ~19h before the tmux fix was applied, so it had handshaked while extended-keys was still off. Reverted both nvim commits (cd787f1).
  • Resolution: restart Neovim so it renegotiates with the now-extended-keys-on tmux. Confirmed working after restart. The tmux change was the only real fix; no nvim config change needed.

What was striking

Every layer masked the one beneath it. The Ghostty keybind had hidden the missing tmux setting for weeks; the stale Neovim negotiation then hid that the tmux fix already covered the nvim case too.

The bigger lesson: I had the Neovim MCP the entire time and could have run one maparg('<S-CR>','t') at the start to see claudecode already handled it. Instead I theorized and shipped two commits against a falsifiable assumption. Inspect the running system before writing a workaround. Saved this as a feedback memory.

Also worth remembering: RPC/MCP key injection enters below tmux, so it can’t validate a physical-key input path. The confirming Shift+Enter keypress is genuinely the user’s to make.

Top 3 tomorrow

  1. Nothing outstanding from this thread; it’s closed.
  • Commits: 98cf3ec (tmux extended-keys, the real fix), cd787f1 (revert of the redundant nvim keymap), 682203d (the original keybind drop that started it).
  • Upstream context: neovim/neovim#14400 (kitty protocol support), discussion #38130 (Shift in :terminal), anthropics/claude-code#1282.