# VIM, The Killer

I’m gonna show you how to get a nice and modern C++ setup for VIM. I’ll talk about my setup in specific, which is OS X based, and should be similar in *nix platforms, and more or less in Windows.

## Results

While building my environment I didn’t stop where the tools didn’t work properly, I fixed them, or searched for help, and learned a lot. In the end I learned Python and VimScript, languages I never touched before, and I liked.

Let’s review those tools, one by one:

### Command Line Tools for Xcode

This will install initial precompiled tools, like compilers, libraries, and also header files, so that you are able to compile Clang.
You can just download Xcode from App Store for free and then install it from Preferences > Downloads > Components, or you can just install it from the OS X Leopard installation media. For Lion and Mountain Lion users, you can get the tools from https://developer.apple.com/downloads, this requires registration to get the download links. As of august 2012, the direct links are the following:

### Git

A modern VIM configuration needs to take advantage of Git, a great amount of plugins lives on GitHub now. Adding a plugin to your installation, that gets persisted on the web, is just a matter of cloning a plugin repository, or even better, turning it into a submodule of your main VIM repository. Managing plugins is managing modules, updating your installation and all plugins at once is just a git command! vim pathogen will help maintaining everything organized. I’ll talk about that later.

### Clang

First, take a look at this: A comparison of C++11 language support in VS2012, GCC 4.7 and Clang 3.1.
So, do you want to really feel how it is to program in C++11? Use Clang! forget the rest.
Clang not only does the job of compiling, it provides compiler services, like syntax checking and completion, and that’s also why I use it, it’ll do the job of C++11 completion for VIM with a little help from the clang_complete plugin.
One thing you need to do is to compile it from sources, directly from trunk. The official repository is SVN, but there’s an official Git mirror. You must build it from sources because I got involved in some annoying completion bugs, which are currently fixed on trunk!
I’m using /usr/local to save and install projects I compile from sources. As stated in the homebrew FAQ:

Apple has conformed to POSIX and left this directory for us. Which means there is no /usr/local directory by default, so there is no need to worry about messing up existing tools.

I save project’s sources at /usr/local/src. For example, I cloned LLVM sources to /usr/local/src/llvm. When installing, I install them to /usr/local.
There’re two things that must be done in OS X to make such a setup work well:

• edit /etc/paths and put /usr/local/bin at the top, this will make tools installed at /usr/local/bin take precedence over others. This is specially needed for Clang, because your system will contain other installation at /usr/bin.
• your permissions may be messed up at /usr/local. There’s no need for sudo install in this directory, so to keep things clean, I recursively changed owner and group (group to admin as in homebrew):

  sudo chown -R francisco:admin /usr/local


Look that francisco is my user, you should put your own.

I then cloned the git mirrors for LLVM and Clang to /usr/local/src with:

git clone http://llvm.org/git/llvm.git /usr/local/src/llvm
git clone http://llvm.org/git/clang.git /usr/local/src/llvm/tools/clang


and built and installed everything by:

mkdir /usr/local/src/llvm/build
cd /usr/local/src/llvm/build
../configure --enable-optimized --disable-assertions --enable-targets=host-only
make -jgetconf _NPROCESSORS_ONLN install


LLVM’s configure script will install at /usr/local by default, so no need to set --prefix.
From here on, I compile everything with this compiler, not the one at /usr/bin.

### libc++

libc++ is the new LLVM’s C++ standard library implementation. I’ve chosen to use it, but you are not obligated to do the same. I even build MacVim with it.
I’ve followed the documentation for installation, the steps are simple, and you can also clone from a git mirror instead of the default SVN:

git clone http://llvm.org/git/libcxx.git /usr/local/src/llvm/tools/libcxx


I then followed the steps in documentation, with one difference, you should not put the include files in /usr/include/c++/v1, your just installed Clang won’t look there, you must put it in /usr/local/lib/c++/v1. Just as the documentation suggests, I’ve just made symbolic links after building. Also, I symlinked the libs to /usr/local/lib, not /usr/lib as suggested.

### PCKeyboardHack

This one is vital for Mac VIM users, it’ll turn your useless caps lock key into esc’s. download it now!

### MacVim

Since I’ve chosen a newer Ruby as default at my setup, I needed to compile MacVim from sources to make it use the newer one. MacVim uses an Xcode project, so you’ll need to download it from App Store first, it’s free.
The advantage of compiling it from sources is that you can optimize compilation. I’ve open up MacVim.xcodeproj and changed it to use Clang and libc++ at compilation. Also, by building from sources you can make document icons available, so that when you set a filetype to aways open with VIM, it won’t show a generic VIM icon in Finder, but a specific one for the file type. You can find more information at the MacVim GitHub wiki.
I’ve set MacVim as my editor of choice for a huge number of file types by using RCDefaultApp.
I’ve cloned MacVim to /usr/local/src/macvim and then, after building, just created a bunch symlinks to install it:

ln -s /usr/local/src/macvim/src/MacVim/build/Release/MacVim.app /Applications/MacVim.app
ln -s /usr/local/src/macvim/src/MacVim/mvim /usr/local/bin/mvim
ln -s /usr/local/bin/mvim /usr/local/bin/mvimdiff
ln -s /usr/local/bin/mvim /usr/local/bin/vim
ln -s /usr/local/bin/mvim /usr/local/bin/vimdiff


mvim is a smart shell script to launch MacVim in GUI or command line mode, you can find more information by invoking the help: :h macvim-start. I’ve tweaked this script a bit to make the GUI launcher (mvim or mvimdiff) to aways use a running instance to open a file in a new buffer, instead of opening a new MacVim instance:

### vim pathogen

Once you start to use it, you know how essential it is. vim pathogen makes using VIM plugins so much easer. Before it, plugins just dropped its files in a confusing manner at the VIM directory, afterwards, how do you know which files comes from which plugin? By using vim pathogen every plugin stays in its own directory, it’ll recognize the vim directory structure inside the plugin’s directory and load it without the need to merge plugin files inside a single directory structure.
After learning of vim pathogen, I’ve made a cleanup at my .vim directory. I started again with an empty one, turned it into a git repository, and added plugins as git modules:

git submodule add git://github.com/tpope/vim-pathogen.git               bundle/vim-pathogen


Some of these submodules are from my personal copies at https://github.com/oblitum, they need to, and I’ll explain it in their own sections.

The only setup for vim pathogen at my .vimrc is the default:

vim pathogen takes care of loading itself, and the other plugins, all living in their own directories.

EDIT 1:
As usual in all things VIM, there’re options, Rodrigo Delduca, aka skhaz just made me remember of Vundle. It builds upon ideas from pathogen and others, currently I don’t use it, feel free to try.

EDIT 2:
Also, I just recalled of VAM too.

### vimprj

vimprj is neat, it’s a minimalist plugin that does the job of cascade sourcing of vim configurations in a directory tree. What can you do with that?

Let’s say I have a boost-samples directory with some C++ files that must link against boost_system to build. I use the SingleCompile plugin for simple compilations and have set a variable to store compiler options for it. This variable has a default value at my .vimrc, but at my boost-samples directory I want to append -lboost_system to the compiler options, how to do that? With vimprj I can just create a .vimprj file at my boost-samples directory and I can just append the extra compiler option to the variable!

Contents for boost-samples/.vimprj:

Done! .= appends strings in Vim Script, now when I open a C++ file living somewhere in the boost-samples directory, or any subdirectory, the “virtual .vimrc” loaded for that file will have the .vimprj file sourced!

But, let’s say there’s a boost-samples/chrono-samples directory, where I need not only to link against boost_system, I need to link against boost_chrono too, what to do?

Contents for boost-samples/chrono-samples/.vimprj:

Done! For the files living in boost-samples/chrono-samples, boost-samples\.vimprj will get sourced and then boost-samples/chrono-samples/.vimprj too! It’s all the flexibility of Vim Script being sourced in cascade =D

This is not all the truth, but is enough to explain the point. The truth is that SingleCompile in specific can’t get configured just by setting a variable, a function like the following must be called to get it’s configuration updated:

Did you see the g:single_compile_options variable being used right there? ok. Let’s say we put this function at our central .vimrc, what we need now is a vimprj hook that calls this function everytime a .vimprj file ends being sourced, so that changes to g:single_compile_options take effect. And we could not expect less from such a smart plugin, just putting this at our beloved .vimrc:

Now g:single_compile_options will aways get a default value and changes to it will aways take effect after sourcing a .vimprj file, and when not sourcing too ;-)

You should get .vimprj not from vim.org, but go directly to the mercurial repository, or even my github copy, the OnAfterSourcingVimprj hook was added after some hacking I was doing that in the end turned in a request to the vimprj author, which he kindly accepted.

### NERD tree

Well, I think I don’t need to explain it, this plugin is so popular. It’ll create a neat buffer to let you browse your filesystem. The only caveat with it I think, is when you begin deleting buffers and the NERD tree buffer takes all the screen. To solve it I employed bufkill, it’s a plugin to provide buffer deleting commands that preserves the VIM’s window layout.
Also, I’ve employed some protection for the NERD tree buffer so that I don’t delete it by accident. These are my mappings relating to NERD tree:

### Command-T

Command-T is another smart file browser for VIM, this one uses fuzzy input to look for files, and it’s a very fast way of doing that in a project tree. This plugin is built upon Ruby and a fast C library for Ruby. I got it from the official git repository and just followed documentation. Just remember it’s a VIM plugin, and as such, must be compiled with the same environment as VIM. This one requires a C library to be compiled, I compiled it with Clang and libc++, as I compiled MacVim.

### Ruby

You may chose the Ruby version you’ll use, the important thing is that VIM must be compiled with the same Ruby version as the one you’ll employ in your system. VIM can be compiled with Ruby and Python script support, Ruby is needed for Command-T for example, and Python is needed for clang_complete. I use RVM for managing Rubies, and used Ruby 1.9.3 for my setup.

### clang_complete

Well, I’ve applied so many tweaks to this project, that I’ll just advice you to clone/fork (or just download it) from my repository instead of the official one. I’ve applied several performance patches that now, are still to be merged in the official.
This project started as a Vim Script plugin that just used Clang binaries to do completion and syntax checking, afterwards it evolved to use libclang and its python bindings to perform much faster than calling an external process. The problem is that, to my taste, the python part of clang_complete was not well developed.

After applying all the performance tweaks, I still feel there’s much room for improvement at other areas, for example, completion for include files should be very easy to do. libclang is evolving, currently it supports completion that gathers doxygen comments! but clang_complete doesn’t support it yet. Also, libclang could be used for other coding stuff beyond trivial completion and code checking. For that I don’t blame clang_complete, it deserves its own project.

So, as I was saying, clone my fork and then checkout my experimental branch if you want to taste a speedy completion. At this branch I expect to evolve things I mentioned, do refactorings, and make its python code more polished. I expect to do it faster and not willing too much to merge changes in the official repository.

These are configurations I have in my .vimrc that relates to clang_complete:

Two things above that are specific of my experimental branch are g:clang_memory_percent and g:ClangBackgroundParse().

g:clang_memory_percent is a setting I’ve created to control the amount of RAM VIM can use to maintain translation units. When Clang parses a file, it can take a considerable amount of RAM for each file parsed, once the amount of RAM being used reaches a given percentage of the total memory, clang_complete will start to deallocate old translation units to leave room for new ones. This is a hint for the maximum of memory that can be used for translation units. This feature requires installation of the psutil python module.

g:ClangBackgroundParse() is a function I’ve created to issue reparsing in background of the source file being edited, as it takes some seconds. It’s mostly useful only when you touch your include headers because Clang precompiles your include section to provide faster completion, and if you change it, you should issue a reparsing to get really fast again.
I’ve created a key mapping for this background reparsing, and also one for the syntax checking feature.

Also, talking about precompilation, currently for it to happen, your source file must exist in the file system. Creating a new file without saving it at last once will not give optimal completion results, once you save it and issue a precompilation, completion is optimal. Completion is optimal while the include section is not touched, once touched, issue a parse. A first parse aways happen after opening a file, so no need to do it manually after opening an existing file. No need to save an existing file after touching includes, just issue a reparse.

g:clang_auto_user_options is a clang_complete setting that has a default value that just caused me problems. This one provides some automatic sources for include headers. I just don’t use it, as I use vimprj to control include directories and stuff like that by setting g:clang_user_options.

Last, but not least, currently there’s a proposal for a kind of Clang services daemon. The future of completion and syntax checking? Who knows.

### SingleCompile

I started using this one for ingenuous compilation of C++ samples, It’s working for that job very well. It can be used with make files, cmake, I don’t know, I haven’t looked into that yet. As already mentioned, I employ cascaded configurations for it using vimprj.

### Ultisnips

Ultisnips is a very well supported snippets plugin, contrary to the competition like SnipMate. It works well with other plugins like SuperTab and clang_complete by not using the same key mappings by default, avoiding conflicts.

### SuperTab

Don’t like to force completion with ctrl-x ctrl-u? SuperTab to the rescue, with it you can use tab most of the time for completion without problems. I’ve set it up like this to get forced Clang completion with tab:

The <c-p> at the end of the <c-x><c-u> is to issue a “control previous” after a completion, this avoids auto selection of itens from the popup menu. I don’t like auto selection.

You can use tab and shift-tab to browse completion entries in the popup menu, tab to browse through function parameters in normal mode (when g:clang_snippets_engine='clang_complete'), to complete a word in the middle, you got it.

### Auto Pairs

Auto Pairs will create automatic pairs for [], {}, (), "", etc. I’ve requested a small correction for it, so I advice you to get a recent copy. Also, if you are an OS X Lion user, or Mountain Lion user like us, there’s a weird behavior with alt/option keys, also know as meta keys in VIM. An alt key combination will produce a special character, for example, alt-p produces π, alt-m produces ∑, and there’s a bunch of others. Auto Pairs uses a bunch of meta key mappings that just won’t work because of that. The solution I found was to map this special characters at my .vimrc and it does works:

### Cpp11-Syntax-Support

This one is to provide minimal support for syntax highlighting of the new standard. I didn’t look too further of what highlighting it does, just installed.

### cSyntaxAfter

Most VIM colorschemes doesn’t provide highlighting for operators of C based languages, I think this is most due to the lack of a syntax highlighting group for that. This small plugin will put operators in a new syntax highlighting group and turn highlighting for them.
I started using it very recently, and applied two small tweaks, one is that I changed it so that it doesn’t highlight < or > when there’s a sequence as <# or #>. <# and #> are used by clang_complete snippets as placeholder marks, and they can be concealed (hidden from user view). The problem is that if highlighting get it, they cease to be concealed. So I’ve used some VIM regex to exclude these special cases.
The other small tweak is that it was highlighting { and } with hardcoded yellow, which wasn’t looking good with light colorschemes. So I changed it to use a default color for operators.
You can get it with the changes from my GitHub repo.

## Results

### My .vimrc

You can check my .vimrc from this gist. It’s contains what I’ve already talked about plus yet more usage of vimprj for example, which can illustrate things better.

### This is what you get

Ok, I’ve prepared a 12 minutes video covering some usage of the above environment editing some C++ files using Poco, Boost, STL, variadic templates, new range for syntax, uniform initialization, etc. Sorry for the slow typing, I was copying text from my cellphone :P and I’m still a beginner in VIM. I tried to cut/edit with iMovie but it just messed with the quality, so I uploaded it raw. If you don’t want to take a look at the whole video, the following links may be of interest:

### Bonus

Now, if you got here and think VIM does not have potential, go get your Winchester! but I’ll stick with my 45: