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:
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 re-mappable
@
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 screenshots 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:
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 white spaces, 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 ("Why does mapping the <C-...> key not work?", "I am not able to create a mapping for the key. What is wrong?", ...)
And a bonus: A question about best practices to find which keys to use in your mapping