Search code examples
vimvim-tabular

How to "rewrite" existing vim key bindings?


I want to assign CTRL+L to go the next tab (:tabnext). I placed it at ~/.vimrc:

nmap <c-l> :tabnext<CR>

It worked fine, but I faced with a case when it doesn't work when I split screen on several windows. It seems that CTRL+L conflicts with "redraw screen" action assigned by default. For example, when I press CTRL+L on the center window I get nothing (see the screenshot):

enter image description here

However when I press the same on either left or right windows it works fine.. I think I need to "rewrite" the default action, doesn't it?

I use vim from terminal.


Solution

  • The window in the middle, if I am not mistaken, is netrw (Vim's standard plugin for file management). It is not a custom plugin, but it is a plugin nevertheless.

    If you take a look at :help netrw-ctrl-l, you will see that it is not just a redraw - it also refreshes the directory. So it is mapped from the plugin, overriding the default ctrl-l mapping for netrw windows only.

    If you execute :verbose nmap <c-l> in that window, you will see exactly where it is defined: in autoload/netrw.vim file in your Vim installation. Looking there, we find this snippet:

    if !hasmapto('<Plug>NetrwRefresh')
     nmap <buffer> <unique> <c-l> <Plug>NetrwRefresh
     imap <buffer> <unique> <c-l> <Plug>NetrwRefresh
    endif
    

    Which says, if <Plug>NetrwRefresh is not bound to anything, then bind <c-l>. This presents an easy solution: since netrw.vim is, like everything else, loaded after .vimrc, if you define those mappings to some other key, they won't be assigned to <c-l>, and your mapping will not be overridden. So just do this in your .vimrc:

     nmap <unique> <c-r> <Plug>NetrwRefresh
    

    However, a better way would be to not step on Vim's toes.