Frequently Asked Questions
==========================

Q:  Why is the program called "Exuberant" ctags?

A:  Because one of the meanings of the word "exuberant" is:

      exuberant : produced in extreme abundance : PLENTIFUL syn see PROFUSE

    Compare the tag file produced by Exuberant Ctags with that produced by any
    other ctags and you will see how appropriate the name is.

--
Q:  Why doesn't my editor work with the tag files generated by Exuberant
    Ctags, even though it is supposed to support tag files?

A:  Because your non-vi-based editor does not have sufficient support for EX
    commands to ignore the extensions of the new tag file format. You can
    disable these extensions using the option --format=1.

--
Q:  I always use a particular option but don't want to have to specify it
    every time I run ctags. How can I avoid this?

A:  By setting the environment variable CTAGS to your custom options.

--
Q:  I have several static functions or variables of the same name in different
    modules. When I put my cursor on a reference to one of them and try to
    jump to this tag, it takes me to the wrong one. Why?

A:  A tag file is simple a list of tag names and where to find them. If there
    are duplicate entries, you often end up going to the wrong one because
    the tag file is sorted and your editor locates the first one in the tag
    file.
    
--
Q:  How can I jump to the correct tag when the same tag appears more than
    once in the tag file?

A:  Standard Vi provides no facilities to improve this behavior. However, Vim
    has some nice features to minimize this problem, primarly by examining all
    matches and choosing the best one under the circumstances. Currently,
    there is work in progress to allow Vim to allow the user to control which
    tag match is used.

--
Q:  What is "Vim"?

A:  Vim is a vi-compatible editor available as source and compilable for any
    platform. Yeah, I know the first reaction is to shy away from this. But
    you will never regret getting it, and you will become greatly attached to
    its features, which you can learn gradually. I would be willing to say
    that it is the best vi-clone available within 4 light-years of Alpha
    Centauri. It works (nearly) exactly like standard vi, but provides some
    incredibly useful extensions (some of which I have participated in
    designing with the author). The RedHat Linux distribution has adopted Vim
    as its standard vi. And, hey!, it comes bundled with Exuberant Ctags!

--
Q:  How can I locate calls to a specific function or references to a
    specific variable?

A:  There are several packages already available which provide this
    capability. Namely, these are: the GNU id-utils package, cscope (a
    commercial package), cs (a cscope work-alike), cflow. As of this writing,
    they can be found in the following locations:

    id-utils:  ftp://ftp.gnu.ai.mit.edu/pub/gnu/id-utils-3.2.tar.gz
    cflow:     ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/cflow-2.0.tar.gz
    cs:        ftp://cantor.informatik.rwth-aachen.de/pub/unix/cs-0.4.tar.gz

--
Q:  I have source files in many directories and use the --append option to
    append tags for each directory to one tag big tag file. Why does it take
    so long?

A:  Because each time ctags is invoked, its default behavior is to sort the
    tag file once the tags for that pass have been added. As the cumulative
    tag file grows, the sort time continually increases. In order to avoid
    these unnecessary sorts, provide the option "--sort=no" to each invocation
    of ctags. Once the tag file is completely built, use the sort command to
    manually sort the final tag file, or let the final invocation of ctags
    sort the file.

--
Q:  Why is it that sometimes when I jump to the definition for a
    preprocessor define, I do not end up at the right line for the
    definition?

A:  By default, ctags encodes the line number in the file where macro
    (#define) tags are found. This was done to remain compatible with the
    original UNIX version of ctags. If you change the file containing the tag
    without rebuilding the tag file, the location of tag in the tag file may
    no longer match the current location.

    In order to avoid this problem, you can specify the option "--excmd=p",
    which causes ctags to use a search pattern to locate macro tags. I have
    never uncovered the reason why the original UNIX ctags used line numbers
    exclusively for macro tags, but have so far resisted changing the default
    behaviour of Exuberant Ctags to work differently.

--
Q:  What are these strange bits of text beginning with ;" which follow many of
    the lines in the tag file? My editor will not find my tags because it does
    not like the search patterns.

    These are "extension flags". They are intended to provide extra
    information about the tag that may be utilized by the editor in order to
    more intelligently handle tags. They are appended to the EX command part
    of the tag line in a manner that provides backwards compatibility with
    existing implementations of the Vi editor. The semicolon is an EX command
    separator and the double quote begins an EX comment. Thus, the extension
    flags appear as an EX comment and should be ignored by the editor when it
    processes the EX command.

    Some non-vi editors, however, implement only the bare minimum of EX
    commands in order to process the search command or line number in the
    third field of the tag file. If you encounter this problem, use the option
    "--format=1" to generate a tag file without these extensions (remember
    that you can set the CFLAGS environment to any default arguments you wish
    to supply). Then ask the supplier of your editor to implement handling
    of this feature of EX commands.

--
Q:  How do I set up a tag file for source files in different directories.
    Does the ctags file have to be in each source directory, or do
    I make one monster tag file for a large multi-directory project?

A:  You can do either. With Vim, your choices are even better!

    Ctags creates the file paths in the tag file with whatever pathnames are
    supplied on the command line (relative or absolute). This is important to
    either vi or vim, as we shall see.

    Consider the following directory structure:

                    src
               ------+-----
              |            |
             libs        apps
          ----------       file1.c
         |          |
        io         misc
	             file2.c

    Standard vi
    -----------
    Standard vi allows you to set the path to the tag file via ":set tag=...",
    which allows you to specify one tag file. So for a directory structure
    like this:

    You could create a separate, local tag file in each directory (e.g.
    execute "ctags *.[ch] in each child directory) which contains only the
    tags for that directory and do ":set tags=tags" (default) which would use
    the local tag file whenever you were in one of the child directories. The
    disadvantage is that if you were in the applications directory and wanted
    to go jump to a tag defined in, say, the libs directory, this would not be
    possible.

    Alternatively you could execute "ctags `pwd`/*/*.[ch]" in the "src"
    directory, (or "ctags -f ../tags ../*/*.[ch]" from one of the child
    directories) which would create one large tag file with pathnames which
    could be located as seen from the child directories. Within vi you would
    set ":set tags=..tags". This method has the advantage that all tags may be
    found in the common tag file and jumping to any tag is easy. This
    disadvantages could be the size of the tag file, the time to search it
    when jumping to a tag and the overhead of rebuilding the tag file as the
    sources change.

    Vim
    ---
    Here many facilities make this process much, much easier. I know, since I
    was the one who provided most of the tag suggestions and tag search
    algorithms which are used in Vim. Vim provides four key features:

    1.  Multiple tag files may be given in the "tag" option, each one being
	searched until the tag is located. This allows a local tag file
	containing all tags (global and static) for the current directory and
	a global tag file containing only those tags which are called outside
	of a directory.

    2.  File locations may be specified (via the "tagrelative" option) to be
	relative to the location of the tag file rather than the current
	directory.

    3.  Tag files may be specified to be found relative to the current file
	rather than the current directory or absolutely.

    4.  The tag search algorithm does not stop at the first instance of a
	selected tag in the tag file, but keeps searching until (1) a matching
	tag is found for the current file (2) a non-static tag is found for
	another file or (3) a static tag is found for another file.

    This provides very powerful methods, particularly when combined with my
    ctags. Given the above example, here is what I would do with my ctags:

    - In each child directory, execute "ctags *.[ch]" to create a local tag
      file with paths relative to the local tag file.

    - In the "src" directory, execute "ctags -i-S */*.[ch]" (creates
      non-static tags for the child directories with paths relative to the
      location of the tag global file).

    - In vim, ":set tagrelative" (to make file locations relative to the
      location of the tag file in which the tag is found) and (for example)
      ":set tags=./tags,tags,./../tags,./../../tags,$src/tags,/usr/include/tags"
      (the "./" prefix is special, meaning that that path is relative to the
      directory of the current file, rather than the current directory). The
      "./tags" is not in general redundant with "tags", because "./tags" has
      no meaning if you do not already have a file in a buffer (e.g. "vim -t
      mytag").

    Using these examples will cause Vim to do the following when you "tag"
    (i.e. ^], :ta, etc.) on a function or other object:

    1.  Search for the tag in the tag file located in the directory containing
	the current file.
    2.  If not found, search the tag file in the current directory (this is
	needed in addition to step 1 in case we do "vi -t some_tag", because
	there is no "current" file to find the tag file relative to).
    3.  If not found, search the tag file one directory up from the directory of
	the current file.
    4.  If not found, search the tag file two directories up from the directory
	of the current file.
    5.  If not found, search the tag file located at the directory indicated
	by the environment variable "src" (which we might set equal to the
	absolute path to the "src" directory).
    6.  If not found, search the tag file located in /usr/include (this is
	great to build with "-ip --excmd=n" to get the prototypes and use line
	numbers, thus making this tag file smaller).

    Suppose I am currently in the source/apps directory and tag on a function
    found in source/libs/misc. Step 3 would find the tag and go to it.

    Suppose I then tag on another function found in the source/libs/misc
    directory. Step 1 would find it.

    Suppose I then tag on a function found in the source/libs/io directory.
    Step 3 would find it.
    The following example demonstrates the advantages of this approach.

    %cd apps
    %vim file1.c

    A jump to a local tag searches ./tags for the tag, finds a matching tag
    for the current file, then jumps to it.

    A jump to an external flag, found in src/tags, searches the local tag
    file ("./tags", which is in the directory of the current file, the local
    directory), fails to find it, skips the "tags" file, since it was already
    searched, searches the global tag file ("../tags") and finds the tag and
    jumps to the file libs/misc/file2.c, relative to the global tag file.

    Now we are in file ../libs/misc/file2.c. If we jump to a tag which is
    found in the libs directory, first the tags file of the current file is
    searched ("./tags"), the tag is found and the file is found relative to
    that tag file and we are there.

    Local tag files are generally small and searched very fast. The global tag
    file is kept smaller since tags which are not global are omitted, allowing
    searches in it to kept shorter.

    You will find that this solution is like a dream. I have tried it the old
    way with standard vi and this is nothing but a pain and with the size of
    your project, you have probably found that the time to lookup a tag is
    significant.

    There are many variations on these ideas which enhance it further. You
    will have fun tuning it to your specific circumstances.
