How to remap [[ and ]] in vim


Remapping [[ and ]] should be straightforward…

Suppose you would like to remap [[ and ]] to navigate a Quickfix window. That’s straightforward enough: simply add these lines to your ~/.vimrc:

nnoremap [[ :cprevious<cr>
nnoremap ]] :cnext<cr>

… but sometimes fails

These mappings don’t work for certain filetypes because their ftplugins already remap [[ and ]]. Ftplugins are loaded after ~/.vimrc so their settings take precedence.

Fortunately, vim provide a way to overrule this thanks to the ~/.vim/after mecanism.

How to fix this

  1. Create the following directory if it doesn’t exist: ~/.vim/after/ftplugin

  2. In this newly created directory, create the folliwing file: mapping_fix.vim:

$ mkdir ~/.vim/after/ftplugin
$ cat ~/.vim/after/ftplugin/mapping_fix.vim
nnoremap <buffer>[[ :cprevious<cr>
nnoremap <buffer>]] :cnext<cr>
  1. Each filetype that is affected is simply linked to mapping_fix.vim. E.g. for filetype ‘foo’, run:
$ ln -s mapping_fix.vim foo.vim

How can I find out the filetype of a buffer?

In vim, run:

:set ft?

How do I know whether I need to do this for filetype ‘foo’?

Make sure you’re in a buffer where a ‘foo’ file is loaded and run:

:verbose nmap [[

You should get only one line starting with n [[ and this line should be:

n  [[          * :cprevious<CR>

If you get more than one line, then the above ln -s is needed.

Which filetypes are affected?

So far, I found the following filetypes:

Therefore my ~/.vim/after/ftplugin directory looks like this:

$ cd ~/.vim/after/ftplugin/
» $ ls -l | grep fix | tr -s ' ' | cut -d' ' -f9-
mapping_fix.vim
markdown.vim -> mapping_fix.vim
php.vim -> mapping_fix.vim
rust.vim -> mapping_fix.vim
vim.vim -> mapping_fix.vim

It’s not unreasonnable to think that there are more.

Sources

  1. StackExchange

  2. :help ftplugin-overrule