-1

While using Vim under Linux Mint 20.2 (with NumLock off), when I hit the NumPad center key (5), a line is inserted above the current line, a capital E appears, and I am left in Insert mode. I often mistakenly hit the 5 key when trying to navigate using the NumPad cursor keys, and I would love to redefine the NumPad 5 to do nothing. I've tried remapping the key in .vimrc (using noremap <Esc>[E <Esc>, for example), but it has no effect. Note, the ANSI sequence produced when I press the NumPad5 is \033[E

FYI, I have TERM=xterm-256color.

SGeorgiades
  • 1,771
  • 1
  • 11
  • 11

2 Answers2

2

Note: this answer generally talks about the numpad in a no-numlock context. All numbers on the numpad can be mapped when numlock is on by using <k0>...<k9>. References to the mapability of keys is therefore in a no-numlock context

Note, the ANSI sequence produced when I press the NumPad5 is \033[E

Vim doesn't see it that way.

On my system (Mint 20.2 with Cinnamon under X11), no-numlock 5 produces ^[OE. That O is very important to the observed behavior. o means "go to a new line under and enter insert mode", and O means the exact same thing, but to a new line above. The next E is then interpreted as an insert mode character, because Vim.

Moreover, esc is represented as ^[, so for mapping purposes, you only need <esc>. This point is easier to demonstrate in Vim:

Image showing ^[OE, with ^[ highlighted in grey.

^[ is additionally treated as a single character. If you want to play around with this, pop into insert mode and press <C-v>. The next key(bind) you press will be printed literally to the screen

This means what you actually want is:

nnoremap <Esc>OE <nop>

Note that I'm not sure how terminal input processing applies here; this may only hold for certain terminals, or even only apply to X11.

Another trick in general here, and a way to make sure the keycode is correct for your terminal, is that you can type :nnoremap , and then press Ctrl+v+Numpad 5. This will give you the exact keycode as Vim sees it, which you then can map to whatever you have planned.

If you do this in gVim, however, you'll find that numpad 5 without numlock doesn't actually produce a keycode detectable by gVim. This presumably means it can't be mapped (unless there's some way I just don't know about - if there is, please prove me wrong). But because it doesn't spew out a terminal code, there's the added benefit of not needing to remap it for this particular purpose, because it doesn't have the problem you're trying to avoid here in the first place.


romainl mentioned :help key-notation in the comments, but there's something to keep in mind here:

gVim not producing a keycode usually means there isn't one. <C-v> followed by numpad 9 in gVim produces <kPageUp>, but followed by numpad 5, it doesn't produce anything. Secondly, if you read :h key-notation, you'll see that it only defines home, end, up, and down, as well as the various operators, enter, and the decimal point. 2, 4, 6, and 8 are all registered as normal arrow keys, meaning <Down>, <Left>, <Right>, and <Up>. There's no way to detect these on the numpad specifically, but that's not really important.

If you've been keeping track, you'll find that numpad 5 is excluded. Note: When numlock is on, <C-v> + numpad 5 doesn't output anything in Vim or gVim, because the definition is:

Insert the next non-digit literally.

See :h i_CTRL-V.

TL;DR:

<C-v> is your friend.

Use:

nnoremap <Esc>OE <nop>

Or use <C-v> to insert the keycode, that may or may not be terminal dependent.

The mapping isn't necessary in gVim, and may not be possible.

1

The reason why you see this behavior is that Vim uses only the termcap interface of the terminal database. If it used terminfo, it would see a wider range of information.

Typing the key on the keyboard is misleading, because Vim (like almost all terminal applications) puts the keypad into application mode, which causes the terminal to send Escape and O rather than Escape and [ as a prefix. In terminal notation, that is \EO. In XTerm Control Sequences, that is referred to as SS3 (technically a misnomer since that applies to output, while keyboard input is input — but since no standards apply to keyboard input, that's good enough).

The terminal description for xterm at one point assigned \EOE to the kbeg capability (i.e., terminfo, which termcap names @1). That was a while back, around 1996.

Terminfo names are generally 3-5 characters, while termcap names are always 2.

Standard terminfo has a limited number of special keys (such as those for the numeric keypad which you are familiar with). All of the standard termcap names correspond to these terminfo names. In the standard arrangement, there are only five keys associated with a keypad: ka1, ka3, kb2, kc1, and kc3, which correspond to termcap's K1, K2, K3, K4, and K5. (Why there are no standard k2, kb1, kb3, or kc2 is long forgotten).

Looking for ways to improve the terminal descriptions in ncurses, a few different layouts of the standard keys have been proposed. But the best solution lies in adding new keys, using extended capabilities (a feature of ncurses since 1999). Those extensions all have names, and are chosen to conform to terminfo naming conventions. So... in May 2019, the terminfo building blocks xterm+keypad and vt220+keypad were introduced. In the former (used in xterm-new and xterm-256color, that key is named kp5.

There's no kp5 in the standard names listed in the terminfo(5) manpage. It is an extended (user-definable) key. In the older scheme some other key was unavailable for applications.

An ncurses application would automatically be able to use all of the keys, because ncurses uses terminfo (and adds all of the keys in a terminal description to its special cases for timing).

Vim will not see that key's definition because it views only a fraction (about a third) of the terminal description. Since it does not see the definition, it does not add that to the special cases where it will wait (a short time) for the completion of the character-sequence sent on that key. As noted in the other answer, in that case, Vim will see the commands Escape and O to insert the third character in the sequence, "E".

Thomas Dickey
  • 51,086
  • 7
  • 70
  • 105