The easiest way by far to generate a tags file recursively is with ‘ctags’ with its -R option for recursing into directories. See BuildTags for just basic information.


You want to eventually run something like:

ctags --languages=lisp -e -R -f TAGS-lisps

To see which files are picked up by that language do:

ctags --list-maps

You’ll see that ‘lisp’ picks up *.el files. Then in your .emacs file put:

(visit-tags-table "~/TAGS-lisps")

Better yet add a hook for lispy languages to load this tags file, when editing python or something else create a different TAGS file for that and selectively load that with another hook.

(mapc (lambda (mode)   
        (let ((hook (intern (concat (symbol-name mode)   
          (visit-tags-table "~/TAGS-lisps")
      '(emacs-lisp lisp inferior-lisp slime slime-repl))


 From: those who know me have no need of my name
 Subject: Re: etags help
 Date: 28 Jun 2001 01:13:39 GMT
 cd c:\source-root
 ctags [other-flags-if-any] -R *.hpp *.cpp *.h

If you want ETAGS output, remember to add the -e option, i.e.,

 ctags -e -R *.hpp *.cpp *.h


 From: Alexander
 Subject: Re: etags help
 Date: Wed, 27 Jun 2001 17:51:27 GMT

Here’s how to create a TagFile for an entire directory tree as posted on one of the EmacsNewsgroups:

 cd c:\source-root
 dir /b /s *.cpp *.h *.hpp | etags --your_options -

Older versions of etags

BuildTags describes how to combine find with etags to generate tags for a tree of files. But the 5.7 version of etags doesn’t have a ‘-’ option for reading on stdin. Use xargs instead, making sure that you pass --append to etags or it will overwrite the tags file for each file it gets from find.

 find . -name "*.cpp" -print -or -name "*.h" -print | xargs etags --append

auto-recursive functionality

This shell script will plough through a source tree and produce a tags file on standard output with GNU ‘etags’. (it mimics the exuberant ‘ctags’ recursive functionality):

 for src in `find . -type f`;
   case "${src}" in
           ${ETAGS} -o- "${src}";
           FTYPE=`file ${src}`;
           case "${FTYPE}" in
                   ${ETAGS} -o- "${src}";
                   if head -n1 "${src}" | grep '^#!' >/dev/null 2>&1;
                       ${ETAGS} -o- "${src}";