cscope or ctags why choose one over the other?

Robert S. Barnes picture Robert S. Barnes · Jun 1, 2009 · Viewed 70.1k times · Source

I primarily use vim / gvim as an editor and am looking at using a combination of lxr (the Linux Cross Reference) and either cscope or ctags for exploring the kernel source. However, I haven't ever used either cscope or ctags and would like to hear why one might choose one over the other taking into consideration my use of vim as a primary editor.

Answer

richq picture richq · Jun 1, 2009

ctags enables two features: allowing you to jump from function calls to their definitions, and omni completion. The first means that when you are over a call to a method, hitting g] or CTRL-] will jump to the place where that method is defined or implemented. The second feature means that when you type foo. or foo->, and if foo is a structure, then a pop-up menu with field completion will be shown.

cscope also has the first feature - using set cscopetag - but not the last. However cscope additionally adds the ability to jump to any of the places where a function is called as well.

So as far as jumping around a code base is concerned, ctags will only ever lead you towards the place where the function is implemented, whereas cscope can show you where a function is called too.

Why would you choose one over the other? Well, I use both. ctags is easier to set up, faster to run and if you only care about jumping one way it will show you less lines. You can just run :!ctags -R . and g] just works. It also enables that omni complete thing.

Cscope is great for bigger, unknown code bases. The set up is a pain because cscope needs a file containing a list of names of files to parse. Also in vim, by default there are no key bindings set up - you need to run :cscope blah blah manually.

To solve the fist problem I've got a bash script cscope_gen.sh that looks like this:

#!/bin/sh
find . -name '*.py' \
-o -name '*.java' \
-o -iname '*.[CH]' \
-o -name '*.cpp' \
-o -name '*.cc' \
-o -name '*.hpp'  \
> cscope.files

# -b: just build
# -q: create inverted index
cscope -b -q

This searches for code that I'm interested in, creates the cscope.files list and creates the database. That way I can run ":!cscope_gen.sh" instead of having to remember all the set up steps.

I map cscope search to ctrl-space x 2 with this snippet, which mitigates the other downer of cscope:

nmap <C-@><C-@> :cs find s <C-R>=expand("<cword>")<CR><CR>

There's this cscope_maps.vim plugin that sets up a bunch of similar bindings. I can never remember what all the options mean, so tend to stick to ctrl-space.

So to conclude: ctags is easier to set up and mostly works without doing much else, it's vital for omni-complete too. cscope provides more features if you have to maintain a large and mostly unknown code base, but requires more leg work.