Vim Plugins packages, managers and 182 plugins worth knowing · 220 entries

A Vim plugin is a directory whose layout Vim recognises, on 'runtimepath' — there is no plugin API, no manifest and no sandbox, and every plugin manager ever written is a program for putting directories on that path and running git. The guide starts there: what plugin/, autoload/, ftplugin/ and after/ mean for load order and startup cost, what Vim 8 packages already do for free (including the six plugins Vim ships switched off), when a manager is actually worth it and which one, how a plugin is put together if you want to read or write one, and the four commands that find the plugin that is misbehaving. Then a defensible eight-plugin starter set instead of a survey. Cards 1–8 are the guide; the rest is a filterable index of 182 plugins grouped by what they do — every repository was resolved against the GitHub API while this page was built, so a row carries the canonical name after any rename, its star count and last push in the tooltip, and a dot when GitHub reports it archived. Press / to jump to the filter box; hover a clipped row for the whole entry.

Dots: Vim and Neovim alike Neovim only archived — unmaintained superseded by something built in plugin manager
Sources: the Vim 9.1 runtime documentation for the package and runtime-path machinery (:h packages, :h runtimepath, :h write-plugin), each manager's own documentation for its commands, and the GitHub GraphQL API for every repository listed — name, stars, licence, last push and archived flag, read while this page was built. Descriptions are editorial. Hover a clipped row for the whole entry.

The Working Guide

How Vim loads a plugin, what a manager actually buys you, how to read one, and how to find the one that is misbehaving

There Is No Plugin API

a directory, and some conventions

A Vim plugin is a directory whose layout Vim recognises, placed somewhere on 'runtimepath'. There is no registry, no manifest, no entry point and no sandbox: the files are sourced, and whatever they do to the editor is done. Every plugin manager in existence is a program for putting directories on 'runtimepath' and running git.

plugin/*.vimsourced once at startup, unconditionally — this is where startup time goesautoload/foo.vimsourced the first time foo#Bar() is called — the native lazy-load mechanismftplugin/{ft}.vimon FileType; must use setlocal and <buffer> mappingsindent/{ft}.vimsets 'indentexpr' for that filetypesyntax/{ft}.vimthe syntax fileftdetect/*.vimat startup; claims file extensionsafter/…the same directories, sourced last — where your overrides belongdoc/*.txthelp, reachable only after :helptagscolors/*.vimcolour schemes; first match on the runtimepath wins

What that means in practice

  • Two plugins can silently fight over a mapping, an option or an autocommand, and nothing warns you. :verbose map {key} and :verbose set {opt}? name the file and line that won.
  • A well-written plugin keeps plugin/ tiny — a few commands and <Plug> mappings — and puts the code in autoload/, so it costs almost nothing until you use it.
  • Load order is 'runtimepath' order, and ~/.vim comes first while ~/.vim/after comes last. That is the entire override mechanism.
The honest question is not "which plugins" but "how few". A hundred plugins is a slow, fragile editor whose failures you cannot attribute. The index half of this sheet lists 182 real, verified repositories precisely so you can choose eight of them.

Native Packages

you may not need a manager

Vim 8 (2016) added packages, and they cover most of what a manager does. A package is a directory under pack/; anything in a start/ directory loads at startup, anything in opt/ loads on :packadd.

~/.vim/pack/plugins/start/vim-surround/ " always loaded " :packadd vimspector ~/.vim/pack/plugins/opt/vimspector/ " install, with no manager at all: cd ~/.vim/pack/plugins/start git clone https://github.com/tpope/vim-surround.git vim -c 'helptags ALL' -c q " or, so your dotfiles repo pins every version: cd ~/.vim git submodule add https://github.com/tpope/vim-surround \ pack/plugins/start/vim-surround git submodule update --remote " update everything

On Windows the same tree is $HOME\vimfiles\pack\plugins\start\. The middle level (plugins here) is a name you choose; people use it to group, e.g. pack/colors/.

Vim already ships several packages, switched off

:packadd matchit% jumps between if/else/endif, not just brackets:packadd cfilter:Cfilter and :Lfilter narrow a quickfix list by pattern:packadd termdebuga gdb front end, in a Vim window:packadd editorconfighonours .editorconfig — shipped since 9.0:packadd commenta commenting plugin, shipped since 9.1:packadd justifytext justification

They live in $VIMRUNTIME/pack/dist/opt/. Two of them — matchit and editorconfig — are plugins people still install from GitHub without noticing they already have them.

Reach for a manager when you want: one command to update everything, lazy loading you did not have to design, a lockfile, or post-install build steps. Do not reach for one merely to install four plugins — git submodule in ~/.vim does that, with pinning, and survives you changing your mind about managers.

Choosing a Manager

four real answers
ManagerReach for it whenCost
nonepack/ + submodulesyou have a handful of plugins and want your dotfiles to pin themyou update by hand; no lazy loading
vim-plugVim, or a config that must work in both editors. Still the default answerone file to vendor; :PlugSnapshot instead of a real lockfile
minpacyou like packages and want only the git part automatedno lazy loading beyond opt/; loads itself on demand, so it is free at startup
lazy.nvimNeovim. Declarative specs, a real lockfile, and per-plugin startup profilingNeovim only, and Lua
dein / packer / Vundle / pathogenyou already have themdein is fast and complex; packer is effectively unmaintained; Vundle and pathogen predate packages

vim-plug, in full

" ~/.vimrc call plug#begin('~/.vim/plugged') Plug 'tpope/vim-surround' Plug 'tpope/vim-repeat' Plug 'tpope/vim-fugitive' " lazy: only when the command is used Plug 'mbbill/undotree', { 'on': 'UndotreeToggle' } " lazy: only for a filetype Plug 'fatih/vim-go', { 'for': 'go', \ 'do': ':GoUpdateBinaries' } " a branch, a tag, a build step Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } Plug 'neoclide/coc.nvim', { 'branch': 'release' } " this also does filetype/syntax on call plug#end()
:PlugInstallclone what is declared and missing:PlugUpdatepull them all; :PlugDiff shows what changed:PlugCleandelete directories no longer declared:PlugStatuswhat is loaded, what is not:PlugSnapshot ~/pins.vimwrite a script that restores today’s commits:PlugUpgradeupdate plug.vim itself

lazy.nvim, for Neovim

-- ~/.config/nvim/init.lua require("lazy").setup({ "tpope/vim-surround", { "lewis6991/gitsigns.nvim", event = "BufReadPre" }, { "nvim-telescope/telescope.nvim", cmd = "Telescope", dependencies = { "nvim-lua/plenary.nvim" } }, { "stevearc/conform.nvim", ft = { "lua", "python" } }, }) -- :Lazy the UI -- :Lazy sync install + update + clean -- :Lazy profile startup cost, per plugin -- lazy-lock.json commit it; :Lazy restore reads it
Do not run two managers at once. pathogen’s bundle/, vim-plug’s plugged/ and a pack/ tree can all be on the runtimepath simultaneously, loading two copies of the same plugin. :scriptnames shows both, and the symptoms are bizarre.

A Starter Set

eight, not eighty

If you want a defensible default rather than a survey, this is it: nothing here changes how Vim behaves in a way you must relearn, and every one of them earns its startup cost.

call plug#begin('~/.vim/plugged') " --- the grammar, extended ------------------------- Plug 'tpope/vim-surround' " cs\"' ds( ysiw] " makes . work with the above Plug 'tpope/vim-repeat' Plug 'tpope/vim-commentary' " gcc, gcap Plug 'tpope/vim-unimpaired' " [q ]q [b ]b yo? " --- the two that pay for themselves --------------- Plug 'tpope/vim-fugitive' " :Git anything Plug 'junegunn/fzf', { 'do': { -> fzf#install() } } Plug 'junegunn/fzf.vim' " :Files :Rg :Buffers " --- quality of life ------------------------------- Plug 'tpope/vim-sleuth' " guess this file's indent Plug 'romainl/vim-cool' " clear search hl on move call plug#end() nnoremap <leader>f :Files<CR> nnoremap <leader>g :Rg<CR> nnoremap <leader>b :Buffers<CR>

What to add next, and why

If you find yourself…Add
wanting diagnostics and completionALE (gentlest), vim-lsp + vim-lsp-settings (pure Vim), or coc.nvim (most capable, largest)
editing arguments and delimited liststargets.vimci, and din(
hunting for a character on the linequick-scope, then vim-sneak if you want more
reaching for git status constantlyvim-gitgutter or vim-signify alongside fugitive
running testsvim-test plus vim-dispatch or asyncrun
losing changes you undidundotree — and turn on 'undofile' first
writing prose or LaTeXgoyo + limelight, or vimtex
The single highest-value install is vim-repeat, and it does nothing by itself. Without it, . does not repeat a surround, a commentary or an exchange — and the plugins feel half-finished for reasons you cannot name.

Anatomy of a Plugin

read one, then write one

The conventions are worth knowing even if you never publish anything, because they are what you read when a plugin misbehaves.

" plugin/hello.vim -- loaded at startup. Keep it small. if exists('g:loaded_hello') || &compatible finish endif let g:loaded_hello = 1 command! -nargs=? -complete=file Hello \ call hello#run(<q-args>) " a <Plug> mapping: unreachable from the keyboard, " so it cannot collide with anything the user has nnoremap <silent> <Plug>(hello-run) \ :<C-u>call hello#run('')<CR> " only provide a default key if the user has not " claimed it, and never noremap to a <Plug> if !hasmapto('<Plug>(hello-run)') \ && empty(maparg('<leader>h')) nmap <leader>h <Plug>(hello-run) endif
" autoload/hello.vim -- sourced on the FIRST call to " hello#run(). This is where the plugin actually lives. function! hello#run(arg) abort let l:target = empty(a:arg) ? expand('%') : a:arg echo 'hello ' . l:target endfunction
ConventionWhy
g:loaded_{name} guardlets a user disable the plugin by setting it in the vimrc — how you turn off netrw
everything in autoload/startup cost is proportional to plugin/, not to the plugin
<Plug>(name-action)a stable entry point that cannot clash; users map to it
hasmapto() + maparg()never steal a key the user already bound
abort on every functionstop at the first error instead of running on in a broken state
<C-u> at the start of a : mappingclears the range a count would otherwise insert
doc/hello.txt + :helptagsa plugin without :h is a plugin nobody configures
ftplugin/ over FileType autocommandsright ordering, and after/ftplugin/ lets the user override you
Vim9script changes the shape but not the layout. A Vim9 plugin still uses plugin/, autoload/ and after/; it just writes def, var and export inside them — and it will not run in Neovim.

Debugging a Plugin Problem

four commands, in order
" 1. is it a plugin at all? " no vimrc, no plugins, real defaults vim --clean file " 2. what got loaded, in what order? :scriptnames " 3. who set this? :verbose set foldmethod? :verbose map <C-p> :verbose autocmd BufWritePre " 4. what is it costing? vim --startuptime /tmp/st file sort -k2 -n -r /tmp/st | head -20

Bisecting

" a throwaway vimrc with just the suspects vim -u NORC -c 'set rtp+=~/.vim/plugged/suspect' file " or comment out half the Plug lines, :PlugClean!, " restart, repeat. Five restarts finds it in 32 plugins.

The failures that look like something else

SymptomUsually
plugin "does nothing"a missing feature: +python3, +job, +clipboard. Check vim --version
. stopped repeating a plugin actionvim-repeat is not installed
a mapping fires lateanother mapping shares its prefix — 'timeoutlen', or add <nowait>
my ftplugin setting is ignoredit needs to be in after/ftplugin/, and use setlocal
help tags missing:helptags ALL was never run — managers do it, manual installs do not
two copies of a plugintwo managers, or a leftover pack/ directory. :scriptnames shows both
startup got slow after an updatea plugin moved code from autoload/ into plugin/, or a syntax file grew. --startuptime
editing is slow, startup is notnot the plugin list: 'foldmethod', a syntax file, or a linter running on every keystroke. :syntime report
A plugin can execute anything. There is no sandbox: plugin/*.vim runs with your privileges, can shell out, and is updated by git pull without review. That is the argument for a small, pinned, read-once plugin list — and for a lockfile or :PlugSnapshot.

Vim and Neovim

one ecosystem, then two

Neovim forked in 2014 and the plugin ecosystems have diverged since roughly 2021, when Lua and the built-in LSP client arrived. Knowing which side a plugin is on saves a lot of time.

Vim 9.1Neovim
script languageslegacy Vimscript, Vim9scriptlegacy Vimscript, Lua
LSPa plugin: vim-lsp, ALE, coc.nvim, YCMbuilt in; nvim-lspconfig is only the configurations
tree-sitternobuilt in, via nvim-treesitter
packagespack/*/start, opt, :packaddthe same, plus lazy.nvim
asyncjobs, channels, timers since Vim 8the same API, plus vim.loop/libuv from Lua
UIterminal and GUI buildsa UI protocol — external GUIs
config file~/.vimrc~/.config/nvim/init.lua (or init.vim)
portableanything in legacy Vimscript: surround, commentary, fugitive, unimpaired, targets, fzf.vim, ALE, vim-test, gitgutter, easy-align, undotreeNeovim onlyanything .nvim or .lua: telescope, treesitter, lspconfig, cmp, LuaSnip, gitsigns, lualine, oil, conform, dap, harpoon, lazyVim onlyanything written in Vim9script, and vimspector’s Vim buildboth, awkwardlycoc.nvim runs in both but brings Node; deoplete and defx need +python3
31 of the 182 plugins indexed here are Neovim-only, and they are the ones doing the newest work. If you are starting from nothing today and have no reason to prefer Vim, that is the honest argument for Neovim. If you already have a Vim config that works, none of it obliges you to move — and vim --clean will still be on every server you ssh into.

Traps

the ones that cost an evening
vim-polyglot shadows the language plugin you installed on purpose. It bundles a hundred language packs and loads them lazily; when its Go or JSX syntax is older than the standalone one you added, the standalone one loses. Disable per language with let g:polyglot_disabled = ['go', 'jsx'] before it loads.
An archived repository still installs and still works — until it does not. Five plugins in the index here are archived on GitHub: syntastic, indentLine, vim-solarized8, vim-gina and vim-argwrap. They will not be fixed when Vim changes underneath them.
<Plug> mappings need nmap, not nnoremap. The whole point of <Plug> is that it resolves further; nnoremap stops exactly that, and the mapping silently does nothing.
Order matters in the vimrc. let mapleader must come before any <leader> mapping, plugin configuration variables must come before the plugin loads (which for vim-plug means before plug#end()), and :colorscheme after syntax enable.
Manual installs have no help. git clone into pack/ and :h surround says E149 until you run :helptags ALL.
Lazy loading by filetype hides errors. A plugin with {'for': 'go'} that fails to load reports nothing until you open a Go file, which may be days later and looks like a different bug.
Completion plugins and auto-pair plugins fight over <CR> and <Tab>. Both want them, both document a different fix, and the result is a newline that sometimes accepts a completion. Read both READMEs before mapping either key yourself.
A linter running on TextChanged can make typing feel heavy in a large file. Move it to InsertLeave and BufWritePost — ALE’s g:ale_lint_on_text_changed = 'never' is the setting worth knowing.
Pin, and read the diff. :PlugSnapshot, a lazy-lock.json, or git submodules all give you a version you chose. Updating everything at once, without reading :PlugDiff, is how a working config becomes an evening of bisecting.

Plugin & Package Index

The package and runtime-path machinery, the managers’ command sets, and 182 plugins grouped by what they do — every repository resolved against GitHub. Type in the filter box, or press /

Packages & the Runtime Path

23

What Vim does natively, and how to debug it

~/.vim/pack/{any}/start/{plugin}/loaded at startup, no manager needed
~/.vim/pack/{any}/opt/{plugin}/loaded only on :packadd {plugin}
:packadd {name}load one optional package now
:packadd! {name}the same, but skip it when Vim starts with --noplugin
:packloadallload every start/ package; happens automatically after the vimrc
:helptags ALLgenerate help tags for every doc/ in 'runtimepath'
git submodule in ~/.vimversion-controlled plugins with no manager at all
$VIMRUNTIME/pack/dist/opt/packages Vim itself ships
:packadd matchitextends % to language keywords
:packadd cfilter:Cfilter / :Lfilter to narrow a quickfix list
:packadd termdebuga gdb front end inside Vim
plugin/*.vimsourced once at startup, unconditionally
autoload/foo.vimsourced on the first call to foo#Bar()
ftplugin/{ft}.vimper filetype; use setlocal and <buffer> maps
after/ftplugin/{ft}.vimyour overrides, sourced last
ftdetect/*.vimclaim new file extensions
syntax/ · indent/ · colors/ · compiler/ · doc/the rest of the runtime directories
:scriptnamesevery file sourced, in order
vim --startuptime /tmp/stper-file startup timings; the last line is the total
:verbose map <C-p>which plugin defined that mapping
:verbose set foldmethod?which plugin set that option
<Plug>Mappinga plugin’s named entry point, unreachable from the keyboard
g:loaded_{plugin}the conventional guard variable

Plugin Managers

22

The managers

junegunn/vim-plugone file, one :PlugInstall, works in both editors — still the default answer for Vim
k-takata/minpaca thin wrapper over Vim 8 packages; installs into pack/minpac/ and gets out of the way
folke/lazy.nvimthe Neovim standard: declarative specs, lazy loading by event, command or filetype, and a lockfile
wbthomason/packer.nvimthe previous Neovim standard; unmaintained in practice, superseded by lazy.nvim
Shougo/dein.vimfast and configurable, with a cache; the power-user option, and the steepest
VundleVim/Vundle.vimthe plugin manager that made the pattern popular in 2010; nothing new needs it
tpope/vim-pathogenthe original: it only manipulates 'runtimepath'. Vim 8 packages made it unnecessary

Their command sets

Plug 'tpope/vim-surround'vim-plug: declare, between call plug#begin() and plug#end()
Plug 'x/y', {'on': ':Cmd'}vim-plug: lazy by command; 'for' for filetype, 'branch'/'tag'/'do' for the rest
:PlugInstall / :PlugUpdate / :PlugCleanvim-plug: install, update, remove what is no longer declared
:PlugUpgrade / :PlugSnapshotvim-plug: update plug.vim itself; write a script pinning current commits
:PlugStatus / :PlugDiffvim-plug: state, and what changed on the last update
call minpac#add('x/y')minpac: declare; {'type': 'opt'} for an opt/ package
call minpac#update() / #clean()minpac: install or update, and prune
require("lazy").setup(specs)lazy.nvim: the entry point
{ "x/y", event = "VeryLazy" }lazy.nvim: lazy by event, cmd, ft, keys or dependencies
:Lazy / :Lazy sync / :Lazy profilelazy.nvim: the UI, install+update+clean, and startup timings per plugin
lazy-lock.jsonlazy.nvim: the lockfile — commit it
:PluginInstallVundle
call dein#add() / :call dein#update()dein
execute pathogen#infect()pathogen: put every directory in ~/.vim/bundle on the runtimepath
lazy loading, honestlya plugin that is already autoload/-based costs almost nothing to load eagerly

Motions, Objects & Operators

27

Editing verbs and nouns

tpope/vim-surroundthe one everyone installs: cs"', ds(, ysiw] — surroundings as an operator
machakann/vim-sandwichsurround, reconsidered: better text objects and a saner default set of recipes
kylechui/nvim-surroundthe Lua rewrite, for Neovim configs that want no Vimscript
tpope/vim-commentarygcc, gcap. Reads 'commentstring', so it works in any filetype
numToStr/Comment.nvimthe same, in Lua, with tree-sitter-aware commentstring for embedded languages
tomtom/tcomment_vimthe older, more configurable commenter
preservim/nerdcommenterthe other older one, with a lot of options
tpope/vim-repeatmakes . work with plugin operators. Install it or half of tpope’s suite half-works
tpope/vim-unimpairedpaired [/] mappings: [q ]q quickfix, [b ]b buffers, [<Space> blank lines, yo option toggles
wellle/targets.vimtext objects that actually reach: ci, for an argument, din( for the next parens, seeking forward on the line
kana/vim-textobj-userthe framework almost every custom text-object plugin builds on
michaeljsmith/vim-indent-objectai/ii — an indentation level as an object. The Python one
andymass/vim-matchup% that understands if/endif, not just brackets; supersedes matchit
easymotion/vim-easymotionlabel every target on screen and jump by letter. Heavy, and the original of the genre
justinmk/vim-sneakthe light alternative: s{char}{char}, a two-character f that works across lines
unblevable/quick-scopehighlights the character to aim f at — passive, no new keys to learn
tommcdo/vim-exchangecx twice to swap two regions
svermeulen/vim-subversivesubstitute an object with a register: s{motion} pastes over it
inkarkat/vim-ReplaceWithRegistergr{motion} — the smallest possible version of the same idea
svermeulen/vim-easyclipreworks the register model so deletes stop clobbering yanks; opinionated, and it changes muscle memory
AndrewRadev/splitjoin.vimgS / gJ: expand a one-liner into a block and back, per language
AndrewRadev/sideways.vimmove a function argument left or right without breaking the commas
FooSoft/vim-argwrapwrap or unwrap an argument list at the cursor
junegunn/vim-easy-alignalign on a delimiter interactively: gaip=
godlygeek/tabularthe older aligner; :Tabularize /=
mg979/vim-visual-multireal multiple cursors, and the maintained one
terryma/vim-multiple-cursorsthe famous one, and long since abandoned by its author in favour of the above

Files & Navigation

20

Finders, trees and jumps

junegunn/fzfthe fuzzy finder itself — a Go binary, not a Vim plugin. Installed as a dependency
junegunn/fzf.vimthe Vim commands on top: :Files :Rg :Buffers :Lines :Commits :Helptags
nvim-telescope/telescope.nvimthe Neovim picker: extensible, previewing, and the centre of most modern configs
nvim-lua/plenary.nvimthe Lua standard library half the Neovim ecosystem depends on. You will install it as a dependency
ctrlpvim/ctrlp.vimpure Vimscript fuzzy finder — no external binary, and slow on very large trees
Yggdroot/LeaderFa faster pure-Vim finder with an optional C extension
preservim/nerdtreethe file tree everyone knows
tpope/vim-vinegarthe counter-argument: fixes netrw instead, and - opens the current file’s directory
justinmk/vim-dirvisha directory is just a buffer of paths — edit it with ordinary Vim commands
lambdalisue/vim-fernan asynchronous tree that works in both editors
Shougo/defx.nvimShougo’s file explorer; needs +python3
nvim-tree/nvim-tree.luathe Lua tree for Neovim
stevearc/oil.nvimdirvish’s idea done properly: edit the filesystem as a buffer, including renames and deletes
ThePrimeagen/harpoonpin four files and jump between them by number. Small idea, disproportionate effect
mhinz/vim-startifya start screen with recent files and sessions
preservim/tagbara ctags outline in a sidebar
ludovicchabant/vim-gutentagsregenerates the tags file in the background so CTRL-] is never stale
junegunn/vim-peekabooshows the register contents when you press " or @
ryanoasis/vim-deviconsfiletype glyphs, if you have a patched font
nvim-tree/nvim-web-deviconsthe same for Neovim, and a dependency of most Lua UI plugins

Git

9

Version control inside the editor

tpope/vim-fugitivethe reason people stay in Vim: :Git anything, a real status buffer, :Gdiffsplit three-way merges, :Gblame you can jump from
tpope/vim-rhubarbadds GitHub to fugitive — :GBrowse, and issue completion in commit messages
junegunn/gv.vima commit browser built on fugitive; :GV for the log, :GV! for this file
airblade/vim-gitgutterchange signs in the gutter, plus stage and undo per hunk
mhinz/vim-signifythe same idea for any VCS, and faster on large repositories
lewis6991/gitsigns.nvimthe Neovim one: signs, hunk staging, inline blame, all asynchronous
rhysd/git-messenger.vima popup with the commit that touched the line under the cursor
lambdalisue/vim-ginaan asynchronous git interface; archived
itchyny/vim-gitbranchone function that returns the branch name, for a statusline

LSP, Completion & Linting

11

Language intelligence

neoclide/coc.nvima Node extension host inside the editor: LSP, completion, and the VS Code extension ecosystem. Powerful, and a large dependency
dense-analysis/aleasynchronous linting and fixing, with an LSP client. The gentlest way into diagnostics for plain Vim
prabirshrestha/vim-lspa pure-Vimscript LSP client, no Node required
mattn/vim-lsp-settingsauto-installs and configures servers for vim-lsp — the piece that makes it painless
prabirshrestha/asyncomplete.vimthe asynchronous completion engine that pairs with vim-lsp
ycm-core/YouCompleteMethe original heavyweight: a compiled server, semantic completion, and a real build step
vim-syntastic/syntasticsynchronous linting from before Vim had jobs. Archived; use ALE
neovim/nvim-lspconfigthe community configurations for Neovim’s built-in LSP client — the client itself is not a plugin
hrsh7th/nvim-cmpthe completion engine most Neovim configs use, with pluggable sources
Shougo/deoplete.nvimthe earlier asynchronous completion framework; needs +python3
davidhalter/jedi-vimPython completion and navigation without LSP

Snippets

4

Engines and content

SirVer/ultisnipsthe Vim snippet engine: tabstops, placeholders, and Python interpolation inside a snippet
honza/vim-snippetsthe community snippet corpus — the content, not an engine
hrsh7th/vim-vsnipa lighter engine that speaks the LSP/VS Code snippet format
L3MON4D3/LuaSnipthe Neovim engine: snippets as Lua data, dynamic nodes, and fast

Editing, Search & Folding

33

The quality-of-life layer

markonm/traces.vimlive preview for :s, :g, :sort and ranges as you type them
osyo-manga/vim-overthe earlier live-substitute preview
haya14busa/incsearch.vimincremental search with all matches highlighted while typing
romainl/vim-cooltwelve lines that clear the search highlight when you move. The best effort-to-value ratio here
romainl/vim-qfmakes the quickfix window behave: filtering, toggling, and better mappings
stefandtw/quickfix-reflector.vimedit the quickfix window and have the edits written to the files
dyng/ctrlsf.vima search-and-edit buffer over ack/ag/ripgrep results
mhinz/vim-grepperone :Grepper command over whichever search tool is installed
mileszs/ack.vimthe classic grep wrapper; configurable to use ripgrep
jremmen/vim-ripgrepa minimal :Rg
rking/ag.vimthe silver-searcher wrapper, superseded by ack.vim itself
mbbill/undotreethe undo tree, visualised — the plugin that makes the tree usable
simnalamburt/vim-mundothe maintained fork of Gundo, same idea, with a diff pane
kshenoy/vim-signatureshows marks in the gutter and gives them navigation keys
chrisbra/NrrwRgnnarrow a region into its own buffer, edit it, write it back
chrisbra/csv.vima genuine CSV mode: column arithmetic, alignment, sorting, headers
will133/vim-dirdiffrecursive directory diff inside Vim
Konfekt/FastFoldstops foldmethod=syntax recomputing on every keystroke — the fix for slow scrolling
tmhedberg/SimpylFoldsane folding for Python
jiangmiao/auto-pairsauto-close brackets and quotes
Raimondi/delimitMatethe other auto-close plugin
windwp/nvim-autopairsthe Neovim one, tree-sitter aware
tpope/vim-endwiseadds end, endif, fi for you in the languages that need them
luochen1990/rainbowrainbow parentheses
Yggdroot/indentLineindent guides; archived
preservim/vim-indent-guidesthe other indent-guide plugin
editorconfig/editorconfig-vimhonours .editorconfig
tpope/vim-sleuthguesses the file’s indentation and sets the options. Zero configuration, and usually right
sbdchd/neoformatrun any external formatter over the buffer
prettier/vim-prettierprettier, specifically
stevearc/conform.nvimthe Neovim formatter runner: per-filetype chains, format-on-save, LSP fallback
907th/vim-auto-savesaves on a timer or on leaving insert mode
psliwka/vim-smoothieanimated scrolling for CTRL-D and friends

Running, Testing & Tooling

20

Build, test, debug and the shell

tpope/vim-dispatchrun :Make and :Dispatch in the background, results into quickfix. Predates Vim 8 jobs and still works
skywind3000/asyncrun.vimthe asynchronous :AsyncRun, with quickfix streaming
skywind3000/asynctasks.vima task-runner layer on asyncrun, configured per project
vim-test/vim-testone set of mappings that runs the nearest test in 40-odd frameworks — :TestNearest, :TestFile, :TestSuite
puremourning/vimspectora full DAP debugger UI for Vim, with a launch-configuration file
mfussenegger/nvim-dapthe DAP client for Neovim
rcarriga/nvim-dap-uithe panes and controls on top of nvim-dap
akinsho/toggleterm.nvimterminal windows you can toggle, float and reuse
preservim/vimuxsend commands to a tmux pane beside Vim
christoomey/vim-tmux-navigatorCTRL-h/j/k/l moves between Vim splits and tmux panes without thinking
edkolev/tmuxline.vimgenerate a tmux statusline from your Vim one
tpope/vim-eunuchthe shell commands you actually wanted: :Rename, :Move, :Delete, :SudoWrite, :Mkdir
tpope/vim-dadboda database client: :DB postgres://… select …
tpope/vim-projectionistdeclare a project’s file layout and get :Emodel, :A for alternate files, and skeletons
tpope/vim-obsessionkeeps a session file up to date without you remembering to :mksession
tpope/vim-apathysets 'path', 'include' and 'suffixesadd' per language, so gf and :find just work
tpope/vim-characterizega that also tells you the Unicode name and HTML entity
tpope/vim-abolishcase-preserving substitute (:S), coercion between snake/camel/kebab (crs crc cr-), and smart abbreviations
tpope/vim-speeddatingCTRL-A on a date increments the date, not the first number in it
tpope/vim-sensiblethe defaults everyone sets. Largely folded into defaults.vim now

Interface & Colour Schemes

20

Statuslines, popups and palettes

vim-airline/vim-airlinethe statusline, in Vimscript, with integrations for everything
vim-airline/vim-airline-themesits theme collection
itchyny/lightline.vimthe same job in a fraction of the code, and it starts faster
nvim-lualine/lualine.nvimthe Lua statusline for Neovim
liuchengxu/vim-which-keya popup showing what the pending key sequence can become
folke/which-key.nvimthe Neovim version, and the more polished one
junegunn/goyo.vimdistraction-free mode: centre the text, hide everything else
junegunn/limelight.vimdims every paragraph but the one you are in. Pairs with goyo
morhetz/gruvboxthe retro warm colour scheme; still the most-installed of them all
altercation/vim-colors-solarizedthe original Solarized
lifepillar/vim-solarized8a true-colour Solarized; archived
joshdick/onedark.vimthe Atom One Dark palette
nordtheme/vimthe arctic blue palette
NLKNguyen/papercolor-themea light scheme that is genuinely readable
dracula/vimDracula
catppuccin/vimCatppuccin, in its Vim port
folke/tokyonight.nvimthe Neovim favourite
rebelot/kanagawa.nvimmuted, ink-wash colours
ayu-theme/ayu-vimthree variants, light through dark
junegunn/seoul256.vimlow-contrast, easy on tired eyes

Languages & Writing

25

Filetype support and prose

vim-polyglot/vim-polyglota hundred-odd language packs in one, loaded lazily. Convenient, and it will shadow anything you install separately
fatih/vim-gothe Go environment: build, test, gopls, coverage, struct tags
rust-lang/rust.vimthe official Rust filetype support and :RustFmt
pangloss/vim-javascriptJavaScript syntax and indentation
leafgarland/typescript-vimTypeScript syntax
MaxMEllon/vim-jsx-prettyJSX and TSX highlighting that survives nesting
mattn/emmet-vimEmmet abbreviations: ul>li*3 then CTRL-Y ,
alvan/vim-closetagcloses HTML and XML tags as you type them
vim-python/python-syntaxa richer Python syntax file
vim-ruby/vim-rubythe official Ruby support
elzr/vim-jsonJSON with concealed quotes and error highlighting
cespare/vim-tomlTOML
stephpy/vim-yamla faster YAML syntax than the shipped one
hashivim/vim-terraformTerraform, plus :TerraformFmt
udalov/kotlin-vimKotlin
keith/swift.vimSwift
octol/vim-cpp-enhanced-highlighthighlights C++ class and template names
rhysd/vim-clang-formatclang-format on a range or on save
lervag/vimtexthe LaTeX environment: compilation, forward search, a document outline, and citation completion
preservim/vim-markdownMarkdown syntax, folding and TOC
iamcco/markdown-preview.nvima live browser preview, synchronised with the cursor
vimwiki/vimwikia personal wiki: linked pages, a diary, and export
xolox/vim-notesplain-text notes with automatic titles and search
vim-utils/vim-manread man pages in a Vim buffer, with K
nvim-treesitter/nvim-treesittertree-sitter parsers for Neovim: highlighting, indentation, folds, and the text objects that come with them

AI Assistants

6

Agents and completion, in the editor

github/copilot.vimthe official Copilot plugin; works in Vim 9 and Neovim
zbirenbaum/copilot.luathe Lua rewrite, with completion-engine integration
olimorris/codecompanion.nvima chat and inline-assistant buffer over several providers
avante-corp/avante.nvima Cursor-like sidebar for Neovim, with diffs you accept or reject
coder/claudecode.nvimruns Claude Code inside Neovim over its own protocol
greggh/claude-code.nvima lighter terminal-based Claude Code integration