[ home ]

(Exuberant) Ctags, Cscope and Vim

Ctags and expecially Cscope in combination with Vim can really boost productivity when working with home-grown and foreign source-trees.

Both tools basically generate references out of source-files, which can be used to locate and cross-reference source-symbols.

While Cscope does come with its own curses-based UI, Vim provides a really nice interface to either tool.



In Arch Linux, package ctags is actually Exuberant Ctags. The binary is called 'ctags'.

In NetBSD, you can use ctags in base, or Exuberant Ctags ('exctags' in pkgsrc). The latter generates more tags; e.g. simple C functions are not (always?) found using the ctags in base.


in Arch Linux, package cscope is in the standard repository. From what I can see, it's available as NetBSD package as well.

As far as I can see, there is just 1 flavour of Cscope.

Create database

vanilla Ctags (NetBSD base)

Exuberant Ctags

Helper-script to generate tags for C-files in multiple given dirs (recursive):

    [ -n "$dirs" ]  ||  dirs=.
    rm -f tags
    for d in $dirs; do
        ctags -a $( find $d -name \*.c -o -name \*.h )


(For non-native source-trees, -k ('kernel') can be given to exclude system include-dirs - '/usr/include' etc - from trying to locate #included files.)

(To generate ASCII-only cscope.out files, add the -c switch. This makes it easier to debug Cscope-lookup, when e.g. lookup of a symbol fails.)

Use in Vim



To automate things a bit, I use the following snippet in .vimrc (as found somewhere on the net - thank you, original author):

    if has("cscope")
        set csprg=/usr/bin/cscope
        set csto=0
        set cst
        set nocsverb
        " add any database in current directory
        if filereadable("cscope.out")
            cs add cscope.out . -C                            (*)
        " else add database pointed to by environment
        elseif $CSCOPE_DB != ""
            cs add $CSCOPE_DB . -C                            (*)
        set csverb
        " 0 or s: Find this C symbol
        " 1 or g: Find this definition
        " 2 or d: Find functions called by this function
        " 3 or c: Find functions calling this function
        " 4 or t: Find this text string
        " 6 or e: Find this egrep pattern
        " 7 or f: Find this file
        " 8 or i: Find files #including this file
          nmap <C-m>s :cs find s <C-R>=expand("<cword>")<CR><CR>
          nmap <C-m>g :cs find g <C-R>=expand("<cword>")<CR><CR>
          nmap <C-m>c :cs find c <C-R>=expand("<cword>")<CR><CR>
          nmap <C-m>t :cs find t <C-R>=expand("<cword>")<CR><CR>
          nmap <C-m>e :cs find e <C-R>=expand("<cword>")<CR><CR>
          nmap <C-m>f :cs find f <C-R>=expand("<cfile>")<CR><CR>
          nmap <C-m>i :cs find i ^<C-R>=expand("<cfile>")<CR>$<CR>
          nmap <C-m>d :cs find d <C-R>=expand("<cword>")<CR><CR>

...which basically does the following:

See either Vim or Cscope docs (or the comment, above) for different types of queries.

Have fun!