Here are some details about how I use VIM with CSCOPE and CTAGS to navigate a codebase.
I keep all my different codebases/repositories in ~/repos/ – I then have a bash script (called “workon”, kept in ~/bin/workon) that is used to jump into a codebase and set up some environment variables. Edit the WORKSPACEROOT definition in the workon file if your repos live somewhere else.
Since “workon” modifies env vars in your current shell, you have to use it with the source command, like this:
$ source workon somecodebase
Since cscope and ctags need to store their database files somewhere, I chose to keep them in ~/scopetags/ so make a scopetags directory in your home directory first. After you’ve run the “source workon somecodebase” command to set up your env vars, run the “regen_cscope_ctags” bash script to analyze the selected codebase and store the database files in ~/scopetags/. Run this script whenever you want to update the database, so do it after you make changes or git fetch a bunch of new code.
Then, we need to tell vim how to interact with cscope/ctags. Edit the file ~/.vimrc and add this line to the end:
let &tags=$CTAGS_DB
Then, make a new directory ~/.vim/plugin/ and download this file into that plugin directory: http://cscope.sourceforge.net/cscope_maps.vim
Now, once you do the “source workon” you can open vim and use the ctags or cscope shortcuts to navigate the codebase. Here are the most common things to do.
Put the cursor inside a variable or function name. Press ctrl + \ + a letter code:
- g = goto definition of that variable/function
- s = search for all uses of that variable/function
- c = callers of that function
This will usually open a little menu where you can pick from a list of all the search results.
Press ctrl + t to jump back.
You can also use ctrl + \ + f to search for a filename under your cursor (great for #include “foobar.h” lines).
You can also use vim commands to do searches, when your search term isn’t under your cursor:
Use CTAGS to search for a variable/function/file/etc – You can use tab-complete here.
:ts searchterm
Use CSCOPE to find the defintion/callers/uses/files (same letter codes as above)
:cs f g somevariable :cs f c somefunction :cs f s something :cs f f somefilename
Hope that helps!
~/bin/workon
#!/bin/bash #vi:syntax=sh # This script must be sourced if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then echo "You should source this script instead of calling it." exit 1 fi WORKSPACEROOT=$HOME/repos if [[ $# -ne 1 || ! -d "$WORKSPACEROOT/$1" ]]; then echo "Usage: source workon workspace" echo "Available workspaces:" ls -1 $WORKSPACEROOT fi export WORKSPACE=$1 export WORKSPACEDIR=$WORKSPACEROOT/$WORKSPACE # for vim: SCOPETAGSDIR=$HOME/scopetags/$WORKSPACE export CSCOPE_DB=$SCOPETAGSDIR/cscope.out export CTAGS_DB=$SCOPETAGSDIR/tags cd $WORKSPACEDIR
~/bin/regen_cscope_ctags
#!/bin/bash #vi:syntax=sh if [ -z "$WORKSPACEDIR" ]; then echo "Need to \"source workon $workspace\" first..." exit 1 fi SCOPETAGSDIR=$HOME/scopetags/$WORKSPACE if [[ ! -d $SCOPETAGSDIR ]]; then mkdir -p $SCOPETAGSDIR fi cd $SCOPETAGSDIR INDEXFILES=$SCOPETAGSDIR/files find -H $WORKSPACEDIR -name '*.c' -o -name '*.h' -o -name '*.a' > $INDEXFILES echo "Generating cscope files..." cscope -i$INDEXFILES -b -q # -b Build the cross-reference only. # -q Enable fast symbol lookup via an inverted index. echo "Generating ctags files..." ctags -L $INDEXFILES --extra=+f # -L Read the list of file names from the specified file. # --extra=+f Also include entries for base filename.
good article