Cover V09, I11
Listing 1
Listing 2
Listing 3
Listing 4


Using vi Tag Files

Ed Schaefer

Administering large software projects requires editing objects in multiple source files. If the desired object, function, etc. is not in your working source file, you probably won't remember where in the source hierarchy that object resides. The vi editor provides a tag file facility that allows a developer or admin to move the vi editing session to the desired object and changes the current working source file with just a key stroke combination. This article covers the use and structure of vi tag files. Creating tag files with the UNIX ctags utilities is also presented.

Cursor Movement with Tag Files

After tag file set up, while in vi, simply place the cursor on the first character of the object and press control-] (right bracket). vi changes the current file to the file in which the object resides. The control-] provides a developer with just a key stroke to move to a function in another source module.

An equivalent method is the tag command. While in vi command mode:

:tag func2
causes the same effect as placing the cursor over func2 and pressing control-].

In addition to cursor movement commands, you can initialize vi knowing the object name by using the -t flag:

vi -t <object>
For example, if function func2() resides in func2.c, executing vi -t func2 makes func2.c the current file and places the cursor at the func2() position in the file.

At any time in vi, you can return to the last edited file by using the e# command (e!# to ignore any changes to the current file). Solaris has provided an extension called “tag stacking” using the control-t command. With tag stacking, cursor movement between files using control-] is remembered. Pressing control-t returns to the previously edited file. Successively executing control-t returns up the stack until the top is reached with “tag stack empty” message.

Tag File Structure

The tags file on separate lines contains the object name, the file in which it is defined, and a search pattern for the object definition, separated by white space. The tags file (which by default is named tags) can be changed with the set command:

:set tags=<new file>
An example of a line of tag file might be:

func2     func2.c       \
   /^void func2(char *str)$/
Using UNIX ctags Command

Fortunately, UNIX provides a utility called ctags that creates a tags file for specified C, C++, Pascal, FORTRAN, yacc, and lex source files. Assuming C source, the tagged objects may be functions, typedef, #define, enum, struct, and union statements. Execute ctags in the present working dirctory:

ctags *.h *.c
Consider an example C project: Listings 1 to 4 include a header file, max.h and three C files, main.c, func1.c, and func2.c. Executing the above ctags command creates the following tags file:

Mmain     main.c    /^main()$/
func1     func1.c   /^void func1(char *str)$/
func2     func2.c   /^void func2(char *str)$/
max       max.h     /^#define max(x,y) ((x > y) ? x : y)$/
node      max.h     /^struct node {$/
For C/C++ programs only, the main tag object is preceded by “M”. This allows having source modules with separate main functions residing in the same directory.


This article has covered the use and structure of tag files. The example C project resides only in the present working directory. An obvious enhancement would be to support a project with a multiple directory structure. The file where the object is defined, column 2, supports a full search path:

func1      /usr/demo/lib/func1.c      \
   /^void func1(char *str)$/

About the Author

Ed Schaefer is a frequent contributor to Sys Admin. He is a senior programmer/analyst for Intel's Factory Information and Control System (IFICS) Group in Aloha, OR. His view points on tag files or any other subject in no way reflects Intel's position. He can be reached at: