vimxtermnumpad

In Vim, the 5-key on the numeric keypad inserts a line above the current line with "E"


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.


Solution

  • 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.