Awesome Vim Configuration

Posted Jan 5, 2013 by John S.

As developers and engineers, we should always be striving to increase our productivity by clearing away the clutter and focusing on the problem at hand. One aspect that we don't focus on enough is having our editors and IDEs finely tuned for how we like to do our job, and learning all the shortcuts that our editors have to offer. Dave Thomas and Andy Hunt call out this problem in The Pragmatic Programmer, along with a call to action to learn to "use a single editor well."

This didn't hit home until I saw Stuart Halloway from Relevance create and manipulate code in IntelliJ during a test-driven development class. He was incredibly efficient with his editor, and it was mind-boggling to see just how fast someone could move when they are that proficient. At the time, SlickEdit was the editor used around the office the most, and it was good. It shined most when exploring code. It's built-in tagging engine is simply superb, and made it quick to get a code base tagged and start exploring it very quickly. I used it for quite some time before finally realizing that it just wasn't getting the job done when it came to editing. As time went on, it also grew features that stood in my way and became increasingly difficult to disable. Also, it just cannot keep up with the plethora of languages out there. It had no Clojure support, and its Python support was abysmal.

So, I made a choice. I used Vim quite a bit for remote work and it's my default editor when creating commit messages and other small tasks. I had tried using Vim as my primary editor in the past, and failed miserably. It was too hard to configure. Tagging was only so-so. Fortunately, I was lucky enough to work with someone, Dr. Mike Henry, who has made it his goal to become a Vim guru. He has put together a great Vim configuration and I coaxed him into placing it up on GitHub.

I've been using this configuration for over a year and a half now, and while I've only scratched the surface of what's packed in the configuration, I'm much more productive with Vim than I've ever been in the past. For the rest of this post, I want to quickly go over how to get up and running with this configuration, and show you some of the more compelling features/plugins. Sometimes, seeing is better than believing, so I made a screencast to show some plugins in action. You'll find it at the bottom of the post.

Getting Started

If you want to be able to easily keep sync with the configuration, you'll want to install Git. If you've not used Git before, GitHub has some documentation to get you jump-started. If you're looking to just try things out, you can also just download a tarball version of the configuration. I'll show how to do that below. Also, the directions I'm giving are geared towards Linux users. A similar story exists for Windows users; it's documented in README.txt.

You'll also want to double-check and make sure your installed version of Vim supports Python:

$ vim --version | grep python
+postscript +printer +profile +python -python3 +quickfix +reltime +rightleft

Most Linux distributions are shipping a Vim with Python support today. If yours does not, you will need to build a new Vim to take full advantage of this configuration. There are notes for how to do this on Fedora and Ubuntu, and a buildtool script to help make the process easier.

Next, you'll want to move any old configuration out of the way:

$ cd ~
$ mv .vimrc .vimrc.old
$ mv .vim .vim.old

Now that we've got a good version of Vim, and the old configuration is out of the way, let's get started.

First, clone Dr. Mike's vimfiles repository into ~/.vim:

This will tell Git to copy Dr. Mike's vimfiles repo into the .vim folder. If you'd rather use a tarball, you can do the following instead1:

$ curl -L -k https://github.com/drmikehenry/vimfiles/archive/master.tar.gz \
  | tar zxvf -
$ mv vimfiles-master .vim

Alternatively, you can visit the vimfiles repository, and click Zip, and it will download a zip file for you. You can unpack it, and move it into place with:

$ unzip ~/Downloads/vimfiles-master.zip
$ mv vimfiles-master .vim

Next, you'll need to run Dr. Mike's setup script:

$ cd ~/.vim
$ python setup.py

This will setup a very bare-bones ~/.vimrc, which will delegate most of the configuration to the files in ~/.vim.

At this point, the environment is setup and you're ready to start using it.

Fuzzy Matching

Two plugins were very much inspired by TextMate's fuzzy-matching algorithm. TextMate is a Mac OS X editor and it has a shortcut, Command-T, for the fuzzy file matching dialog. In this dialog, you start typing characters of the filename and TextMate will show you a list that shrinks down to the file you want. It's a real time saver when you start out because you don't have to know the entire hierarchy of the project to find the file you're looking for. And once you do learn the hierarchy, you know just what to type to narrow down your selection without spending time navigating the depths of your project. Either way, it's a win, and it's a feature you'll use quite frequently.

Command-T

There exists a plugin that implements this capability for Vim and it carries the same name as the shortcut: Command-T. It was in the default configuration for quite a while, and it was quite awesome. It was fast, and the fuzzy matching algorithm did a great job.

The only drawback was that it required your Vim to be compiled with Ruby support. On most Fedora distributions, Vim wasn't being built that way, which meant you had to build your own Vim. That was fine until a new contender came along.

CtrlP

CtrlP is also another fuzzy matching plugin, although it goes a little further than Command-T. Not only can you fuzzy match files and buffers, it can fuzzy match tags, the quickfix buffer, changing directories, undo history, lines in all buffers, and bookmarks too.

To bring up the fuzzy file matcher, type <ctrl-p><ctrl-p>. Just start typing characters from the filename and it will begin shrinking the list. Since CtrlP is entirely implemented in VimScript, it can take it a moment to bring up the file list the first time on large projects. CtrlP also caches the paths so the next invocation will go faster.

Here are some of the various shortcuts for CtrlP:

  • <ctrl-p><ctrl-p> for files
  • <ctrl-p><ctrl-o> for buffers
  • <ctrl-p><ctrl-m> for MRU (most recently used)
  • <ctrl-p>m for files, buffers, and MRU
  • <ctrl-p><ctrl-t> for tags

There are many more that Dr. Mike set up. You can see all the mappings with :help notes_ctrlp.

Since CtrlP does cache entries, you may need to clear the cache to have it recognize that some files were added or removed. You can do this with by pressing <F5> once the CtrlP prompt comes up.

Of the two plugins, I like CtrlP better because it's all in native Vimscript, and because it offers a framework for fuzzy matching on other things. Since it provided all the capability of Command-T, we recently pulled Command-T out of the configuration. This also removed the need to have Ruby support as well.

Snippets

This is another feature popularized by TextMate. I've used other snippet engines in the past, including SlickEdit's, but none have worked quite as well as Vim's [Ultisnips][ultisnips] plugin. The idea is that your editing a particular kind of file... maybe a C file. You can type a few characters, press tab, and presto! The few characters have expanded into a kind of template to speed you along.

For example, let's say I want to include a file. I might type inc:

inc typed in

Then hit Tab, which will expand into the include directive, with example.h highlighted:

Tab pressed

Then we can type in the name of the header, stdio.h.

All done.

The movie shows a slightly more elaborate example using the func definition, which is in the default configuration.

The take away is that it can help make some common things a snap to do. For instance, I've been writing quite a bit of documentation using reStructuredText and Sphinx lately. Writing documentation in reStructuredText can be a little bit onerous--though still much better than Word--but having snippets makes that process way easier. I type code<TAB> and now I have a code block. I type sect<TAB> and it starts a new section for me. Snippets not only help me get what I need faster, but more correctly.

Powerline

Powerline currently calls itself "the ultimate vim statusline utility," and I think it's pretty fitting. Normally, the statusline provides a few bits of useful information, but it isn't very context aware. Powerline provides fantastic context-based information.

It changes color based on mode, but it also provides extra information based on what you're doing at the time. For instance, when bringing up CtrlP, it will turn purple, and it'll tell you whether you're looking at files, open buffers, or tags, and shows you the path to the current working directory.

If you have Fugitive installed, it can also show you the current Git branch you're working on in the vim statusline as well.

Here's an example of how it looks normally:

Powerline in Normal mode.

Here's an example showing what the statusline looks like when CtrlP is active:

Powerline in with CtrlP active.

There's Plenty More

I only touched on a couple of plugins here because I think they're the most beneficial, but there are many more excellent plugins out there. It would be impossible to name them all here. Dr. Mike keeps notes on the plugins that have been added to his configuration. You can see them via :help notes. You can also take a look here on GitHub. His list is a good place to start if you're looking to add some plugins to your own configuration. However, if you're new Vim, perhaps starting with his configuration is the best choice.

Adding Your Own Customizations

Dr. Mike and I realize that everyone is different. So while we strive to provide a good starting point, we provided a mechanism for users to maintain long-term branches of the configuration. By default, our configuration will look in three places for extra customizations:

  • In ~/.vim/user/$VIMUSER-before.vim. This is good if you need to adjust the key that you want to use as the leader key. I often type on a Dvorak keyboard, and using a comma (,) works better for me, so I set it up there.

  • ~/.vim/user/$VIMUSER-after.vim. This is probably where you want to put the majority of your customizations.

  • ~/.vim/user/$VIMUSER/bundle/. This area will be treated as a place to put plugins that work with pathogen. Pathogen is an excellent way of managing your plugins, and many of them out there are compatible with it.

Note that VIMUSER defaults to the login name of the user. My repository shows an example of how you can use the -before and -after files to customize your experience.

Trying Out My Configuration

While VIMUSER defaults to the login name, you can override that by explicitly setting the VIMUSER variable. This means it's possible to try my customizations, if you like. To do so, instead of cloning Dr. Mike's repository, clone mine:

$ git clone git://github.com/jszakmeister/vimfiles.git .vim

Or, download a tarball:

$ curl -L -k https://github.com/jszakmeister/vimfiles/archive/mine.tar.gz \
  | tar zxvf -
$ mv vimfiles-mine .vim

Follow the steps in Getting Started, and then set VIMUSER to jszakmeister:

$ export VIMUSER=jszakmeister

And fire vim up:

$ gvim

If you'd like to try out the configuration longer term, you can edit ~/.vimrc and add the following line just before the runtime vimrc line:

let $VIMUSER = "jszakmeister"

It's Not About the Editor

This post has been entirely on Vim, but there are other awesome editors out there. The point is to learn the ins and outs of your editor of choice, and customize it to help you do things faster. Software development is in many ways a lot like other trades: honing your tools is part of becoming a master craftsmen. Spend the time tweaking your environment. It's worth the effort.


  1. If you'd like to combine the two steps into one, you could do curl -L -k https://github.com/drmikehenry/vimfiles/archive/master.tar.gz | tar xzv -s '|^vimfiles-master/|.vim/|S'

Comments

wow

I'm glad you asked the kind doctor to post his config. It's unbelievably thorough.

Thank you!

Yes it is. It's nice that he's worked through some of the pain points of getting a good configuration. And the best part is that it keeps getting better all the time. Make sure to follow him or his repo on GitHub!

HoCoBlogs

Hi, I'd like to encourage you to submit your blog to hocoblogs.com; it's free to be listed, and we'd love to have you listed there. ~ Jessie

Re: HoCoBlogs

Thank you for the suggestion! We'll look into it!

Snippets

Why are the snippets included in your config different from those here:
https://github.com/SirVer/ultisnips/tree/master/UltiSnips

That is the link I found in the documentation about adding snippets. Will those snippets work with your config? I'm asking because I'm looking for Java snippets.

Subject

Hi Aaron! Those snippets are included, but they're disabled for some file types. We did this for a few reasons. First, the packaged snippets often don't adhere to style guidelines given by our customers. Secondly, Holger (SirVer) recommends coming up with your own too. Snippets are often fairly personal, so it's good to customize them to your taste.

I'd recommend copying the ones you want into your user area (~/.vim/user/$USER/UltiSnips), or simply create softlinks to ones you are interested in--if you're OS supports softlinks. Then tweak and customize them to suite your needs. The ones that come with UltiSnips are located in ~/.vim/bundle/ultisnips/UltiSnips, if you're interested. You can also see them here: https://github.com/drmikehenry/vimfiles/tree/master/bundle/ultisnips/UltiSnips