vimtricks.wiki Concise Vim tricks, one at a time.

What is the difference between :map and :noremap, and why should I use non-recursive mappings?

Answer

:nnoremap / :inoremap / :vnoremap

Explanation

Vim has two types of key mappings: recursive (:map, :nmap, :imap) and non-recursive (:noremap, :nnoremap, :inoremap). The critical difference is that recursive mappings expand other mappings within them, while non-recursive mappings use only default Vim behavior. Using non-recursive mappings prevents unexpected chains of remappings and is considered a best practice for almost all custom mappings.

How it works

  • :nmap j gj maps j to gj in normal mode — but if gj is also remapped, Vim follows that chain (recursive)
  • :nnoremap j gj maps j to gj using Vim's built-in gj behavior, ignoring any other mappings on gj (non-recursive)
  • The nore in noremap stands for "non-recursive"

Recursive mappings can cause infinite loops. For example:

:nmap j k
:nmap k j

This creates an infinite loop — j triggers k, which triggers j, which triggers k... Vim will hang or error. With :nnoremap, each mapping refers to the original key behavior, so there is no loop.

Mode-specific non-recursive mappings

:nnoremap  " Normal mode only
:inoremap  " Insert mode only
:vnoremap  " Visual and Select mode
:xnoremap  " Visual mode only (not Select)
:cnoremap  " Command-line mode only
:tnoremap  " Terminal mode only

Example

Common safe mappings for your vimrc:

" Move by visual lines instead of physical lines
nnoremap j gj
nnoremap k gk

" Quick save
nnoremap <leader>w :w<CR>

" Clear search highlighting
nnoremap <leader>h :nohlsearch<CR>

" Better window navigation
nnoremap <C-h> <C-w>h
nnoremap <C-j> <C-w>j
nnoremap <C-k> <C-w>k
nnoremap <C-l> <C-w>l

" Escape insert mode with jk
inoremap jk <Esc>

Tips

  • Always use noremap variants unless you specifically need recursive expansion (which is rare — typically only when chaining plugin mappings)
  • Use :verbose nmap {key} to see where a mapping was defined and what it expands to — invaluable for debugging conflicts
  • Use :nmap to list all normal mode mappings, :imap for insert mode, etc.
  • Use <leader> as a namespace prefix for your personal mappings to avoid colliding with built-in keys — set it with let mapleader = " " (space is a popular choice)
  • Add <silent> to suppress command-line echo: nnoremap <silent> <leader>w :w<CR>
  • Add <buffer> for buffer-local mappings that only apply to the current file: nnoremap <buffer> <leader>r :!python3 %<CR>
  • Use :unmap {key} or :nunmap {key} to remove a mapping

Next

How do I edit multiple lines at once using multiple cursors in Vim?