Skip to main content

Navigating source code with VIM

Lately I've had the pleasure to have to read different code bases in a fairly short amount of time. So I spent a little bit of time checking out the available tools to navigate source code in a more efficient way than launching 'grep' all over a code base. So first things first, let's make sure that on this system (Fedora 19) all the needed packages are installed:

$ rpm -q vim-enhanced cscope ctags vim-nerdtree
 vim-enhanced-7.4.027-2.fc19.x86_64
 cscope-15.8-4.fc19.x86_64
 ctags-5.8-10.fc19.x86_64
 vim-nerdtree-4.2.0-9.fc19.noarch

Let's start to explore one tool at the time.

NerdTree

I use this plugin just to get a better feel of how files and directories are structured. Once you install 'vim-nerdtree', you only need to type ":NERDTree" from VIM to activate it:

nerdtree

ctags

Let's now add the vim-taglist plugin to our VIM installation:

mkdir -p ~/.vim && wget -O ~/vimtaglist.zip \
 http://vim.sourceforge.net/scripts/download_script.php?src_id=19574 \
 && cd ~/.vim && unzip ~/vimtaglist.zip

Also add the following line to your ~/.vimrc:

" Enable Tlist toggle with F8
nnoremap <silent> <F8> :TlistToggle<CR>

Now we can see all the functions, macros and variables of a source file just by pressing F8:

ctags

Using Ctrl-] you will always go to the definition of a symbol which is pretty handy (use Ctrl-t to go backwards)

cscope

I also use cscope because ctags is not always too precise and it does not allow you to see which functions call a certain other functions which is often quite handy. It is slower than ctags to generate the index so it's a bit more painful for bigger codebases but nothing too dramatic. Let's start by creating the index for our codebase via:

cscope -R -b -q

Note: the above cscope command indexes all the files. You might want to make it smarter and index only the files you're interested in. I do that with a script that takes all the files with extensions and skips certain directories I am not interested in (for example arch/ia64 of the Linux kernel)

Once the index 'cscope.out' is created we can use it within VIM. Let's for example open VIM in the same directory as 'cscope.out' and look for "all the functions that call add_matched_proc()" via ':cs find c add_matched_proc'cscope

CCTree

The cctree plugin is not currently packaged in Fedora so we need to install it by hand:

wget -O ~/.vim/plugin/cctree.vim http://www.vim.org/scripts/download_script.php?src_id=18112

Once installed we need to load and parse the cscope DB. We do this with ':CCTreeLoadDB cscope.out'. Once this is done we can ask ourselves questions like "what is the callgraph of functions from main()"? We type ":CCTreeTraceForward main" and we get something like the following:

cctree

Do you have other useful plugins you use? Drop me a line ;)