diff options
author | Mantas Mikulėnas <grawity@gmail.com> | 2025-02-20 15:26:46 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2025-02-20 05:26:46 -0800 |
commit | 574ea6a1911b740bb611f0b658a83f606b6837bc (patch) | |
tree | a45d36fea0278f59d2482c84fc7e35c6a14c57e4 | |
parent | 4913b7895cdd3fffdf1521ffb0c13cdeb7c1d27e (diff) | |
download | rneovim-574ea6a1911b740bb611f0b658a83f606b6837bc.tar.gz rneovim-574ea6a1911b740bb611f0b658a83f606b6837bc.tar.bz2 rneovim-574ea6a1911b740bb611f0b658a83f606b6837bc.zip |
fix(keycodes): recognize <Find>, <Select> #28431
PuTTY sets TERM=xterm, but sends ESC[1~ and ESC[4~ for Home/End keys,
which does not match what the 'xterm' terminfo has for khome/kend, so
libtermkeys instead reports them as the original DEC VT220 names.
The VT220 came with a DEC LK201 keyboard which had the following keys in
the area above arrow keys (where PCs now have Ins/Del/Home/End/etc):
┌────────┬────────┬────────┐
│ Find │ Insert │ Re- │
│ │ Here │ move │
├────────┼────────┼────────┤
│ Select │ Prev │ Next │
│ │ Screen │ Screen │
└────────┴────────┴────────┘
These would send ESC[x~ sequences in the expected order:
┌────────┬────────┬────────┐
│ ESC[1~ │ ESC[2~ │ ESC[3~ │
├────────┼────────┼────────┤
│ ESC[4~ │ ESC[5~ │ ESC[6~ │
└────────┴────────┴────────┘
Modern terminals continue to use the same sequences for Ins/Del as well
as PageUp/PageDn. But the VT220 keyboard apparently had no Home/End, and
PuTTY apparently chose to re-purpose the Find/Select key sequences for
Home/End (even though it claims to emulate Xterm and this doesn't match
what actual Xterm does).
So when Home/End are used in Neovim through PuTTY with TERM=xterm (the
default setting), libtermkey finds no match for the received sequences
in the terminfo database and defaults to reporting them as <Find> and
<Select> respectively.
PuTTY is not unique here -- tmux *also* sends ESC[1~ and ESC[4~ after
its internal translation -- but the difference is that 'tmux' terminfo
correctly maps them to Home/End so Neovim recognizes them as such, while
PuTTY defaults to using 'xterm' which uses a different mapping.
This initial patch only allows Neovim to recognize <Find> and <Select>
key codes as themselves, so that the user could manually map them e.g.
using ":imap <Find> <Home>".
Alternatives:
- Using TERM=putty(-256color) would of course be the most correct
solution, but in practice it leads to other minor issues, e.g. the
need to have different PuTTY config profiles for older or non-Linux
systems that lack that terminfo, or tmux's insistence on rendering
italics as reverse.
- Using Neovim through tmux avoids the problem (as tmux recognizes
ESC[1~ on input), but is something that needs to be manually run
every time.
The keycodes.h constants are slightly misnamed because K_SELECT was
already taken for a different purpose.
-rw-r--r-- | runtime/doc/intro.txt | 2 | ||||
-rw-r--r-- | src/nvim/keycodes.c | 2 | ||||
-rw-r--r-- | src/nvim/keycodes.h | 2 | ||||
-rw-r--r-- | test/functional/ui/input_spec.lua | 4 |
4 files changed, 10 insertions, 0 deletions
diff --git a/runtime/doc/intro.txt b/runtime/doc/intro.txt index 0c654b8b30..5cb969a531 100644 --- a/runtime/doc/intro.txt +++ b/runtime/doc/intro.txt @@ -272,6 +272,8 @@ notation meaning equivalent decimal value(s) ~ <S-F1> - <S-F12> shift-function keys 1 to 12 *<S-F1>* <Help> help key <Undo> undo key +<Find> find key +<Select> select key <Insert> insert key <Home> home *home* <End> end *end* diff --git a/src/nvim/keycodes.c b/src/nvim/keycodes.c index a9f8c9222a..b6ba73f7c1 100644 --- a/src/nvim/keycodes.c +++ b/src/nvim/keycodes.c @@ -261,6 +261,8 @@ static const struct key_name_entry { { K_HELP, "Help" }, { K_UNDO, "Undo" }, + { K_FIND, "Find" }, // DEC key, often used as 'Home' + { K_KSELECT, "Select" }, // DEC key, often used as 'End' { K_INS, "Insert" }, { K_INS, "Ins" }, // Alternative name { K_KINS, "kInsert" }, diff --git a/src/nvim/keycodes.h b/src/nvim/keycodes.h index 5a7ddd4847..e24e30e7d0 100644 --- a/src/nvim/keycodes.h +++ b/src/nvim/keycodes.h @@ -352,6 +352,8 @@ enum key_extra { #define K_HELP TERMCAP2KEY('%', '1') #define K_UNDO TERMCAP2KEY('&', '8') +#define K_FIND TERMCAP2KEY('@', '0') // DEC key, often used as Home +#define K_KSELECT TERMCAP2KEY('*', '6') // DEC key, often used as End #define K_BS TERMCAP2KEY('k', 'b') diff --git a/test/functional/ui/input_spec.lua b/test/functional/ui/input_spec.lua index 98312c42c9..bc1f3480e1 100644 --- a/test/functional/ui/input_spec.lua +++ b/test/functional/ui/input_spec.lua @@ -62,6 +62,8 @@ describe('mappings', function() add_mapping('<kenter>', '<kenter>') add_mapping('<kcomma>', '<kcomma>') add_mapping('<kequal>', '<kequal>') + add_mapping('<find>', '<find>') + add_mapping('<select>', '<select>') add_mapping('<f38>', '<f38>') add_mapping('<f63>', '<f63>') end) @@ -130,6 +132,8 @@ describe('mappings', function() check_mapping('<KPComma>', '<kcomma>') check_mapping('<kequal>', '<kequal>') check_mapping('<KPEquals>', '<kequal>') + check_mapping('<Find>', '<find>') + check_mapping('<Select>', '<select>') check_mapping('<f38>', '<f38>') check_mapping('<f63>', '<f63>') end) |