summaryrefslogtreecommitdiff
path: root/config
diff options
context:
space:
mode:
authorIgor Soarez <igor@soarez.org>2026-10-26 16:20:45 +0200
committerIgor Soarez <igor@soarez.org>2026-10-26 16:20:45 +0200
commit65d3da052dcecba82f05e4244f33c3f489b575c5 (patch)
treeac7fd673208f38d45d9aa9a4d8e3a0e815e7cde3 /config
parent4f40b8ea2f224132dddde4f505191c3662620741 (diff)
tmux: Shift+Enter reaches pi, Neovim and Claude Code under Ghostty
With extended-keys off, tmux hands every pane a plain CR for Shift+Enter and Ctrl+Enter, so pi submits where it should add a line, and warns about it at every start. Turning it on is not enough on its own, though pi's warning then goes quiet: tmux asks the outer terminal for modified keys only when it knows the terminal can send them, and tmux does not recognise Ghostty, whose terminfo does not declare it either. So Ghostty also gets the extkeys feature, and the format is csi-u, the one pi asks for. `on`, not `always`, which would send zsh ESC[13;2u for Shift+Enter. The paste corruption the old comment blamed on extended keys shows up only in a display-popup, where tmux re-encodes the newlines of a paste for an app that asked for modified keys; normal panes get the pasted bytes unchanged. Nothing here opens popups. Checked on tmux 3.7c against a pty answering as Ghostty 1.3.1, with pi itself in the pane, and by hand in Ghostty on a separate tmux server. The csi-u line is set with -q, since extended-keys-format arrived in tmux 3.5; 3.4 was not tried, only an unknown option name standing in for it.
Diffstat (limited to 'config')
-rw-r--r--config/tmux.conf25
1 files changed, 20 insertions, 5 deletions
diff --git a/config/tmux.conf b/config/tmux.conf
index ceb59e6..9a264bd 100644
--- a/config/tmux.conf
+++ b/config/tmux.conf
@@ -149,11 +149,26 @@ if-shell -b 'test -e ~/.local/share/tmux/color.conf' {
# swallows Claude Code's desktop notifications and progress updates.
set -g allow-passthrough on
-# Extended key sequences - disabled for Ghostty compatibility
-# Ghostty implements the Kitty keyboard protocol natively, and tmux's extended-keys
-# conflicts with paste operations (causes escape sequences like ^[[27;5;106~ to appear)
-# See: https://github.com/ghostty-org/ghostty/issues/7997
-set -g extended-keys off
+# Modified keys -- Shift+Enter, Ctrl+Enter, Ctrl+J -- reach the apps that ask
+# for them (pi, Neovim, Claude Code) instead of arriving as a plain Enter. All
+# three lines are needed:
+#
+# - extended-keys on: a pane may request xterm modifyOtherKeys. Not `always`,
+# which forces it on every pane and hands zsh ESC[13;2u for Shift+Enter.
+# - extended-keys-format csi-u: the format pi asks for, and the one it can
+# decode in the misfire below. tmux 3.5 and later; -q lets 3.4 skip it.
+# - extkeys for Ghostty: tmux asks the outer terminal for modified keys only
+# when it knows the terminal can send them, and it does not recognise
+# Ghostty, whose terminfo does not say so either. Without this the two lines
+# above change nothing there: Shift+Enter still arrives as a bare CR.
+#
+# Panes that ask for nothing, shells included, still get plain bytes, pastes
+# too. One known misfire: in a display-popup tmux re-encodes the newlines of a
+# paste, so an app there that asked for modified keys sees ESC[106;5u in
+# their place. Nothing here opens popups.
+set -g extended-keys on
+set -gq extended-keys-format csi-u
+set -as terminal-features 'xterm-ghostty:extkeys'
# Caps Lock is F20 (hammerspoon). What reaches tmux for it is read as S-F10 and
# passed on as ESC[21;2~, which Neovim takes for F22 and types out as text. Wispr