61

I see a lot of questions on here where a user has a mapping which doesn't work and most of the time the reasons are pretty similar.

I suggest to make this question a reference for this kind of questions, to give a complete procedure to debug a mapping. If a user as a problem with a mapping they could be redirected here to eliminate the most common issues.

Of course there will still be particular cases which will require a dedicated question and will not be addressed here.

82

Your mapping doesn't do what it should do or behaves differently than expected, several steps are to follow to troubleshoot that:

Check that the key is effectively mapped to what it should do

Vim provides a command :map. By default (when no argument is given) the command will show all the mappings currently created. Here is an example of the result of the command:

result of <code>:map</code>

As always the doc is your friend: :h map-listing

You can see in the first column the mode of the mapping (n for normal mode, v for visual mode, etc), the second column shows the keys mapped and the last column what the keys are mapped to. Note that before the mapped actions some additional characters may appear, it is important to understand them:

  • * indicates that it is not remappable (i.e. it is not a recursive mapping, see know when to use nore later in this answer)
  • & indicates that only script-local mappings are remappable
  • @ indicates a buffer-local mapping

When asking for help about a mapping it is a good thing to add this information since it can help other people to understand the behavior of your mapping.

It is possible to restrict the prompt to a particular mode with the sister-commands of :map, like :vmap, :nmap, :omap, etc.

Now to restrict your search to the problematic mapping you can pass the key sequence you're debugging as the parameter of the commands, like this:

:map j
:map <Leader>m
:map <F5>

Note that the <Leader> key will be replaced by its actual value in the list.

If the result of the command shows that your keys are correctly mapped, it probably means that the problem doesn't come from Vim but from your terminal or your desktop environment. See the part Check if your mapping is actually intercepted by Vim

If the result of the command shows that your keys are not correctly mapped see the following part.

Check what overrode your mapping

Another convenient use of the :map command is to combine it with verbose: This will prompt the last file which modified your mapping.

For example, see these two screen-shots which are the results of :verbose map: the first one is a mapping modified by my .vimrc and the second a mapping created by a plugin:

Mapping set from vimrc

Mapping set from a plugin

Now if you see that another script modified your mapping you'll have to see if you can remove it or modify its behavior. (Note that some plugins provide variable to enable/disable their mappings, unfortunately not all of the plugins do that)

If the last file which changed your mapping is your .vimrc, make sure there is no other line that also defines a mapping for the same key. The .vimrc file will happily override any mappings with the last one of its kind in the file.

Check if your mapping is actually intercepted by Vim

Several situations may indicate that Vim doesn't intercept your key:

  • The command :map shows that your key is correctly mapped but pressing it does nothing.
  • Your mapping works on gVim (GUI) but does nothing in terminal Vim
  • Your mapping works on a defined terminal emulator but not on another
  • Your mapping works on a defined OS but not another one.

It is probably caused by one of the two following things:

  • Something intercepts the key before Vim: It can be different applications: your OS, your desktop environment, your terminal emulator, Tmux (if you use it)...

    To troubleshoot that, you should:

    • Try to temporarily remove your .tmux.conf if you use tmux
    • Refer to the doc of your terminal or of your desktop environment.

    You could also refer to sister-sites like super-user, Unix and Linux, askUbuntu, etc...

    If this is the problem, you then have two solutions: either you spend (a lot of) time to change the behavior of the application which causes the problem or you find another key combination to map which isn't intercepted by another application.

  • Your terminal emulator can't handle the key combination you're trying to map: Terminal emulators are implemented differently and some of them are not able to handle some particular key combination. (The reason why they can't is out of the scope of this question, see their doc or the sister-sites mentioned before for more details).

    In this case, you don't have a lot of solutions: either you change your key for another one which is handled properly by your terminal or you change your terminal emulator.

Check for the common pitfalls

Some problems in mappings are pretty recurrent and mostly related to the vimscript syntax. If your mapping has an unexpected behavior remember to check the following points:

  • Do not put a comment on the same line as your mapping, instead put the comment on the line above. Example:

    Don't do that:

    inoremap ii <esc>    " ii to go back into normal mode
    

    Vim will consider the whitespaces, the " and the comment as a part of the mapping which will result in an unexpected behavior.

    Instead do that:

    " ii to go back into normal mode
    inoremap ii <esc>
    

    This is easier to read and won't mess your mapping.

  • Do not pipe your commands with |. Example:

    Don't do that:

    nnoremap <Leader>x :w | !% python -m json.tools
    

    Vim will consider the pipe | as a command termination: When you source your .vimrc the mapping nnoremap <Leader>x :w will be created then the external command !% python -m json.tools will be executed.

    Instead do that:

    nnoremap <Leader>x :w <bar> !% python -m json.tools
    

    See an explanation about <bar>.

  • Know when to use nore: always.

    LearnVimscriptTheHardWay explain it pretty clearly: never use map, nmap, vmap, etc... Always prefer the nore version: noremap, nnoremap, vnoremap, etc... Why? nore stands for non-recursive mapping it means that the right-hand side of the mapping will be considered as the built-in feature even if you remmaped it. Example:

    Let's say you want to map > to delete a line and - to increment the indent of a line. If you don't use non-recursive mappings you'll do that:

    (Do not do that it's for the example)

    nmap > dd
    nmap - >
    

    When you'll hit > your line will be deleted, that's good. But when you'll hit - your line will also be deleted instead of being indented. Why? Because Vim understood "I received a hit on - which I should translate to > which I should, in turn, translate to dd".

    Instead do that

    nnoremap > dd
    nnoremap - >
    

    This way Vim will translate - as > and will not try to do any other translation because of the nore.

    Edit note "Always" may be an exaggerated answer in some cases you'll need to use the recursive mapping form but it is not really common. To clarify, I'll quote @romainl from this answer:

    Use a recursive mapping only if you intend to use any other mapping in your mapping. Use non-recursive mappings if you don't.

  • Remember that some key combinations are equivalent: Because of the hexadecimal codes that are produced some key combinations will be interpreted by Vim as another key. For example

    • <C-h> is equivalent to <backspace>
    • <C-j> as <enter>
    • On French keyboards <M-a> is the same as á and the same goes with all the <m- mappings. As @LucHermitte pointed out in the comment that is a problem with plugins using this type of mappings like vim-latex.
    • <C-S-a> is equivalent to <C-a>. Mapping Ctrl+upper case letter separately from Ctrl+lower case letter is not possible cause of the way the terminals send ASCII codes.

    When your mapping seems to affect another key try to use another lhs combination, if that solves the problem inspect which hexadecimal codes are sent to Vim.

  • Check that your leader is correctly defined: If your mappings involving <leader> doesn't work and you changed your leader with the command mapleader, check that the definition of your leader is done before the definition of the mappings. Otherwise, Vim will try to create mappings with a key which is not the one you think. Also if you want to use the space bar as your leader (which is pretty current) make sure that you used the correct notation: let mapleader = "\<Space>"

Your mapping still doesn't work?

If you went through all the steps of this answer and your mapping still doesn't work like you want, you'll probably want to ask for help on this site.

To help people to help you remember to provide some crucial information like:

  • The command you used to define your mapping.
  • What you are expecting your mapping to do.
  • A precise description of the problem:

    "It doesn't work" won't be really helpful to people who will try to help you. You should precise if the mapping doesn't do anything or how it behaves differently than what you were expecting.

  • Also indicate that you actually followed the steps described here and the results you get with :map and :verbose map

All of this will save you and the users of the site a lot of time.


A useful command: :unmap

Sometimes it can be useful to reset a mapping without quitting Vim to help debugging its behavior.

To do so you can use the command :unmap <key> which will remove the mapping assigned to <key> for Normal, Visual and Operating-pending modes. :iunmap will remove mappings for Insert mode. For other modes see :help :unmap.


References

An excellent introduction to mapping: learnvimscriptthehardway (And a lot of other aspects of Vim)

The doc: :h mapping, :h :map

Section 20 of Vim's FAQ is about mapping and contains interesting questions:

And a bonus: A question about best practices to find which keys to use in your mapping

  • 2
    To share my experience with other users as our moderator suggested to do. And because I see a lot of questions on here where a user has a mapping which doesn't work and most of the time the reasons are pretty similar as I said in the first line of my question, so gathering these reasons should allow to reduce the number of duplicate questions about mapping. – statox Jul 1 '16 at 5:35
  • 1
    A recurring problem with vim-latex and French keyboards: <m-i> and é are the same for vim, and it's the same with all meta+key: they are associated to a different diacritic. – Luc Hermitte Nov 3 '16 at 9:21
  • 1
    It's also important to know how to read buffer-local mappings when we ask for their definition with :map {sequence} -> there is a * in reverse highlight in what vim prints before the associated action. – Luc Hermitte Nov 3 '16 at 9:23
  • 2
    Sometimes we really want to debug what happens. Typically when the mapping calls a plug mapping, or a function with a name impossible to remember or with complex parameters. In that case we can execute: :debug normal {keysequence} (without any bang), or :debug i{keysequence} for insert mode mappings, etc. If the key sequence contains things like special keys (<cr>, <left>, <c-x>, <m-i>, <leader>...). Then we need to play with execute + double-quotes + backslash -> :debug execute "normal \<leader>\<cr>Z". – Luc Hermitte Nov 3 '16 at 9:28
  • 2
    Regarding meta-sequences, this is a old point of FAQ as vim-latex did chose to use things like <m-i>. Most users don't use the meta key as they are strongly oriented toward running Vim in the terminal -- where the meta-key cannot be used simply. We need to use gvim or macvim to notice the issue. – Luc Hermitte Nov 3 '16 at 9:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.