Want to see the full-length video right now for free?
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.
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!
Vim provides a special variable, $MYVIMRC
that points to your vimrc file
and allows for quick editing with:
:e $MYVIMRC<cr>
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>".
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:
nmap
is a normal mode
map, imap
for insert, etc." 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>
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.
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>"
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.
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>
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 imap
s (insert mode mappings), they will not affect
any other mode. Typing jk
in normal mode will still perform the expected
navigation.
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.
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.
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
<cr>
while on the word set
to toggle a
specific option value.<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 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.
" 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 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.
Don't be afraid to borrow from others' dotfiles. Here are a few samples to get you started:
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