1 Frequently Asked Questions
2 ==========================
4 * 1. Why do you call it "Exuberant Ctags"?
5 * 2. Why doesn't my editor work with these tag files?
6 * 3. What are these strange bits of text beginning with ;"?
7 * 4. Why doesn't XEmacs' Speedbar module work with Exuberant Ctags?
8 * 5. Why doesn't Xemacs correctly locate the tag in the source file?
9 * 6. Why doesn't NEdit correctly locate the tag in the source file?
10 * 7. Why can't I jump to "class::member"?
11 * 8. How can I avoid having to specify my favorite option every time?
12 * 9. Why do I end up on the wrong line when I jump to a tag?
13 * 10. How do I jump to the tag I want instead of the wrong one by the
16 * 12. How can I locate all references to a specific function or variable?
17 * 13. Why does appending tags to a tag file tag so long?
18 * 14. How do I get regex support for Win32?
19 * 15. How should I set up tag files for a multi-level directory hierarchy?
21 ----------------------------------------------------------------------
22 1. Why do you call it "Exuberant Ctags"?
24 Because one of the meanings of the word "exuberant" is:
26 exuberant : produced in extreme abundance : PLENTIFUL syn see PROFUSE
28 Compare the tag file produced by Exuberant Ctags with that produced by any
29 other ctags and you will see how appropriate the name is.
31 ----------------------------------------------------------------------
32 2. Why doesn't my editor work with these tag files?
34 3. What are these strange bits of text beginning with ;" which follow
35 many of the lines in the tag file?
37 These are "extension flags". They are added in order to provide extra
38 information about the tag that may be utilized by the editor in order to
39 more intelligently handle tags. They are appended to the EX command part of
40 the tag line in a manner that provides backwards compatibility with existing
41 implementations of the Vi editor. The semicolon is an EX command separator
42 and the double quote begins an EX comment. Thus, the extension flags appear
43 as an EX comment and should be ignored by the editor when it processes the
46 Some non-vi editors, however, implement only the bare minimum of EX commands
47 in order to process the search command or line number in the third field of
48 the tag file. If you encounter this problem, use the option "--format=1" to
49 generate a tag file without these extensions (remember that you can set the
50 CTAGS environment variable to any default arguments you wish to supply). Then
51 ask the supplier of your editor to implement handling of this feature of EX
54 ----------------------------------------------------------------------
55 4. Why doesn't XEmacs' Speedbar module work with Exuberant Ctags?
57 The default command line switches used by XEmacs for "etags" are not
58 compatible with Exuberant Ctags options. By default, Exuberant Ctags installs
59 a symbolic link, "etags", pointing to the ctags executable. When Exuberant
60 Ctags is started with the name "etags", it produces Emacs-style tag files by
63 To fix this, add the following lines to your .emacs file, replacing the path
64 to "etags" with the path where the symbolic link was installed.
66 (autoload 'speedbar "speedbar")
67 (setq speedbar-fetch-etags-command "/usr/local/bin/etags"
68 speedbar-fetch-etags-arguments '("-f" "-"))
70 ----------------------------------------------------------------------
71 5. Why doesn't Xemacs correctly locate the tag in the source file?
73 This has been observed with version 20.3. It seems that when Xemacs searches
74 for a tag, it searches using the tag name instead of the search string located
75 in the TAGS file. This is a bug in Xemacs and does not occur in the GNU
78 ----------------------------------------------------------------------
79 6. Why doesn't NEdit correctly locate the tag in the source file?
81 Versions of NEdit prior to 5.1 did not support the extended tag file format
82 generated by Exuberant Ctags by default. Either upgrade to version 5.1 or
83 specify the option "--format=1" when running ctags to output the old tag file
86 ----------------------------------------------------------------------
87 7. Why can't I jump to "class::member"?
89 Because, by default, ctags only generates tags for the separate identifiers
90 found in the source files. If you specify the --extra=+q option, then
91 ctags will also generate a second, class-qualified tag for each class member
92 (data and function/method) in the form class::member for C++, and in the form
93 class.method for Eiffel and Java.
95 ----------------------------------------------------------------------
96 8. How can I avoid having to specify my favorite option every time?
98 Either by setting the environment variable CTAGS to your custom
99 options, or putting them into a .ctags file in your home directory.
101 ----------------------------------------------------------------------
102 9. Why do I end up on the wrong line when I jump to a tag?
104 By default, ctags encodes the line number in the file where macro (#define)
105 tags are found. This was done to remain compatible with the original UNIX
106 version of ctags. If you change the file containing the tag without
107 rebuilding the tag file, the location of tag in the tag file may no longer
108 match the current location.
110 In order to avoid this problem, you can specify the option "--excmd=p",
111 which causes ctags to use a search pattern to locate macro tags. I have
112 never uncovered the reason why the original UNIX ctags used line numbers
113 exclusively for macro tags, but have so far resisted changing the default
114 behaviour of Exuberant Ctags to behave differently.
116 ----------------------------------------------------------------------
117 10. How do I jump to the tag I want instead of the wrong one by the
120 A tag file is simple a list of tag names and where to find them. If there
121 are duplicate entries, you often end up going to the wrong one because the
122 tag file is sorted and your editor locates the first one in the tag file.
124 Standard Vi provides no facilities to alter this behavior. However, Vim
125 has some nice features to minimize this problem, primarly by examining all
126 matches and choosing the best one under the circumstances. Vim also provides
127 commands which allow for selection of the desired matching tag.
129 ----------------------------------------------------------------------
132 Vim is a vi-compatible editor available as source and compilable for any
133 platform. Yeah, I know the first reaction is to shy away from this. But you
134 will never regret getting it, and you will become greatly attached to its
135 features, which you can learn gradually. I would be willing to say that it
136 is the best vi-clone available within 4 light-years of Alpha Centauri. It
137 works (nearly) exactly like standard vi, but provides some incredibly useful
138 extensions (some of which I have participated in designing with the author).
139 Most Linux distributions have adopted Vim as its standard vi.
141 ----------------------------------------------------------------------
142 12. How can I locate all references to a specific function or variable?
144 There are several packages already available which provide this capability.
145 Namely, these are: GLOBAL source code tag system, GNU id-utils, cscope,
146 and cflow. As of this writing, they can be found in the following locations:
148 GLOBAL: http://www.gnu.org/software/global
149 id-utils: http://www.gnu.org/software/idutils/idutils.html
150 cscope: http://cscope.sourceforge.net
151 cflow: ftp://www.ibiblio.org/pub/Linux/devel/lang/c
153 ----------------------------------------------------------------------
154 13. Why does appending tags to a tag file tag so long?
156 Sometimes, in an attempt to build a global tag file for all source files in
157 a large source tree of many directories, someone will make an attempt to run
158 ctags in append (-a) mode on every directory in the hierarchy. Each time
159 ctags is invoked, its default behavior is to sort the tag file once the tags
160 for that execution have been added. As the cumulative tag file grows, the sort
161 time increases arithmetically.
163 The best way to avoid this problem (and the most efficient) is to make
164 use of the --recurse (or -R) option of ctags by executing the following
165 command in the root of the directory hierarchy (thus running ctags only once):
169 If you really insist on running ctags separately on each directory, you can
170 avoid the sort pass each time by specifying the option "--sort=no". Once the
171 tag file is completely built, use the sort command to manually sort the
172 final tag file, or let the final invocation of ctags sort the file.
174 ----------------------------------------------------------------------
175 14. How do I get regex support for Win32?
177 You need to download the GNU regex package for Win32 from the following
180 http://people.delphiforums.com/gjc/gnu_regex.html
182 Then point the makefile macro, REGEX_DIR, found in mk_mvc.mak and mk_bc5.mak,
183 to the directory created by extracting this archive.
185 ----------------------------------------------------------------------
186 15. How should I set up tag files for a multi-level directory hierarchy?
188 There are a few ways of approaching this:
190 1. A local tag file in each directory containing only the tags for source
191 files in that directory.
193 2. One single big, global tag file present in the root directory of your
194 hierarchy, containing all tags present in all source files in the
197 3. A local tag file in each directory containing only the tags for source
198 files in that directory, in addition to one single global tag file
199 present in the root directory of your hierarchy, containing all
200 non-static tags present in all source files in the hierarchy.
202 4. A local tag file in each directory of the hierarchy, each one
203 containing all tags present in source files in that directory and all
204 non-static tags in every directory below it (note that this implies
205 also having one big tag file in the root directory of the hierarchy).
207 Each of these approaches has its own set of advantages and disadvantages,
208 depending upon your particular conditions. Which approach is deemed best
209 depends upon the following factors:
211 A. The ability of your editor to use multiple tag files.
213 If your editor cannot make use of multiple tag files (original vi
214 implementations could not), then one large tag file is the only way to
215 go if you ever desire to jump to tags located in other directories. If
216 you never need to jump to tags in another directory (i.e. the source
217 in each directory is entirely self-contained), then a local tag file
218 in each directory will fit your needs.
220 B. The time is takes for your editor to look up a tag in the tag file.
222 The significance of this factor depends upon the size of your source
223 tree and on whether the source files are located on a local or remote
224 file system. For source and tag files located on a local file system,
225 looking up a tag is not as big a hit as one might first imagine, since
226 vi implementations typically perform a binary search on a sorted tag
227 file. This may or may not be true for the editor you use. For files
228 located on a remote file system, reading a large file is an expensive
231 C. Whether or not you expect the source code to change and the time it
232 takes to rebuild a tag file to account for changes to the source code.
234 While Exuberant Ctags is particularly fast in scanning source code
235 (around 1-2 MB/sec), a large project may still result in objectionable
236 delays if one wishes to keep their tag file(s) up to date on a
237 frequent basis, or if the files are located on a remote file system.
239 D. The presence of duplicate tags in the source code and the ability to
242 The impact of this factor is influenced by the following three issues:
244 1. How common are duplicate tags in your project?
246 2. Does your editor provide any facilities for dealing with duplicate
249 While standard vi does not, many modern vi implementations, such
250 as Vim have good facilities for selecting the desired match from
251 the list of duplicates. If your editor does not support duplicate
252 tags, then it will typically send you to only one of them, whether
253 or not that is the one you wanted (and not even notifying you that
254 there are other potential matches).
256 3. What is the significance of duplicate tags?
258 For example, if you have two tags of the same name from entirely
259 isolated software components, jumping first to the match found
260 in component B while working in component A may be entirely
261 misleading, distracting or inconvenient (to keep having to choose
262 which one if your editor provides you with a list of matches).
263 However, if you have two tags of the same name for parallel builds
264 (say two initialization routines for different hosts), you may
265 always want to specify which one you want.
267 Of the approaches listed above, I tend to favor Approach 3. My editor of
268 choice is Vim, which provides a rich set of features for handling multiple
269 tag files, which partly influences my choice. If you are working with
270 source files on a remote file system, then I would recommend either
271 Approach 3 or Approach 4, depending upon the hit when reading the global
274 The advantages of Approach 3 are many (assuming that your editor has
275 the ability to support both multiple tag files and duplicate tags). All
276 lookups of tag located in the currect directory are fast and the local
277 tag file can be quickly and easily regenerated in one second or less
278 (I have even mapped a keystroke to do this easily). A lookup of a
279 (necessarily non-static) tag found in another directory fails a lookup in
280 the local tag file, but is found in the global tag file, which satisfies
281 all cross-directory lookups. The global tag file can be automatically
282 regenerated periodically with a cron job (and perhaps the local tag files
285 Now I give an example of how you would implement Approach 3. Means of
286 implementing the other approaches can be performed in a similar manner.
288 Here is a visual representation of an example directory hierarchy:
310 Here is a recommended solution (conceptually) to build the tag files:
312 1. Within each of the leaf nodes (i.e. hdrs, lib, src, test) build a tag
313 file using "ctags *.[ch]". This can be easily be done for the whole
314 hierarchy by making a shell script, call it "dirtags", containing the
321 Now execute the following command:
323 find * -type d -exec dirtags {} \;
325 These tag files are trivial (and extremely quick) to rebuild while
326 making changes within a directory. The following Vim key mapping is
327 quite useful to rebuild the tag file in the directory of the current
330 :nmap ,t :!(cd %:p:h;ctags *.[ch])&<CR><CR>
332 2. Build the global tag file:
335 ctags --file-scope=no -R
337 thus constructing a tag file containing only non-static tags for all
338 source files in all descendent directories.
340 3. Configure your editor to read the local tag file first, then consult
341 the global tag file when not found in the local tag file. In Vim,
342 this is done as follows:
344 :set tags=./tags,tags,~/project/tags
346 If you wish to implement Approach 4, you would need to replace the
347 "dirtags" script of step 1 with the following:
352 # Now append the non-static tags from descendent directories
353 find * -type d -prune -print | ctags -aR --file-scope=no -L-
355 And replace the configuration of step 3 with this:
357 :set tags=./tags,./../tags,./../../tags,./../../../tags,tags
359 As a caveat, it should be noted that step 2 builds a global tag file whose
360 file names will be relative to the directory in which the global tag file
361 is being built. This takes advantage of the Vim 'tagrelative' option,
362 which causes the path to be interpreted a relative to the location of the
363 tag file instead of the current directory. For standard vi, which always
364 interprets the paths as relative to the current directory, we need to
365 build the global tag file with absolute path names. This can be
366 accomplished by replacing step 2 with the following:
369 ctags --file-scope=no -R `pwd`