With map we can map key sequence for commands or to create shortcut for repeating a sequence. The concept is easy, but there are too many map variants and they can be confusing.

All map commands are similar on how to define them: map {mapped} {to this}. For example:

" In Insert or Command-line, insert current date.
:imap! <F3> <C-R>=strftime('%c')<CR>

" Remove search highlight.
:nmap <C-l> :nohlsearch<C-R>=has('diff')?'<Bar>diffupdate':''<CR><CR><C-L>

Here is a list of map command:

  • map: Normal, Visual, Select, Operator-pending
  • map!: Insert and Command-line
  • nmap: Normal
  • vmap: Visual and Select
  • smap: Select
  • xmap: Visual
  • omap: Operator-pending
  • imap: Insert
  • lmap: Insert, Command-line, Lang-Arg
  • cmap: Command-line
  • tmap: Terminal

All of them has two more variation with :[type]noremap and :[type]unmap, for example :noremap or :unvmap.

There are special arguments, they must appear right after the command, before any other arguments:

  • <buffer>: Mapping will be effective only in the current buffer.
  • <nowait>: Vim by default waits for more keys if the current character is ambiguous, for example we have a mapping to sad and we want to create a new mapping for the current buffer that’s just sa, but default Vim waits a bit to see if you want to use sa or sad. With <nowait>, it will not wait after sa.
  • <silent>: Silences echoed text. It does not silence echos in commands, if a we have a map to a command, add :silent before the command to do that.
  • <unique>: It will fail if the mapping is already defined. It’s a safe way to not override a mapping we already have.

Using maps are easy and usually does not require too much brain… up until we meet some strange behaviour and realize we want to use :[type]noremap instead of :[type]map.

What’s the difference? While map allows recursion, noremap disallow recursion. For example mapping k to gk and j to gj allows us to use k and j to move between “visual lines” if we have long lines it will move the cursor not to the next line, but to the next displayed line.

:nnoremap k gk
:nnoremap j gj

Now we create a new map with map or noremap:

" It will be gk at the end, because k is already mapped to gk.
:map K k

" Now with K we can move between lines like we did before we mapped k to gk.
:noremap K k

Disclaimer: I do not promot mapping j/k to gj/gk but default, but I couldn’t find an easy to demonstrate example.