Vim Cheatsheet
Plugins and Tooling
Use this Vim reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Plugin Managers
Vim 8 and Neovim both have a built-in package system, so a manager is optional but still the norm.
| Manager | Notes |
|---|---|
| Built-in packages | Drop a repo in ~/.vim/pack/x/start/, no plugin needed |
| vim-plug | Single file, works in Vim and Neovim, the common default |
| lazy.nvim | Neovim only, Lua, lazy loading |
| packer.nvim | Neovim, Lua, largely superseded by lazy.nvim |
# Built-in packages: no manager at all mkdir -p ~/.vim/pack/plugins/start git clone https://github.com/tpope/vim-surround ~/.vim/pack/plugins/start/vim-surround # Optional (load on demand with :packadd name) mkdir -p ~/.vim/pack/plugins/opt
" vim-plug call plug#begin('~/.vim/plugged') Plug 'tpope/vim-surround' Plug 'tpope/vim-commentary' Plug 'tpope/vim-fugitive' Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } Plug 'junegunn/fzf.vim' Plug 'nvim-treesitter/nvim-treesitter', { 'do': ':TSUpdate' } Plug 'preservim/nerdtree', { 'on': 'NERDTreeToggle' } call plug#end()
| vim-plug command | Action |
|---|---|
:PlugInstall | Install anything missing |
:PlugUpdate | Update everything |
:PlugClean | Remove plugins no longer in the config |
:PlugStatus | Show status |
:PlugUpgrade | Update vim-plug itself |
:helptags ALL " rebuild help tags after installing manually :packadd name " load an optional package now
Plugins Worth Knowing
| Plugin | What it adds |
|---|---|
vim-surround | cs"' change surrounding quotes, ds( delete them, ysiw" add them |
vim-commentary | gcc comment a line, gc{motion} comment a range |
vim-repeat | Makes . repeat plugin commands too |
targets.vim | More text objects: arguments, next/last pairs |
vim-fugitive | :Git, :Git blame, :Gvdiffsplit |
vim-gitgutter / gitsigns.nvim | Change markers in the sign column |
fzf.vim / telescope.nvim | Fuzzy find files, buffers, lines, git objects |
nvim-treesitter | Real parse trees: better highlighting and text objects |
nvim-lspconfig / coc.nvim | Language servers: completion, rename, diagnostics |
ale | Async linting and fixing |
vim-airline / lualine.nvim | Status line |
undotree | Visualize the undo tree |
vim-easymotion / leap.nvim | Jump anywhere on screen in a few keys |
vim-surround Idioms
Surround is the plugin most worth muscle memory, because it fills the gap in Vim's grammar around delimiters.
| Keys | Does |
|---|---|
cs"' | Change surrounding " to ' |
cs'<q> | Change ' to <q> tags |
ds" | Delete the surrounding quotes |
dst | Delete the surrounding tag |
ysiw" | Surround the word with quotes |
yss) | Surround the whole line with parens |
yS{motion} | Surround on its own indented lines |
S" in Visual | Surround the selection |
Completion Without Plugins
Vim's built-in completion covers a lot before you reach for an LSP.
| Insert-mode key | Completes from |
|---|---|
Ctrl-n / Ctrl-p | Words in open buffers |
Ctrl-x Ctrl-f | Filenames |
Ctrl-x Ctrl-l | Whole lines |
Ctrl-x Ctrl-o | Omni completion (filetype aware) |
Ctrl-x Ctrl-k | Dictionary words |
Ctrl-x Ctrl-t | Thesaurus |
Ctrl-x Ctrl-i | Included files |
Ctrl-x Ctrl-] | Tags |
Ctrl-x Ctrl-v | Vim command line |
Ctrl-x s | Spelling suggestions |
set completeopt=menuone,noinsert,noselect set omnifunc=syntaxcomplete#Complete set complete-=i " do not scan included files (slow on big projects)
Language Servers
In Neovim, LSP is built in. These are the default keymaps most configs set up, and they replace tags entirely.
| Key | Action |
|---|---|
gd | Go to definition |
gD | Go to declaration |
gr | List references |
gi | Go to implementation |
K | Hover documentation |
<leader>rn | Rename symbol |
<leader>ca | Code action |
[d / ]d | Previous / next diagnostic |
<leader>f | Format the buffer |
In Vim, coc.nvim or ALE provide the same features. Either way the underlying protocol and the language servers (tsserver, pyright, gopls, rust-analyzer, clangd) are the same ones VS Code uses.
Debugging Your Config
:scriptnames " everything sourced, in load order :verbose set option? " which file last set an option :verbose nmap <C-h> " which file defined a mapping :messages " the message history :redir @a | messages | redir END " capture messages into a register vim -u NONE file " no config at all vim -u minimal.vim file " a minimal repro config vim --startuptime log.txt " profile startup :profile start prof.txt :profile func * :profile pause
When a plugin misbehaves, bisect it: start with vim -u NONE, confirm the problem is gone, then add plugins back to a minimal config until it returns. --startuptime is the tool for "why does my editor take 800ms to open".