How do I create a key mapping that only applies to the current buffer?
Answer
:nnoremap {lhs} {rhs}
Explanation
The <buffer> flag in a mapping definition makes it local to the current buffer. The mapping exists only in that buffer — other buffers are unaffected. This is how filetype-specific mappings work: you define them in ftplugin files, and they only activate for files of that type.
How it works
:nnoremap <buffer> <leader>r :!python3 %<CR>
This mapping only exists in the buffer where it was defined. Opening another buffer will not have <leader>r mapped (unless that buffer also defines it).
Practical use: ftplugin files
Create ~/.vim/ftplugin/python.vim:
nnoremap <buffer> <leader>r :!python3 %<CR>
nnoremap <buffer> <leader>t :!pytest %<CR>
setlocal shiftwidth=4 tabstop=4 expandtab
Create ~/.vim/ftplugin/javascript.vim:
nnoremap <buffer> <leader>r :!node %<CR>
nnoremap <buffer> <leader>t :!npm test<CR>
setlocal shiftwidth=2 tabstop=2 expandtab
Now <leader>r runs Python in .py files and Node in .js files.
Buffer-local vs global
| Mapping | Scope |
|---|---|
:nnoremap {lhs} {rhs} |
Global — all buffers |
:nnoremap <buffer> {lhs} {rhs} |
Local — this buffer only |
Buffer-local mappings take priority over global ones with the same key.
Tips
<buffer>works with all map commands:inoremap,vnoremap,cnoremap, etc.:mapclear <buffer>removes all buffer-local mappings for the current buffer- Use
autocmd FileType {type} nnoremap <buffer> ...as an alternative to ftplugin files :verbose nmap <buffer>lists all buffer-local normal mode mappings for the current buffer