Video

Want to see the full-length video right now for free?

Notes

Configuration

Nearly everything in Vim can be configured and customized to match your preferences. Now that you have an understanding of core Vim and the power it has, we can dive into discussing how to go about configuring it to match your preferences and workflows.

Vimrc Configuration File

Vim reads in configuration from a specific file, ~/.vimrc, on startup. This file must be be located and named as such, but thankfully we don't have to let this limit us.

Our recommendation is to store the actual file in a git repository somewhere else on your system, and then use a "symlink" (symbolic link) to simulate the file living in your home directory.

Assuming you have a file you want to use as your vimrc in a git repo on your system (we're using ~/code/dotfiles/vimrc for our example, but yours can be anywhere).

# Move to your home directory (~ means home dir)
$ cd ~

# Create the symlink to the existing vimrc file
$ ln -s ~/code/dotfiles/vim/vimrc ~/.vimrc

This lets you can track changes to your vimrc over time using git, and replicate those changes across machines, but without having to store your entire home directory in a repo!

Editing the Vimrc

Vim provides a special variable, $MYVIMRC that points to your vimrc file and allows for quick editing with:

:e $MYVIMRC<cr>

Testing out Configurations

All configurations in Vim use the identical syntax when run either at the Vim command line or read in from the vimrc config file. This means that it is very easy to test out configuration commands before committing them to your vimrc. This means that running the command:

:nmap 0 ^<cr>

is identical to having the following line in your vimrc.

nmap 0 ^

Note The <cr> above is how Vim refers to the return key, so when typing you would hit return, not literally type "<cr>".

Custom Key Mappings

Vim allows you to map any key sequence you'd like. Each mapping is scoped to a mode, e.g. normal mode or insert mode. All mappings follow the same structure:

  1. Map command - the command specifying the mode. nmap is a normal mode map, imap for insert, etc.
  2. lhs (left hand side) - These are the key or keys you type to cause the mapping to trigger.
  3. rhs (right hand side) - The key sequence Vim will fire after the mapping is triggered. Vim runs exactly as if you've typed those keys directly.
" map-cmd   lhs   rhs
nmap        0     $

You can use mappings to trigger Vim commands like :w[rite]<cr> by prefixing the rhs with :, and ending with <cr> to represent hitting return. Note, this is exactly what you would type to run the command directly. For example:

" Map Ctrl-s to write the file
nmap <C-s> :w<cr>

Leader Mappings

Since Vim makes such terrific use of the available keys in normal mode, there is unfortunately not much left for us to work with. Luckily, Vim has a feature known as the "leader key" which is intended to be used to prefix all your custom commands, essentially providing a safe namespace for your custom mappings.

Configuring the Leader Key

By default the leader is mapped to \, but this is not ideal since the \ key is a bit of a stretch for your poor pinky. Instead, we can use the following to set the leader to the space bar, a sizeable and easy-to-reach target:

" Use the space key as our leader. Put this near the top of your vimrc
let mapleader = "\<Space>"

Defining Leader Mappings

When using the leader to prefix our mappings, use the literal string <leader> to prefix the left hand side of the map:

" Split edit your vimrc. Type space, v, r in sequence to trigger
nmap <leader>vr :sp $MYVIMRC<cr>

" Source (reload) your vimrc. Type space, s, o in sequence to trigger
nmap <leader>so :source $MYVIMRC<cr>

For each of these mappings <leader> will be replaced by whatever mapleader is currently set to. Again, by default this is \, but since we've configured space as our mapleader, our mappings will be configured with space.

Rapid Editing of Your Vimrc

The mappings below provide the ability to rapidly tweak and reload your vimrc configuration without having to leave your editor. We recommend adding these to your vimrc, and using them to regularly add new leader mappings, try out settings, etc, all on the fly.

nmap <leader>vr :sp $MYVIMRC<cr>
nmap <leader>so :source $MYVIMRC<cr>

Mapping in Other Modes

As discussed above, Vim allows you to map key sequences in any of the modes, not just normal mode. As an example, the following creates mappings to escape from insert mode:

imap jk <esc>
imap kj <esc>

With this in place, type j then k (or k then j) and Vim will instead treat it as if you typed <esc> and will exit insert mode.

Similarly, the following mapping both exits insert mode and saves the buffer:

imap <C-s> <esc>:w<cr>

Note Since these are imaps (insert mode mappings), they will not affect any other mode. Typing jk in normal mode will still perform the expected navigation.

Special Keys in Mappings

Most keys can be entered literally in mappings, e.g. j will be treated as if you pressed the j key. Some keys and key sequences are special and need to be entered using a specific sequence to work as expected in a mapping. The following is a partial list of special keys and characters:

Sequence Meaning
<leader> Will be replaced with your leader key, e.g. \ or space
<esc> Treated as pressing the escape key
<cr> Treated as pressing the return key
<C-k> Control and k (k can be any character here)
K Upercase k. Note no need to specify shift key
<F6> Function key 6. (Similar for all fn keys)

See :h :map-special-keys and :h :map-special-chars for a complete listing.

Setting Options

Vim has an extensive collection of options which you can configure using the set command. One example would be instructing Vim to display line numbers. You can do this by running the command :set number at the command line, or by adding the following to your vimrc:

set number

Here is a small sample of some options to give you an idea of what is available.

set number                      " Display line numbers beside buffer
set nocompatible                " Don't maintain compatibilty with Vi.
set hidden                      " Allow buffer change w/o saving
set lazyredraw                  " Don't update while executing macros
set backspace=indent,eol,start  " Sane backspace behavior
set history=1000                " Remember last 1000 commands
set scrolloff=4                 " Keep at least 4 lines below cursor

There are hundreds of options that you can set, so we recommend against trying to tweak too many at once. Instead, look them up as you hit pain points or borrow from other's configurations and try one or two at a time.

Browsing Options

Vim has a somewhat-staggering list of options so you likely don't need to know all or even most of them, but if you do want to get an overview, you can run :browse set<cr> to see a list of all the options, grouped by type.

While in this option window you can navigate to the help for a specific option by pressing <C-]> with your cursor on the setting name

  • Toggle the setting - Press <cr> while on the word set to toggle a specific option value.
  • View the Help - You can navigate to the help entry for a given option by pressing <C-]> while on the option.

Note - This is not the common place you will interact with or learn about Vim's options, but does provide a good introduction.

Autocommands

Autocommands allow you to hook into Vim's event system. This lets you run any command based on events that Vim triggers. As an example:

" Bind `q` to close the buffer for help files
autocmd Filetype help nnoremap <buffer> q :q<CR>

The above configuration will map q to quit whenever you open a help file in Vim. (Note, <buffer> is a special mapping argument that instructs Vim to only register the mapping for the current buffer).

In addition to the Filetype event we've seen, Vim provides an array of other events that you can tap into:

Event Trigger
BufRead Starting to edit a new buffer
BufWrite starting to write the whole buffer to a file
BufEnter after entering a buffer
VimEnter after doing all the startup stuff

The above is a subset, see :h autocmd-events for the full list.

Sample Configurations

" Pre-populate a split command with the current directory
nmap <leader>v :vnew <C-r>=escape(expand("%:p:h"), ' ') . '/'<cr>

" Edit your vimrc in a new tab
nmap <leader>vi :tabedit ~/.vimrc<cr>

" Copy the entire buffer into the system register
nmap <leader>co ggVG*y

" Edit the db/schema.rb Rails file in a split
nmap <leader>sc :split db/schema.rb<cr>

" Move up and down by visible lines if current line is wrapped
nmap j gj
nmap k gk

" Command aliases for typoed commands (accidentally holding shift too long)
command! Q q " Bind :Q to :q
command! Qall qall
command! QA qall
command! E e

Custom Commands

Custom commands are defined by providing a name for the command and then another command to run when the new command is triggered. For example:

command! Q q

The above creates a command Q that can be run with the sequence :Q<cr> in normal mode.

Custom commands are useful for paving over rough edges (holding down shift for too long when trying to quit), or combining multiple steps into a single command.

Building Your Dotfiles

Don't be afraid to borrow from others' dotfiles. Here are a few samples to get you started:

  • [Ben's dotfiles][]
  • [Chris's dotfiles][]
  • [thoughtbot's shared dotfiles][] - A much more reserved set that acts as a great foundation for deeper configuration

Building up your dotfiles should be a slow process, and will likely be ongoing for as long as you use Vim and similar tools. As such, don't worry about building the perfect configuration, but instead try to improve your configuration a little each week.

Pay attention to the commands and key sequences you use regularly and consider creating a leader mapping or a custom command. Time spent smoothing out those rough edges and optimizing your workflow will be time well spent.

[Ben's dotfiles]: https://github.com/r00k/dotfiles [Chris's dotfiles]: https://github.com/christoomey/dotfiles [thoughtbot's shared dotfiles]: https://github.com/thoughtbot/dotfiles