Today I learned

Navigate code like a pro with Ctags

Ctags is not always the best solution to this today. There are Language Server implementations for some modern languages that would offer these features and more. Also, as of 2019, there are other ctags alternatives to consider today, such as Universal Ctags.

Ctags lets you navigate code fast, and is perhaps the single most useful productivity boosting tool in any developer's arsenal. If you're not using Ctags yet, let's get you started.

What's it for?

Ctags indexes a project's tags, or names of its classes and methods. Coupled with some integration with your editor (shown: Vim's unite-tag), it will give you two interesting features to help you traverse code base:

  1. Jump to where any class, module, method, or function is defined given its name. In vim, that's :tag.

  2. Place your cursor on a word, and jump to where it's defined with one keystroke. In vim, that's ^].

Installing Ctags

Exuberant Ctags

In OS X, use Homebrew to install Exuberant Ctags. This is a more useful version of ctags than the one that ships with Xcode.

brew install ctags

Ctags options

Let's make ctags ignore some common directories. Save this file as ~/.ctags.

--recurse=yes
--exclude=.git
--exclude=vendor/*
--exclude=node_modules/*
--exclude=db/*
--exclude=log/*

Generate ctags for a project

Go to your project's path, and run ctags to generate a tags file in your project. This is the index of all tags in your project that your editor will use.

ctags .

Ignore all ctags files

It's safe to make all projects ignore all files called tags. I recommend setting up a global git ignore list.

echo "tags" >> ~/.global_ignore
git config --global core.excludesfile $HOME/.global_ignore

Vim setup

Auto-update ctags files

Use vim-autotag to automatically update tags files. This will only work on projects that have already had ctags -R performed before.

Plug 'craigemery/vim-autotag'

Jumping to tags

Use :tag to go to the definition of a certain tag. Usually, you will want to use this to jump to a certain Class or Method. Yes, this supports tab completion!

:tag ClassName

From the command line

Use vim -t to open vim to a certain tag.

vim -t <tag>

Navigating through multiple definition

If you used :tag on a tag that's got multiple definitions, use these commands to sift through them all.

ShortcutDefinition
:tnMove to next definition (:tnext)
:tpMove to previous definition (:tprevious)
:tsList all definitions (:tselect)

Key shortcuts

You can also place your cursor on some text and press ^] to jump to that tag.

ShortcutDefinition
^]Jump to definition
^tJump back from definition
^W }Preview definition
g]See all definitions

Unite integration

If you're using unite.vim, you can use unite-tag to browse tags. You can also check out my plugin, vim-fastunite, which offers a pre-packaged distribution of Unite.vim.

:Unite -start-insert tag

Futher reading

You have just read Navigate code like a pro with Ctags, written on April 22, 2015. This is Today I Learned, a collection of random tidbits I've learned through my day-to-day web development work. I'm Rico Sta. Cruz, @rstacruz on GitHub (and Twitter!).

← More articles