Last edit


< (when gtags-mode


> (when ggtags-mode


The GNU GLOBAL package is highly recommended for using a single tags file, covering all files in all subdirectories, that lives at the base of a source-code tree.

The package comes with gtags.el that integrates it seamlessly into Emacs.

In 2013, GNU ELPA included a package ggtags.el for integrating GNU Global with Emacs, which provides an intuitive UI for navigating between multiple matches along with many other features. Check the project page for full feature list.

Cycling through GNU Global result

The gtags.el package doesn’t cycle through gtags result. Here’s some code for doing it. CyclingGTagsResult

GNU GLOBAL incremental update

It’s possible to use GNU GLOBAL incremental update feature in after-save-hook in order to keep synchronized the changes you made in source code and gtags database:

  (defun gtags-root-dir ()
    "Returns GTAGS root directory or nil if doesn't exist."
      (if (zerop (call-process "global" nil t nil "-pr"))
          (buffer-substring (point-min) (1- (point-max)))
  (defun gtags-update ()
    "Make GTAGS incremental update"
    (call-process "global" nil nil nil "-u"))
  (defun gtags-update-hook ()
    (when (gtags-root-dir)
  (add-hook 'after-save-hook #'gtags-update-hook)

GNU GLOBAL update for a single file

For projects with a huge amount of files, “global -u” can take a very long time to complete. For changes in a single file, we can update the tags with “gtags --single-update” and do it in the background:

    (defun gtags-update-single(filename)  
      "Update Gtags database for changes in a single file"
      (start-process "update-gtags" "update-gtags" "bash" "-c" (concat "cd " (gtags-root-dir) " ; gtags --single-update " filename )))
    (defun gtags-update-current-file()
      (defvar filename)
      (setq filename (replace-regexp-in-string (gtags-root-dir) "." (buffer-file-name (current-buffer))))
      (gtags-update-single filename)
      (message "Gtags updated for %s" filename))
    (defun gtags-update-hook()
      "Update GTAGS file incrementally upon saving a file"
      (when ggtags-mode
        (when (gtags-root-dir)
    (add-hook 'after-save-hook 'gtags-update-hook)

Alternative interface to GNU GLOBAL

If, for whatever reasons, you do not feel comfortable with the interface gtags.el provides, you might try xgtags.el instead. Since its look and feel is more like that of xcscope.el, it differs from gtags.el in several ways:

while using xgtags.el, if you have spaces in the path for sources, you may want to consider to change xgtags--tag-regexp likecedet

(defconst xgtags--file-regexp "\\([^ \t]+\\)[ \t]+\\([0-9]+\\)[ \t]+\\(.*\\.\\(cpp\\|hpp\\|h\\|c\\|idl\\)\\)[ \t]+\\(.+\\)$" "...")

Lisp:anything-gtags.el is Anything interface. See also AnythingApplications. – rubikitch

CEDET (CollectionOfEmacsDevelopmentEnvironmentTools) supports the use of GNU Global as a back-end to some tasks. They include:

  • EDE Locate - Helps EDE find files in your project, like header files.
  • SemanticBovinator Symref backend, for finding symbol usages.
  • Semantic Database backend, for finding tags by name.

Yet another interface to GNU GLOBAL

GNU Global has a cscope-compatibility utility called “gtags-cscope”. This tool has an identical interface to cscope, so any cscope interface can be used with it. Look at “xcscope.el”, which is on MELPA and in Debian and in Ubuntu. The source is here: To use this interface, do (setq cscope-program “gtags-cscope”). This interface has superior support for keeping track of multiple searches, and it’s the best of the bunch, I think.

Comment: would be interesting to see why xcscope.el is the best of the bunch. ggtags.el was created fairly recently out of frustration with all interfaces to gnu global. At the time they usually lacked one thing or another, or difficult to extend. – Leo

CategoryProgrammerUtils CategoryExternalUtilities CategoryCompletion CategoryNavigation