Vim 101: Tags

A big part of editing that often gets overlooked is file navigation. Effective file navigation is a skill that can help improve productivity, but also aids visualisation of a project.

Vim's bare interface belies a wealth of hidden functionality that can help you dart around a project like a fake US crime drama hacker. One key feature is support for tag files. Tag files are simple text files that list "language objects" alongside file names and locations. It's very much like an index in a book, except it's generally interpreted by software rather than human readers.

There are three aspects to using tags in Vim:

  1. Generating tag files
  2. Setting the locations of these files
  3. Navigating using tags and understanding the tag stack

Generating Tag Files

Before you can use tags, you'll need to generate a tag file. There are several programs that can do this, although given how simple the tag file format is it wouldn't be too difficult to write new ones for less popular programming languages. Most people use Exuberant Ctags by Darren Hiebert -- if you're using Linux you probably already have it, otherwise it can easily be installed with a package manager. On a Mac Homebrew can install it.

The ctags binary will generate a tags file for a project. That means whenever files change it'll start to become inaccurate, and therefore must be regenerated. Several plugins have been created to manage this for you, but it's a good idea to do it manually first to understand how it works.

I have a copy of Vim's source where I ran ctags -R:

$ ctags -R
$ wc -l tags
   26353 tags

It took about half a second to generate on my system.

Using a Specific Tags File

To use the tags file, you'll need to open Vim and tell it where it is. Still in the Vim source directory, I ran vim and then typed :set tags+=tags to tell it to use the ./tags file.

At this point, Vim knows about the tags file -- you don't need to tell it to load the file.

Navigating with Tags

Typing :tag text will cause Vim to search through tags for a tag name, and :tag /pattern will search for pattern instead. So let's say I can't quite remember the name of the found_tagfile_cb function in Vim's source: I could type :tag /found_tagfile and it should skip to the closest match without opening the file where it's defined.

I find jumping to tags like this is useful, because I can often remember class names or function names but not which file they're in. This is great for projects that split across lots of files.

Tag navigation comes into its own when you're working with unfamiliar code. If you don't know how a particular function works, move the cursor over it and press CTRL-] to jump to the definition.


The CTRL-] command will jump across files and even projects: Vim doesn't understand the concept of a "project". You can create multiple tags files for anything you want, including the C standard library. When navigating Vim's source, that would allow you to look up the definition of a standard library function in a header file -- you're not limited to the current "project". This can make projects with limited documentation easier to figure out, so it's extremely useful when fixing bugs or doing general support work.

Jumping to a definition would be less useful if there wasn't an easy way of jumping back: once you're done reading the function's definition, press CTRL-T to go back to where you left off.


In this post you've learned how to generate a tags file, tell Vim where it is, look up a tag, search for tags, and jump between definitions. I recommend practicing these techniques, particularly CTRL-] and CTRL-T, before going off and installing fancy tags plugins. There are some great plugins out there, but you should master the basics before relying on them too much.

blog comments powered by Disqus