mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 09:44:31 +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