Home

Awesome

IDIOMATIC VIMRC

Guidelines for sculpting your very own ~/.vimrc.

This document is available in the following languages:

Unlike the many so-called "distributions", "templates" or "awesome vimrc" you can find on the web, this project is NOT meant to provide you with a working config, or help you bootstrap your config with opinionated "defaults", or tell you what to put in your config. Therefore, don't copy it to your $HOME and expect it to do anything.

The purpose of this project is to document battle-tested best practices regarding Vim configuration. Use it as a reference, not as a starting point.

Furthermore, a vimrc is something personal, that grows, shrinks and evolves over time, as you increase your Vim-fu and your needs change. While looking at other people's vimrc can certainly be an interesting exercise, one should refrain from looking for solutions to non-existing problems.

Remember, kids... Pandajail is where pandas are sent when you use someone else's vimrc. Don't be the vimmer responsible for this:

pandajail

TABLE OF CONTENTS

FILES AND DIRECTORIES

Unless you really know what you are doing (hint: if you learn anything from this document, it means that you are not there yet), whatever you do to customize Vim should NEVER happen outside of your "home" directory, hereby referred to as $HOME:

If in doubt, open Vim and ask it:

:echo $HOME

Now that that's out of the way, you must be aware of what Vim calls "runtime files". Vim depends on several of those to work properly, that are located in two "runtime directories": a "system" one and a "user" one. The "system" runtime directory contains all the runtime files that came with Vim and is best left as-is. The "user" runtime directory, located in the aforementioned $HOME, is where most of the customization usually happens, by way of editing your own configuration file, called vimrc, and moving files around your own runtime directory, called vimfiles.

The canonical location for your vimrc file and vimfiles directory is at the root of the $HOME directory mentioned above:

Systemvimrcvimfiles
UNIX-like$HOME/.vimrc$HOME/.vim/
Windows$HOME\_vimrc$HOME\vimfiles\

Note that Vim doesn't create those files and directories on its own: you need to create them yourself.

Since Vim 7.4 it is possible to keep your lovely vimrc INSIDE your vimfiles. It is really a good idea, if only because it makes it easier to move your config from one machine to another.

The following gives you a neat self-contained setup from 7.4 up:

SystemLocation
UNIX-like$HOME/.vim/vimrc
Windows$HOME\vimfiles\vimrc

Here are a few things to keep in mind if you decide to move your vimrc into your vimfiles, though:

For the sake of simplicity and agnosticism, vimrc, vimfiles, and $HOME will be used in the rest of the document, regardless of their actual name and path.

A NOTE ON TUTORIALS

Vim tutorials, including this one, and plugin instructions are often written from a "Unix" perspective, which has been causing confusion among Windows users since forever. If you are on Windows trying to follow Unix-centric instructions, keep in mind the rules below:

MISCELLANEOUS ADVICE

DEFAULTS.VIM

Vim's spartan defaults having been a contentious topic for a very long time, it has been decided between the releases of Vim 7.4 and Vim 8.0 to provide newcomers with a more user-friendly base setup. The scheme that was devised is to silently source a specific runtime file, defaults.vim if no vimrc is found at the usual locations (see above). And indeed, it works as intended: simply starting Vim without a custom config truly provides a slightly more comfortable experience than previously.

One of the many troubles with that scheme is that embarking on the life-long journey of mastering Vim implies creating one's own vimrc, which effectively disables defaults.vim. This puts the new user in an even worse position than before: with the spartan defaults everyone likes to hate and no idea whatsoever about how to get back the admittedly useful things they got used to because defaults.vim is pretty much a black box. Good job!

In case you happen to struggle with that particular problem, two quick and dirty solutions are offered under :help defaults.vim. The first is to source that file in your vimrc:

unlet! skip_defaults_vim
source $VIMRUNTIME/defaults.vim

The second one is to copy its content in your vimrc, which you can do like this:

:0read $VIMRUNTIME/defaults.vim

See :help :source and :help :read.

NOTE: the author doesn't find any of those solutions particularly satisfying and recommends instead to try to understand what that file does and, eventually, to copy the most useful bits over to one's vimrc.

OPTIONS

There are three kinds of options:

Checking the value of an option:

Getting help for an option:

:help 'optionname'
:help 'optionname
:help optionname'

Setting boolean options (booloption is not a real option):

set booloption      " Set booloption.
set nobooloption    " Unset booloption.

set booloption!     " Toggle booloption.

set booloption&     " Reset booloption to its default value.

Setting string options (stroption is not a real option):

set stroption=baz   " baz

set stroption+=buzz " baz,buzz
set stroption^=fizz " fizz,baz,buzz
set stroption-=baz  " fizz,buzz

set stroption=      " Unset stroption.

set stroption&      " Reset stroption to its default value.

Setting number options (numoption is not a real option):

set numoption=1     " 1

set numoption+=2    " 1 + 2 = 3
set numoption-=1    " 3 - 1 = 2
set numoption^=8    " 2 * 8 = 16

set numoption&      " Reset numoption to its default value.

MAPPINGS

Use non-recursive mappings if you intend to ONLY use default commands in your mappings, which is almost always what you want:

nnoremap <key> yyp

Use recursive mappings ONLY if you intend to use other mappings in your mappings:

nnoremap b     B
nmap     <key> db

Executing a command from a mapping:

nnoremap <key> :MyCommand<CR>

Executing multiple commands from a mapping:

nnoremap <key> :MyCommand <bar> MyOtherCommand <bar> SomeCommand<CR>

Calling a function from a mapping:

nnoremap <key> :call SomeFunction()<CR>

NOTE: since 8.2.1978, the recommended way to call Ex commands from a mapping is with :help <Cmd>:

nnoremap <key> <Cmd>MyCommand<CR>
nnoremap <key> <Cmd>MyCommand <bar> MyOtherCommand <bar> SomeCommand<CR>
nnoremap <key> <Cmd>call SomeFunction()<CR>

The right-hand-side of a mapping is a macro, a series of keystrokes, everything there is typed for you so be careful with spaces and such. For example, the two mappings below don't do the same thing at all:

nnoremap <key> w i foo <Esc>
nnoremap <key> wifoo<Esc>

VARIABLES

Like most scripting languages, vimscript has variables.

One can define a variable with:help :let:

let variable = value

Inspect its value with :help :echo:

echo variable

And delete it with :help :unlet:

unlet variable

Variables can be scoped by prepending a single letter and a colon to their name. Plugin authors use that feature to mimic options:

let g:plugin_variable = 1

or to keep variables "private":

let s:script_variable = 'foo'

Read up on the subject in :help internal-variables.

CUSTOM COMMANDS

Examples:

command! MyCommand call SomeFunction()
command! MyOtherCommand command | Command | command

CUSTOM FUNCTIONS

Example:

function! MyFunction(foo, bar) abort
  return a:foo . a:bar
endfunction

AUTOCOMMANDS

Example:

augroup MyGroup
  " Clear the autocommands of the current group to prevent them from piling
  " up each time you reload your vimrc.
  autocmd!

  " This autocmd calls the fictitious `MyFunction()` everytime Vim tries to
  " create/edit a buffer tied to a file in /`path/to/project/**/`.
  autocmd BufNew,BufEnter /path/to/project/**/* call MyFunction()
augroup END

Alternative strategy:

" Put an empty, self-clearing group somewhere near the top of your vimrc
augroup MyGroup
  autocmd!
augroup END

" Add autocommands to that group from anywhere
autocmd MyGroup BufNew,BufEnter /path/to/project/**/* call MyFunction()

CONDITIONALS

Do something if Vim is the right version:

if v:version >= 704
  " see :help v:version
endif

Do something if Vim has the right patch-level:

if has('patch666')
  " see :help has-patch
endif

Do something if Vim is built with feature:

if has('feature')
  " see :help feature-list
endif

Do something on Wednesdays:

if strftime("%u") == 3
  " see :help time-functions
endif

COLORS

The standard location for a standalone colorscheme is:

$HOME/.vim/colors/foobar.vim

You can make it the current one with:

:colorscheme foobar

And persist that choice by adding this line to your vimrc:

colorscheme foobar

NOTE: most colorschemes these days are provided as "plugins". Read on to see how these work.

PLUGINS

Vim does a lot but we can count on its thriving plugin ecosystem for when the built-in features are not enough. Look for plugins that:

Vim plugins are to be installed in your vimfiles directory and NOWHERE else.

Properly designed plugins usually follow Vim's own runtime directory's structure:

Historically, the normal method for installing plugins was to put each file in its corresponding directory under one's vimfiles, as above. It was messy and the more plugins you added the messier your vimfiles would get.

To solve that problem, a number of what people call "plugin managers" appeared, all more or less built around the same logic: each plugin is kept in its own directory under a common parent directory and Vim is told where to find those plugins via :help 'runtimepath'.

Note that using a plugin manager is not an absolute requirement. After all, the traditional way was messy but workable, but if you think you need one, make sure you read and understand its README.md before using it.

Vim 8's "package" feature

Vim 8 introduced a new scheme called package that lets you organise your plugins in so-called "packages" and decide whether they are to be enabled at startup or manually:

DirectoryDescription
pack/{arbitrary name}/start/Plugins in this directory are enabled automatically at startup
pack/{arbitrary name}/opt/Plugins in this directory are enabled manually

For example, here is the author's setup:

While that feature is a clear improvement, it is still not an actual plugin manager and you may still have to use one if you need one.

See :help package.

SUGGESTED MINIMAL SETTINGS FOR PROGRAMMING

How you customise your tools is entirely dependant on a) what you use them for and b) how well you know them, so YMMV. In that spirit, the settings below are only suggestions, based on what the author would do if he had to work on a new machine for a couple of hours and didn't feel like installing his full config.

" Enabling filetype support provides filetype-specific indenting,
" syntax highlighting, omni-completion and other useful settings.
filetype plugin indent on
syntax on

" `matchit.vim` is built-in so let's enable it!
" Hit `%` on `if` to jump to `else`.
runtime macros/matchit.vim

" various settings
set autoindent                 " Minimal automatic indenting for any filetype.
set backspace=indent,eol,start " Intuitive backspace behavior.
set hidden                     " Possibility to have more than one unsaved buffers.
set incsearch                  " Incremental search, hit `<CR>` to stop.
set ruler                      " Shows the current line number at the bottom-right
                               " of the screen.
set wildmenu                   " Great command-line completion, use `<Tab>` to move
                               " around and `<CR>` to validate.