ctags etags gtags: How to Find Where a Function is Defined or Called?

By Xah Lee. Date:

if you work with a project new to you, that has tens of files or more in nested directories, you'll need this.

How do you quickly find where a function is called, or where a function is defined?

the classic tool for this is ctags. Basically, ctags is a shell command. Run it to create a index file, then you can use command to quickly jump to a identifier (function)'s definition.

(using grep is much slower, because everytime it needs to search all the files. That's why ctags creates a index files first, which is basically the one-shot search result of all function names.)

ctags index file is named tags.

The index file has a simple format, like this:

{tagname}␉{tagfile}␉{tagaddress}

The fields are specified as follows:

Variations: ctags, etags, gtags (GNU Global)

There are many improvements of the ctags tool. They include:

The index file format are similar or compatible with ctags.

GNU Global home page is at: http://www.gnu.org/software/global/

Install gtags on Ubuntu Linux

# install gnu global
sudo apt-get install global

After intall, you have 2 commands:

See man gtags and man global

See the official gtags tutorial at http://www.gnu.org/software/global/globaldoc_toc.html

how to make etags Index Clojure Files?

there's this regex from http://nakkaya.com/2009/12/13/getting-etags-to-index-clojure-files/ and http://stackoverflow.com/questions/1481842/clojure-emacs-etags

find . \! -name '.*' -name '*.clj' | xargs etags --regex='/[ \t\(]*def[a-zA-Z!$%&*+\-.\/:<=>?@^_~]*[ \n\t]+\(\^{[^}]*}[ \n\t]+\|\)\([a-zA-Z!$%&*+\-.\/:<=>?@^_~]+\)/\2/s' --regex='/[ \t\(]*ns \([a-z.]+\)/\1/'

but it doesn't work for me

for now, just use emacs rgrep. 〔➤see Emacs: Searching for Text in Files (grep, find)

or use this emacs command, which calls git grep.

(defvar gitgrep-history nil)

(defun gitgrep (*search-string)
"call git grep to search symbols in a project.

2014-11-19 by “Left Right” https://plus.google.com/113859563190964307534/posts/CyEsoyhkTVe
"
  (interactive
   (let ((-sym (thing-at-point 'symbol)))
     (list
      (completing-read
       "String to search for: "
       (list -sym
             (buffer-name)
             (buffer-file-name))
       'identity nil -sym gitgrep-history -sym))))
  (grep (format "git --no-pager grep -P -n '%s'" *search-string)))