unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
* Smooth incremental GNU Global gtags behaviour from Emacs
@ 2005-09-07  9:53 per.nordlow
  2005-09-07 20:11 ` Kevin Rodgers
  0 siblings, 1 reply; 2+ messages in thread
From: per.nordlow @ 2005-09-07  9:53 UTC (permalink / raw)


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

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Smooth incremental GNU Global gtags behaviour from Emacs
  2005-09-07  9:53 Smooth incremental GNU Global gtags behaviour from Emacs per.nordlow
@ 2005-09-07 20:11 ` Kevin Rodgers
  0 siblings, 0 replies; 2+ messages in thread
From: Kevin Rodgers @ 2005-09-07 20:11 UTC (permalink / raw)


per.nordlow@gmail.com wrote:
 > 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:
...
 > 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.

I can't critique the overall approach, but I think it could be improved
in minor ways (like using after-save-hook instead of rebinding C-x C-s):

(when (locate-library "gtags")

   (autoload 'gtags-mode "gtags" nil t)

   (when (executable-find "global")

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

     (defun gtags-global-dir-p (dir)
       "Return non-nil if directory DIR contains a GLOBAL database."
       (and (file-exists-p (expand-file-name "GPATH" dir))
            (file-exists-p (expand-file-name "GRTAGS" dir))
            (file-exists-p (expand-file-name "GSYMS" dir))
            (file-exists-p (expand-file-name "GTAGS" dir))))

     (defun gtags-global-dir (&optional dir)
       "Return the nearest super directory that contains a GLOBAL database."
       (interactive)
       (when (null dir)
         (setq dir default-directory))
       (cond ((gtags-global-dir-p dir) dir)
             ((equal (file-truename dir) (file-truename "/")) nil)
             (t (gtags-global-dir (file-name-as-directory
                                   (expand-file-name ".." dir))))))

     (defvar gtags-global-complete-list-obsolete-flag nil
       "When non-nil, the GLOBAL complete list should be rebuilt.")

     (defun gtags-global-update ()
       "If current directory is part of a GLOBAL database update it."
       (interactive)
       (when (gtags-global-dir)
         (if (equal (call-process "global" nil nil nil "-vu") 0)
             (setq gtags-global-complete-list-obsolete-flag t)
           (error "global database update failed"))))

     (defun gtags-global-complete-list-maybe ()
       "Rebuild the GLOBAL complete list when indicated.
See `gtags-global-complete-list-obsolete-flag'."
       (interactive)
       (when gtags-global-complete-list-obsolete-flag
         (gtags-make-complete-list)
         (setq gtags-global-complete-list-obsolete-flag nil)))

     (add-hook 'gtags-mode-hook
               (lambda ()
                 (add-hook 'after-save-hook 'gtags-global-update nil t)
                 (defadvice gtags-find-tag
                   (before gtags-global-complete-list-maybe activate)
                   (gtags-global-complete-list-maybe))
                 (defadvice gtags-find-rtag
                   (before gtags-global-complete-list-maybe activate)
                   (gtags-global-complete-list-maybe))
                 (defadvice gtags-find-symbol
                   (before gtags-global-complete-list-maybe activate)
                   (gtags-global-complete-list-maybe))
                 (defadvice gtags-find-pattern
                   (before gtags-global-complete-list-maybe activate)
                   (gtags-global-complete-list-maybe))
                 (defadvice gtags-find-with-grep
                   (before gtags-global-complete-list-maybe activate)
                   (gtags-global-complete-list-maybe))
                 (defadvice gtags-find-with-idutils
                   (before gtags-global-complete-list-maybe activate)
                   (gtags-global-complete-list-maybe))
                 (defadvice gtags-find-file
                   (before gtags-global-complete-list-maybe activate)
                   (gtags-global-complete-list-maybe))
                 (defadvice gtags-parse-file
                   (before gtags-global-complete-list-maybe activate)
                   (gtags-global-complete-list-maybe))
                 (defadvice gtags-find-tag-from-here
                   (before gtags-global-complete-list-maybe activate)
                   (gtags-global-complete-list-maybe))
                 )                       ; (lambda () ...)
               )                        ; (add-hook 'gtags-mode-hook ...)
     )                            ; (when (executable-find "global") ...)

   ;; Use gtags in all modes for now.
   (gtags-mode 1)
   )                                ; (when (locate-library "gtags") ...)

-- 
Kevin Rodgers

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2005-09-07 20:11 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-07  9:53 Smooth incremental GNU Global gtags behaviour from Emacs per.nordlow
2005-09-07 20:11 ` Kevin Rodgers

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).