September 10, 2018

Ctags and the Vim editor

I highly recommend ctags if you are working with a big piece of software with lots of files and directories.

Suppose you are studying a large body of source code that is unfamiliar to you. Perhaps there are hundreds, maybe even thousands of files. Suppose there is some byzantine include file setup. I have found myself in this situation exploring the linux sources. Dealing with the sources for U-Boot is also a nasty business.

One way to try to cope is to keep a window open at the root directory of the project and use it to perform "grep -r some_thing ." whenever you want to chase down the definition of a function. If you find yourself doing this, there is a better way, namely ctags.

  • Vim and ctags
  • Navigate like a pro with ctags
  • Browsing with ctags
  • Ctags tips and tricks

    It is worth mentioning that there are improved tools that serve the same purpose as recursive grep, namely Ack and Ag. I recommend "Ag". Whenever you feel the itch to type "grep -r xxx ." consider typing "ag xxx" instead. It is very fast, and the output is nice.

    Note that Ack uses perl style regular expressions.

    Also worth mentioning is Cscope. This is a standalone program apart from Vim and ctags. It allows you to do the inverse of ctags (find out where functions are called from or referenced).

    Installing ctags

    This was "just there" on my fedora linux system, but you may need to install some package.

    What you want is "Exuberant ctags", not some older version. On my Fedora system, this is installed by default as revealed by:

    [tom@trona ~]$ which ctags
    /usr/bin/ctags
    [tom@trona ~]$ ctags --version
    Exuberant Ctags 5.8, Copyright (C) 1996-2009 Darren Hiebert
      Compiled: Feb  3 2016, 19:43:56
      Addresses: , http://ctags.sourceforge.net
      Optional compiled features: +wildcards, +regex
    
    If you are OSX, you probably have the old ctags, so beware.

    Running ctags

    You need a "tags" file in the base directory of your project. You make one like this:

    cd /path/u-boot
    ctags -R .
    
    This takes only a few seconds, even on a very big project.

    You should also put a line like this in your .vimrc. With this, vim will run up through directories looking for a tags file, so you get access to tags even when working down inside a project.

    set tags=tags;
    
    If you are using git (and you should be), you will want to add the tags file to your .gitignore.

    Hiding the tags file

    You can hide the tags file if it offends your sense of tidiness by using "ctags -R -f ./.git/tags ." This places the tags file into the .git directory for your project.

    This does not work for me -- vim does not find the tags file. I'll sort this out someday, something probably needs to be fiddled in the .vimrc file, despite what they say.

    Using ctags from within Vim

    Two keys handle most of what you want to do with ctags inside of vim.

    Control-] -- goes to the definition of whatever the cursor is on.
    Control-t -- unwinds the above one level (a "back" button).
    
    Sometimes there are choices about where to go and you are presented with a "menu" and need to type a number to make a choice.

    If you just want to launch vim at a certain function definition, use:

    vi -t my_func
    

    The "*" key has nothing to do with ctags, but is hugely useful. Rather than typing in search strings by hand, if the string is already part of the text you are looking at, place the cursor on it and type "*" (the star key). Vim will go to the next occurence of the word in the same file. Break your habit of using slash searches and use this more.

    If you are in vim, and want to go to the definition of a function (and the string isn't already on the screen so you can use Control-] type the following:

    :tag my_func
    

    The ":tag" command provides additional functionality. Using ":help tag" will be instructive.


    Have any comments? Questions? Drop me a line!

    Tom's vim pages / tom@mmto.org