Here are the current Neovim mappings I came to feel comfortable with over time. This is by no means a reference card, and yes I do use the arrow keys for navigating into my buffers. It depends on motion range, though. Another key idea is that I use Tmux everyday and I like to have an unified set of mappings, beside the leader/prefix key. See my blog posts for how I started to use Vim and Neovim.
Note that I only have a dozen of plugins in my start
and opt
directories, in addition to part of mini.nvim that I adapted to suit my needs better: (This may change in the future but usually I tend to remove plugins rather than add new ones.1 )
nvim-treesitter
, nvim-treesitter-textobjects
, Comment.nvim
, nvim-lspconfig
, null-ls.nvim
, plenary
(dep), neogen
, nvim-parinfer
, nvim-lightbulb
, vimtex
, nvim-colorizer
gitsigns.nvim
;packer.nvim
, fzf-lua
I prefer a minimalist setup these days, and I tend to rely on hand-on solutions for tasks I carry over and over. Many of those custom settings come from briliant Vimers who are acknowledged in my config files. Note that some of those mappings may override existing ones, whether they are somewhat redundant (e.g. s and c) or because I don’t use them at all (e.g., some of the Ctrl, g or z combinations).
My leader is “,”2 and I do not define specific mappings for the localleader in my main config files. It looks like I always misunderstood the role of the localleader, and I decided to book it for my after/ftplugin
custom settings.
Mapping | Mode | Command | Role |
<C-a> | c | :<Home> | Go to start of line |
<C-e> | c | :<End> | Go to end of line |
- | n | :Ex | Show explorer |
,. | n | :lcd %:p:h | Set local current directory |
<Backspace> | n | :bp <Bar> bd! # | Kill current buffer |
<C-x> | n | Only() | Keep only current buffer (custom) |
,e | n | :e <C-R>=expand("%:p:h") . "/" | Open file from current directory |
<Tab> | n | tabpagenr('$') ==? 1 ? " | Go to alternate buffer or to next tab |
,<Tab> | n | :$tabnew | New tab |
,<S-Tab> | n | winnr('$') ==? 2 ? " | Move split to new tab or go to previous tab |
J | n | mzJ`z | Join lines (cursor stationary) |
<C-q> | n | quickfix_toggle() | Close quickfix window (custom) |
[Q | n | :cfirst | Go to first quickfix item |
]Q | n | :clast | Go to last quickfix item |
W!! | c | :w !sudo tee % >/dev/null<Cr>:e!<Cr> | Save as root |
<C-s> | i | <C-g>u<Esc>[s1z=`]a<C-g>u | Fix last spelling error (repeat.) |
,S | n | vip:sort iu | Sort in reverse lexicographic order |
,S | v | :sort u | Sort in reverse lexicographic order |
,s | n | vip:sort u | Sort in lexicographic order |
,s | v | :sort u | Sort in lexicographic order |
N | n | Nzz | Keep cursor centered on screen when looking behind |
n | n | nzz | Keep cursor centered on screen when looking ahead |
U | n | <C-r> | Redo |
zs | n | 1z= | Fix spelling using first suggestion |
,df | n | :setlocal spell!<bar>setlocal spell?<cr>:setlocal spelllang=fr<cr> | Toggle spelling on/off (French) |
,de | n | :setlocal spell!<bar>setlocal spell?<cr>:setlocal spelllang=en<cr> | Toggle spelling on/off (English) |
,p | n | :set invpaste<Cr>:set paste?<Cr> | Toggle on/off paste mode |
<C-p> | n | :FzfLua files | Fuzzy finder for files |
<C-s> | n | :RgCw | Fzf Rg on current word or project |
,, | n | :FzfLua buffers | Fuzzy finder for buffers |
,gg | n | :FzfLua git_status | Git status |
,gb | n | :FzfLua git_bcommits | Git buffer commit log |
,gc | n | :FzfLua git_commits | Git commit log |
,r | n | :FzfLua oldfiles | Old files |
,ww | n | vim.diagnostic.setqflist | Show diagnostics in quickfix (LSP) |
g= | n | vim.lsp.buf.format | Format selection (LSP) |
z= | n,x | vim.lsp.buf.code_action | Code action (LSP) |
z! | n,x | vim.lsp.codelens.run | Code lens (LSP) |
gO | n | vim.lsp.buf.document_symbol() | Show workspace or buffer symbols depending on filetype (LSP) |
K | n | vim.lsp.buf.hover | Show help for current symbol (LSP) |
<C-h> | i | vim.lsp.buf.signature_help | Show signature help (LSP) |
gd | n | vim.lsp.buf.definition | Show definition (LSP) |
gr | n | vim.lsp.buf.references | Show references (LSP) |
gi | n | vim.lsp.buf.implementation | Show references (LSP) |
zr | n | vim.lsp.buf.rename | Rename symbol (LSP) |
I also have kind of an universal mapping, gs, which depending on filetype may compile a $\LaTeX$ document or a C file and show its output, run a Python/Haskell/Lisp/Scheme script and show its output, etc. It is defined in relevant after/ftplugin/*.vim
files. Finally, since I never found a good or reliable plugin to send command to a terminal, and I’ve tried many of the exiting ones for Vim or Neovim, I wrote my own commands: (It assumes that you have a terminal opened next to your buffer in a split, which is how I work in any case.)
" poor man send-to-repl features (we need to fire a REPL in a split first)
noremap ss Vy<C-w>wpa<CR><C-\><C-n><C-w>pj
noremap s y<C-w>wpa<CR><C-\><C-n><C-w>p
xnoremap s y<C-w>wpa<CR><C-\><C-n><C-w>p
When I first drafted this cheatsheet, I was still using 15 plugins or so. Some packages broke at some point and I was too lazy to investigate why, or some were of too little use to justify keeping them. I don’t really miss anything with my current config, though. ↩︎
I recently switched to this leader key after having spent three years using the Space key as my leader, as a leftover of my Doom Emacs period. ↩︎