help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Smooth incremental GNU Global gtags behaviour from Emacs


From: per . nordlow
Subject: Smooth incremental GNU Global gtags behaviour from Emacs
Date: 7 Sep 2005 02:53:27 -0700
User-agent: G2/0.2

Hey there!

I am using the Emacs interface to the GNU GLOBAL source code tagging
system and it works mostly great for me. I am however a bit unsatisfied
with its ruff behaviour when doing incremental updates when a buffer is
saved into a file from Emacs. In order for it to work properly during
the development process I want the database to be updated every time I
save the buffer to a file. I have solved this in the following way:

(if (file-exists-p "~/.emacs.d/gtags.elc")
    (progn
      (autoload 'gtags-mode "gtags" "" t)

      (if (and (executable-find "global")
               (executable-find "gtags"))
          (progn

            (defadvice gtags-visit-rootdir (after make-complete-list activate)
              "Rebuilds completion list when changing GLOBAL database
rootdir."
              (gtags-make-complete-list))

            (defun is-gtags-dir (dir)
              "Return true if directory DIR contains a GLOBAL database."
              (and (file-exists-p (concat dir "GPATH"))
                   (file-exists-p (concat dir "GRTAGS"))
                   (file-exists-p (concat dir "GSYMS"))
                   (file-exists-p (concat dir "GTAGS"))))

            (defun find-super-gtags-dir ()
              "Return shallowest super-directory that contains a GLOBAL
database."
              (interactive)
              (cond ((is-gtags-dir (eval 'default-directory))
                     (eval 'default-directory))
                    ((is-gtags-dir (concat (eval 'default-directory) "../"))
                     (concat (eval 'default-directory) "../"))
                    ((is-gtags-dir (concat (eval 'default-directory) "../../"))
                     (concat (eval 'default-directory) "../../"))
                    ((is-gtags-dir (concat (eval 'default-directory) 
"../../../"))
                     (concat (eval 'default-directory) "../../../"))
                    ))

            (defvar
              gtags-complete-list-obselete-flag
              nil
              "Indicates that GLOBAL complete list should be rebuilt.")

            (defun if-gtags-update ()
              "If current directory is part of a GLOBAL database update it."
              (interactive)
              (let ((super-dir (find-super-gtags-dir)))
                (if (eval 'super-dir)
                    (progn
                      (call-process "global" nil nil nil "-vu")
                      (setq gtags-complete-list-obselete-flag t)
                      ))
                ))

            (defun check-gtags-complete-list-obslete-tag ()
              (interactive)
              (if gtags-complete-list-obselete-flag
                  (progn
                    (gtags-make-complete-list)
                    (setq gtags-complete-list-obselete-flag nil)
                    )))

            (defun save-buffer-and-update-global()
              "Save buffer and if needed update GLOBAL database."
              (interactive)
              (save-buffer) (if-gtags-update))

            (defun save-some-buffers-and-update-global()
              "Save some buffers and if needed update GLOBAL database."
              (interactive)
              (save-some-buffers) (if-gtags-update))

            (setq gtags-mode-hook
                  '(lambda ()
                     (global-set-key "\C-x\C-s"
                                     'save-buffer-and-update-global)
                     (global-set-key "\C-xs"
                                     'save-some-buffers-and-update-global)
                     (defadvice gtags-find-tag
                       (before check-gtags-completion activate)
                       (check-gtags-complete-list-obslete-tag))
                     (defadvice gtags-find-rtag
                       (before check-gtags-completion activate)
                       (check-gtags-complete-list-obslete-tag))
                     (defadvice gtags-find-symbol
                       (before check-gtags-completion activate)
                       (check-gtags-complete-list-obslete-tag))
                     (defadvice gtags-find-pattern
                       (before check-gtags-completion activate)
                       (check-gtags-complete-list-obslete-tag))
                     (defadvice gtags-find-with-grep
                       (before check-gtags-completion activate)
                       (check-gtags-complete-list-obslete-tag))
                     (defadvice gtags-find-with-idutils
                       (before check-gtags-completion activate)
                       (check-gtags-complete-list-obslete-tag))
                     (defadvice gtags-find-file
                       (before check-gtags-completion activate)
                       (check-gtags-complete-list-obslete-tag))
                     (defadvice gtags-parse-file
                       (before check-gtags-completion activate)
                       (check-gtags-complete-list-obslete-tag))
                     (defadvice gtags-find-tag-from-here
                       (before check-gtags-completion activate)
                       (check-gtags-complete-list-obslete-tag))
                     ))

            ;; Use gtags in all modes for now.
            (gtags-mode 1)
            )

        )
      )
  )

I have, however, a feeling that this is a bit complicated solution.
Does anyone have a better idea? If not, I still hope the code can be of
use to other uses of global from emacs.

Many thanks in advance,

Per Nordlöw



reply via email to

[Prev in Thread] Current Thread [Next in Thread]