Repository navigation
Possible regression: tmux silently swallows extended keys #2705
Description
Activity
Worth noting other extended keys work fine.
C-1orC-S-aare Ok, it's just C-i, C-m and I imagine some of the other special keys which are implicitly translated to other keys.tmux only has one representation for
C-iandC-mand they are the same asTabandEnter.The problem if we had two is - if you do
bind C-i lskwhich do you mean? If someone is using a terminal without extended keys,C-iwon't work anymore.My terminal emulator sends
\033[105;5ufor C-i and\033[109;5ufor C-m. It sends different keys for TAB and RET and I'd like to be able to handle them separately. Which I can on an older tmux version but the one from master seems to implicitly translate\033[105;5uto TAB when it should be to C-i.Yes, I know, it is intentional. I'll have to think about what to do, I don't want
C-ito stop working for everyone not using extended keys.I don't want C-i to stop working for everyone not using extended keys.
Fair enough, but the issue I have is in emacs I've bound C-i seperate from TAB and tmux seems to send TAB in both cases. I can understand tmux internally treating C-i as TAB but when sending to a pane I'd prefer it sent the same input that was sent to tmux instead of deciding to send what it thinks the input was.
Admittedly I'm not very experienced in the domain of terminal emulators. There might be some special mode or sequence emacs has to send to get this working, not sure whether this is an application problem or a tmux one :/.
Actually if you enable extended keys shouldn't you expect C-i to stop working as TAB. You're sending different sequences so expecting the same behaviour seems odd.
emacs will need to send the sequence to enable extended keys or you will need to set
extended-keystoalways.But at the moment
C-iandTabwill be the same no matter what.If someone does
bind C-i lskin.tmux.confbut theirC-ikey actually sendsTabthen if tmux treats them differentlyC-iwill not work.emacs will need to send the sequence to enable extended keys
How do I check whether it's done this or not, other extended keys (eg. C-1) work fine so it might've.
you will need to set extended-keys to always.
I did try that before opening the issue, didn't have any noticable difference.
But at the moment C-i and Tab will be the same no matter what.
Yep. That's my issue 😋. Would you be open to distinguishing them through a terminfo extension or something to that affect.
If they are working then emacs must do it.
Right but it is not as easy as just knowing it should happen.
I think tmux will need to store
C-iandTabas separate key codes and then do some sort of "try this key also" lookup if extended keys is set to off.So when tmux comes to lookup
Tabin the key tables it first tries it as-is and if that is not found it tries it asC-ias well if extended-keys is off.We currently (deliberately) only support modifyOtherKeys mode 1 which does not alter
Tab/C-i.It would be nice to support modifyOtherKeys mode 2 also but it changes a lot more keys as well. So the easier stuff is:
-
tmux would have to represent the keys differently internally, I am not sure whether it is better to replace
C-iwithKEYC_CTRL|'i'and leaveTabas\011or to replaceTabwithKEYC_TABand leaveC-ias\011. Similarly forC-a, does it becomeKEYC_CTRL|'a'or remain\001? It seems more consistent to do the former, but probably less disruptive to do the latter. -
All the internal use of keys would have to change to the new mapping (key-string.c, status.c, mode-tree.c, window-*.c).
-
Incoming keys (tty-keys.c) would need to map the keys correctly, and Backspace would need to be dealt with.
-
When writing keys to panes which have not sent the escape sequence or have requested mode 1, keys would need to be mapped, so
KEYC_CTRL|'i'sends\011,KEYC_CTRL|'a'sends\001and so on. We already do this to map, for example,C-S-itoC-i- see input-keys.c:486.
The problems come with key bindings:
-
If someone binds
C-i,C-IorTabin.tmux.confat the moment, they are the same. Likewise,C-S-i,C-S-IorS-Tabare allS-Tab. We do not want to break this, and I am not sure the best way to do it. Perhaps we add a separate modifier for "mode 2 ctrl key" soC-iwould have to be bound asE-ior something, if you bindC-iyou end up withTabas before. Not very intuitive however. -
modifyOtherKeys = 2 terminals send
C-S-A(27;6;65) forC-S-a. But we needC-AandC-ato both beC-a. This is not so big a problem I think because I don't know of any terminals that actually sendC-S-a(27;6;97), so it is probably OK just to force allC-AtoC-aon input and mapC-S-atoC-S-Aon output for mode 2 panes.
-
Have you had a chance to think more on modifyOtherKeys mode 2?
I just did a system upgrade which accidentally upgraded tmux as well and now I'm gonna have to revert back to make sure all my keybindings still work 😁.
EDIT:
I couldn't seem to get the earlier version of tmux to build (strange makefile shenanigans). In the end I ended up commenting out the following block and my extended-keys started working again. This is a stop-gap fix and almost certainly will break something somewhere else but if any-one else wants a quick and dirty solution here it is:
diff -u --label /home/mohkale/.local/temp/20210614.225927/tty-keys.c --label \#\<buffer\ tty-keys.c\> /home/mohkale/.local/temp/20210614.225927/tty-keys.c /tmp/buffer-content-qkwMFp --- /home/mohkale/.local/temp/20210614.225927/tty-keys.c +++ #<buffer tty-keys.c> @@ -957,25 +957,25 @@ * Don't allow both KEYC_CTRL and as an implied modifier. Also convert * C-X into C-x and so on. */ - if (nkey & KEYC_CTRL) { - onlykey = (nkey & KEYC_MASK_KEY); - if (onlykey < 32 && - onlykey != 9 && - onlykey != 13 && - onlykey != 27) - /* nothing */; - else if (onlykey >= 97 && onlykey <= 122) - onlykey -= 96; - else if (onlykey >= 64 && onlykey <= 95) - onlykey -= 64; - else if (onlykey == 32) - onlykey = 0; - else if (onlykey == 63) - onlykey = 127; - else - onlykey |= KEYC_CTRL; - nkey = onlykey|((nkey & KEYC_MASK_MODIFIERS) & ~KEYC_CTRL); - } + /* if (nkey & KEYC_CTRL) { */ + /* onlykey = (nkey & KEYC_MASK_KEY); */ + /* if (onlykey < 32 && */ + /* onlykey != 9 && */ + /* onlykey != 13 && */ + /* onlykey != 27) */ + /* /\* nothing *\/; */ + /* else if (onlykey >= 97 && onlykey <= 122) */ + /* onlykey -= 96; */ + /* else if (onlykey >= 64 && onlykey <= 95) */ + /* onlykey -= 64; */ + /* else if (onlykey == 32) */ + /* onlykey = 0; */ + /* else if (onlykey == 63) */ + /* onlykey = 127; */ + /* else */ + /* onlykey |= KEYC_CTRL; */ + /* nkey = onlykey|((nkey & KEYC_MASK_MODIFIERS) & ~KEYC_CTRL); */ + /* } */ if (log_get_level() != 0) { log_debug("%s: extended key %.*s is %llx (%s)", c->name, Diff finished. Tue Jun 15 00:30:13 2021
In the mean-time I'll try to get started on the suggestions by nicm (at least the easy ones).
I started looking at it but it is substantial work and I don't have time to do it at the moment.
Reacted by Mohsin Kaleem, Ben Jackson, Joel Johnson, Linus Arver, lacygoill, milanglacier, Nick Dow, Scc, sandwich, 三咲雅 misaki masa and 5 moreJust a heads up but I ran into what I assume is the same thing with and when going from 3.1 to 3.2a.
25 remaining items
Got it.
Downgrade to 3.1c and add the following to alacritty.yml:
key_bindings: - { key: I, mods: Control, chars: "\x1b[105;6u"@mohkale Thanks for the pointer to the related snippet. I revisited this issue today because I can no longer ignore the inconvenience of not being able to yank in vi mode in version 3.1_c. Could someone help me check my understanding:
This function
tty_keys_extended_keyessentially handles CSI u sequences. Applications that do support CSI u sequences will ask about the availability of support in the terminal emulator, and the terminal emulator (I am using kitty) will start sending these sequences instead of legacy keycodes.Normally without tmux this should work fine, but tmux intercepts the CSI u sequences and translates those that correspond to Ctrl-keys back into their original forms. IMO this is unnecessary and incorrect behavior. If the terminal emulator does not support CSI u sequences, it would not have sent those in the first place so this function is never invoked. I think tmux should honor the terminal emulator's intention and not interfere with applications that explicitly ask for CSI u support.
I have also confirmed that removing this translation does NOT break legacy terminal emulators. I recompiled tmux without the following lines:
else if (onlykey >= 97 && onlykey <= 122) onlykey -= 96;
If I configure kitty to send
\x1b[105;5uforctrl+i,^[[105;5uis printed correctly in cat when I pressctrl+i. Otherwise (if I don't specify this keymap in kitty config) it delivers Tab.I think it is fully safe to remove these lines, and all Neovim/Emacs/kakoune/etc. users will be happy then.
@nicm Please point out if I missed anything. PR is on the way. I still need to figure out what other lines nearby are doing though. Pointers are welcomed.
Reacted by edte and Steven XuReacted by Murtaza and Andy YuFound some references:
- https://www.leonerd.org.uk/hacks/fixterms/
- https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797
I plan to rework this function to match the specification I found. Let me know if it doesn't make sense or needs more discussion.
Reacted by edte, Steven Xu, Alex C and Krikchai PongtaveewouldSee also Comprehensive keyboard handling in terminals - kitty. It's an improved Fix Terminals - Please that's used by many programs.
Reacted by tummetott, Tom van der Sommen and Johnson HuSee also Comprehensive keyboard handling in terminals - kitty. It's an improved Fix Terminals - Please that's used by many programs.
Yess I second this. If tmux would support kitty's keyboard protocol all problems would be solved as it's superior and backward compatible with fixterm CSI u sequences
Reacted by Tom van der Sommen and Michael Brumlow@mohkale Thanks for the pointer to the related snippet. I revisited this issue today because I can no longer ignore the inconvenience of not being able to yank in vi mode in version 3.1_c. Could someone help me check my understanding:
This function
tty_keys_extended_keyessentially handles CSI u sequences. Applications that do support CSI u sequences will ask about the availability of support in the terminal emulator, and the terminal emulator (I am using kitty) will start sending these sequences instead of legacy keycodes.Normally without tmux this should work fine, but tmux intercepts the CSI u sequences and translates those that correspond to Ctrl-keys back into their original forms. IMO this is unnecessary and incorrect behavior. If the terminal emulator does not support CSI u sequences, it would not have sent those in the first place so this function is never invoked. I think tmux should honor the terminal emulator's intention and not interfere with applications that explicitly ask for CSI u support.
I have also confirmed that removing this translation does NOT break legacy terminal emulators. I recompiled tmux without the following lines:
else if (onlykey >= 97 && onlykey <= 122) onlykey -= 96;
If I configure kitty to send
\x1b[105;5uforctrl+i,^[[105;5uis printed correctly in cat when I pressctrl+i. Otherwise (if I don't specify this keymap in kitty config) it delivers Tab.I think it is fully safe to remove these lines, and all Neovim/Emacs/kakoune/etc. users will be happy then.
@nicm Please point out if I missed anything. PR is on the way. I still need to figure out what other lines nearby are doing though. Pointers are welcomed.
I compiled your fork and configured it in kitty
map ctrl+i send_text all \x1b[105;5uBut after restarting tmux, ctrl+i will still be recognized as tab.- added a commit that references this issue
on Mar 14, 2024 - added a commit that references this issue
on Apr 25, 2024 For completeness I'm cross linking this (closed) issue #3335 which proposes to implement the kitty keyboard protocol. This would make it easier to handle/distinguish key sequences like
ctrl-iandtab.Reacted by tummetott, Valeriy Sakharov, Tom van der Sommen, Noam Stolero, Erik Nygren, Johnson Hu and Magnus GroßMode 2 is now supported and mode 1 more fully as of tmux 3.5a, although I would probably use master since there have been a few fixes.
This issue has been automatically locked since there has not been any recent activity after it was closed.
- locked as resolved and limited conversation to collaborators
on Dec 23, 2024
Issue description
My terminal emulator has special extended keys for C-i and C-m distinct from the standard translation of these key sequences to TAB and RET respectively.
Up until recently I used to be able to bind TAB and C-i independently without issue. For example after running
tmux bind-key -T prefix / command-prompt -k -p key "list-keys -1N "%%%"". I can do<prefix> / C-iand it shows C-i, whereas<prefix> / TABshowed TAB.However now
C-iis shown as TAB and C-m is shown as RET.I tried installing an older build (not sure about the specific commit, the version still says next-3.3) and this wasn't an issue there dispite using the same config. I believe this is a regression.
Required information
Please provide the following information:
tmux -V).tmux next-3.3uname -sp).Linux unknownecho $TERM).st-256color,tmux-24bittmux kill-server; tmux -vv new). older-server-log, master-server-log