ctags is a program that generates a file containing a
dictionary matching C identifiers (and other things, e.g. macros)
to source files/lines. It's very useful for browsing source code
and support for it is integrated into editors like vi, Vim and
emacs. See man ctags etc. for a more thorough
explanation.
You do this with an external program (i.e. not with your editor).
On my system there are at least five different programs for generating tags files:
They all seem to be different binaries. They differ in the support they provide for languages other than C, some are intended for emacs rather than vi and so on.
I haven't tried all combinations, but on my system (SUSE 9.1) ctags works well with C and Vim, and etags works well with C and XEmacs. ctags -e usually works OK for C and XEmacs.
There are lots of different ways to do this. The one I usually use is this (for C and Vim):
$ cd my_project
$ ctags -R --tag-relative -f ~/tags *
$ cd /usr/local/some_package
$ ctags -R -a --tag-relative -f ~/tags *
This keeps all the tags in one file ~/tags, which works regardless
of the editor's current working directory. This avoids a lot of
confusion, and works well for me because the way I use Vim involves
changing directory often. First we're building the tags for the
project we're working on, and then using the -a option
to append tags for some package we may be using and wish to browse
the source code of. Obviously we can add a few more packages with
a few more invocations of ctags still using
-a (append
) until we've built up a tags file
with everything in it we want. It's often worth encapsulating all
this in a script somewhere so it's easy to rebuild the tags when
the sources have changed a lot and it's getting out of date.
-R means recursive
(go into subdirs), and
--tag-relative is what makes the tags file work
regardless of the current working directory of the editor's
environment. By using -e as well as those other
options, you can make a tags file suitable for XEmacs.
Non-GNU versions of ctags (e.g. on Solaris systems) may not have
-R or --tag-relative options. In that
case, use find in place of -R to retrieve
all the files, and pass them to ctags as absolute
paths:
$ find `pwd` -type f | xargs ctags -f ~/tags
By using `pwd` instead of . to mean the
current directory
we list filenames with absolute paths to go
in the ~/tags file. This has the same effect as
--tag-relative-- the tags file will work regardless of the
editor's working directory.
ctags might not always work as well for XEmacs as
etags. Unfortunately etags has a completely
different syntax from ctags… On my system, the
etags equivalent of the above sequence of
ctags commands is:
$ cd my_project
$ rm -f ~/tags
$ find `pwd` -type f -name '*.[hc]' | xargs etags -a -o ~/tags
$ cd /usr/local/some_package
$ find `pwd` -type f -name '*.[hc]' | xargs etags -a -o ~/tags
Note also that because we are invoking etags with
xargs, we use etags in append
mode
always. This is because if the argument list is very long
(which in this case it is quite likely to be), xargs
may invoke etags more than once with different
sections of the argument list. We want the
subsequent invocations to append, or we'll only end up with tags
for last section.
:set tags+=~/tags
Type :help tags for more information.
Add this line to ~/.xemacs/custom.el:
(setq tag-table-alist '(("" . "~/tags")))
Type C-h v tag-table-alist for more information.
These are the most important tag commands:
| Command | XEmacs/GNU Emacs | Vim |
|---|---|---|
| Jump to tag | M-. | CTRL-] |
| Jump back | M-* | CTRL-T |
| Next matching tag | M-, | :tn |
| Previous matching tag | ? | :tp |
| Find by name | M-x find-tag | :tag |