Vim Recipes Navigation Navigating Tags

Navigating Tags

Problem

You're working on a project where you need to jump between occurrences of significant keywords, which are possibly spread across multiple files.

For example, you're writing source code and want to be able to type a function name then quickly jump to where it was initially defined so you understand how it should be used. Then you want to return to where you were.

Solution

Use tags. Tags are similar to index entries in a book: significant terms are linked to the key places that they occur.

We will use a program called Exuberant Ctags to generate the tag list because it is compatible with popular programming languages such as C, C++, Java, Lisp, Perl, PHP, Python, and Ruby.

After you have installed Ctags you can generate a tag list for the current directory (and its sub-directories) with ctags -R. To only consider files in the current directory use ctags *. This will generate a tag list for source code in most common languages.

You can now open a source file from that directory and use the :tag tag command to jump to the definition of the tag. To look up the tag under the cursor use <Ctrl>+]. You can also auto-complete tag names by starting to type one then using <Tab> to cycle through the list of matching tags. To return to where you were before you jumped to a tag you use <Ctrl>+t.

Discussion

So far, we have only described tags in terms of program source code, but they are by no means limited to this domain. The Vim help system uses tags extensively to allow navigation. When you use :help term you're actually looking up a tag in the documentation tag file. When you position your cursor over a highlighted entry in a help file, you use <Ctrl>+] to follow it. This is all possible because as long as you have a way of identifying significant terms in a file, you can generate a tags list for it. For example, here's an excerpt from the tags documentation:

                *tags-option*
The 'tags' option is a list of file names.  Each of these
files is searched for the tag.  This can be used to use a
different tags file than the default file "tags".  It can
also be used to access a common tags file.

The tags-option syntax is used for defining a tag. Elsewhere, the |tags-option| syntax is used for linking to a tag. You can use :helptags dir for generating a taglist for all *.txt files in the given directory which are marked up in this way.

However you generate it, the tag list is a static file, so it must be regenerated when your files change significantly. In programming projects, it is typical to update the tags file during the build process. For example, the Makefile could execute ctags.

Both invocations of ctags given above are very liberal in what they index. They search for all programming language source code in the specified directories, and incorporate all the tags found therein into a single tags file. To limit ctags to just Ruby source code, for example, you can use ctags *.rb. For more control over what files ctags considers, consult its documentation. On Linux: man ctags.

Once you have generated the tags file Vim needs to be able to find it. By default it looks for a file named tags in the current directory, but for projects which span multiple directories this is not always suitable. You can specify the location of the tags file using :set tags=file. Specify multiple tag files by separating the paths with commas. Instruct Vim to search for a tags file recursively with :set tags=./tags;/.

Using <Ctrl>+] to jump to a new tag takes you to a new buffer to show the results. If you'd rather see them in a new window use <Ctrl>+W+], or :stag tag.

If you get dizzy after all this jumping around you can reacquaint yourself with where you've been by using the :tags command. This shows you which tags you've jumped to, and where you jumped to them from.