The most surprising thing about building a perfect Vim setup is that it’s less about finding the "best" plugins and more about understanding your own workflow and how Vim’s built-in features can be leveraged.

Let’s see Vim in action, not with a complex application, but with a simple text file and a few common modifications. Imagine you’re editing a Python file.

syntax enable
filetype plugin indent on
set number
set relativenumber
set tabstop=4
set shiftwidth=4
set expandtab

When you open a Python file with these settings, syntax enable highlights keywords, strings, and comments in different colors, making the code much more readable. filetype plugin indent on loads filetype-specific settings, including intelligent indentation for Python, so pressing Enter automatically indents your new line correctly. set number displays line numbers on the left, while set relativenumber shows the current line number absolutely and all other lines relatively, allowing you to quickly jump to lines using commands like 5j (move down 5 lines) or 10k (move up 10 lines). set tabstop=4 and set shiftwidth=4 define that a tab character takes up 4 spaces and that indentation levels should be 4 spaces wide, respectively. set expandtab ensures that when you press the Tab key, Vim inserts spaces instead of a literal tab character, enforcing consistent indentation across different editors and environments.

The problem your .vimrc configuration solves is the inherent verbosity and lack of immediate usability of Vim out of the box. By default, Vim is a powerful, modal editor, but it’s not opinionated about how you should work. Your .vimrc is where you inject your preferences, automate repetitive tasks, and integrate external tools. It’s a personal operating system for text manipulation.

Internally, Vim reads this .vimrc file on startup. Each command is an instruction to Vim’s internal state machine. set number toggles an internal option. map commands create new keybindings by telling Vim to intercept a key sequence and execute a different command. Plugin managers like vim-plug or Vundle use Vimscript to download, install, and load additional functionality, often by sourcing separate plugin files into Vim’s runtime path.

The exact levers you control are numerous. You can remap keys to perform complex actions with a single keystroke. For example, nnoremap <leader>w :w<CR> maps your leader key (often \) followed by w to save the file, making saving faster and more accessible. You can configure search behavior with set incsearch (show matches as you type) and set hlsearch (highlight all matches). You can customize the appearance with colorschemes (colorscheme desert) and status line settings. You can even write custom functions in Vimscript to automate intricate editing tasks.

Many users struggle with managing their plugins effectively. Instead of just listing plugins, consider how they interact. For instance, if you use a fuzzy finder like fzf.vim and a completion engine like coc.nvim, you might find that coc.nvim’s completion popup interferes with fzf.vim’s results. The solution isn’t just installing both, but understanding their configuration options. You might need to add specific mappings or settings to tell coc.nvim to temporarily disable its popup when fzf.vim is active, perhaps by adding something like this to your .vimrc after the plugins are loaded:

" Prevent coc.nvim from interfering with fzf.vim
autocmd User CocPopupClosed call fzf#vim#complete({})

This tells Vim that when the CocPopupClosed event fires (meaning coc.nvim’s completion popup has closed), it should then execute a command to potentially trigger fzf.vim’s completion. This kind of inter-plugin coordination is where the real power lies, and it often requires digging into plugin documentation and understanding Vim’s event system.

The next concept you’ll likely explore is advanced Vimscript for creating custom commands and functions that go beyond simple remappings.

Want structured learning?

Take the full Vim course →