mirror of
https://github.com/neovim/neovim
synced 2025-07-16 01:01:49 +00:00
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.
This commit is contained in:
@ -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*
|
||||
|
@ -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" },
|
||||
|
@ -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')
|
||||
|
||||
|
@ -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)
|
||||
|
Reference in New Issue
Block a user