]> code.delx.au - gnu-emacs-elpa/blobdiff - packages/ggtags/ggtags.el
Merge branch 'master' of github.com:leoliu/ggtags
[gnu-emacs-elpa] / packages / ggtags / ggtags.el
index efbab00f5b892961ea20fcd631b4696cf21fdcb7..52081c92019255b301c12d239ca64f26696e784e 100644 (file)
@@ -3,7 +3,7 @@
 ;; Copyright (C) 2013-2014  Free Software Foundation, Inc.
 
 ;; Author: Leo Liu <sdl.web@gmail.com>
-;; Version: 0.8.7
+;; Version: 0.8.8
 ;; Keywords: tools, convenience
 ;; Created: 2013-01-29
 ;; URL: https://github.com/leoliu/ggtags
 ;;
 ;; All commands are available from the `Ggtags' menu in `ggtags-mode'.
 
-;;; NEWS 0.8.7 (2014-11-10):
+;;; NEWS 0.8.8 (2014-12-03):
 
-;; - New navigation command `ggtags-navigation-start-file'.
-;; - New variable `ggtags-use-sqlite3' to enable sqlite3 storage.
+;; - Command `ggtags-update-tags' now runs in the background for large
+;;   projects (per `ggtags-oversize-limit') without blocking emacs.
 ;;
 ;; See full NEWS on https://github.com/leoliu/ggtags#news
 
@@ -654,8 +654,11 @@ Value is new modtime if updated."
   (when (ggtags-find-project)
     (with-temp-buffer
       (ggtags-with-current-project
-        (process-file (ggtags-program-path "global") nil t nil
-                      "-vP" (concat "^" (ggtags-project-relative-file file) "$")))
+        ;; NOTE: `process-file' requires all files in ARGS be relative
+        ;; to `default-directory'; see its doc string for details.
+        (let ((default-directory (ggtags-current-project-root)))
+          (process-file (ggtags-program-path "global") nil t nil
+                        "-vP" (concat "^" (ggtags-project-relative-file file) "$"))))
       (goto-char (point-min))
       (not (re-search-forward "^file not found" nil t)))))
 
@@ -714,20 +717,38 @@ source trees. See Info node `(global)gtags' for details."
 
 (defun ggtags-update-tags (&optional force)
   "Update GNU Global tag database.
-Do nothing if GTAGS exceeds the oversize limit unless FORCE."
+Do nothing if GTAGS exceeds the oversize limit unless FORCE.
+
+When called interactively on large (per `ggtags-oversize-limit'
+projects, the update process runs in the background without
+blocking emacs."
   (interactive (progn
                  (ggtags-check-project)
                  ;; Mark project info expired.
                  (setf (ggtags-project-timestamp (ggtags-find-project)) -1)
-                 (list t)))
-  (when (or force (and (ggtags-find-project)
-                       (not (ggtags-project-oversize-p))
-                       (ggtags-project-dirty-p (ggtags-find-project))))
-    (ggtags-with-current-project
-      (ggtags-with-temp-message "`global -u' in progress..."
-        (ggtags-process-string "global" "-u")
-        (setf (ggtags-project-dirty-p (ggtags-find-project)) nil)
-        (setf (ggtags-project-mtime (ggtags-find-project)) (float-time))))))
+                 (list 'interactive)))
+  (cond ((and (eq force 'interactive) (ggtags-project-oversize-p))
+         (ggtags-with-current-project
+           (with-display-buffer-no-window
+             (with-current-buffer (compilation-start "global -u")
+               ;; A hack to fool compilation mode to display `global
+               ;; -u finished' on finish.
+               (setq mode-name "global -u")
+               (add-hook 'compilation-finish-functions
+                         #'ggtags-update-tags-finish nil t)))))
+        ((or force (and (ggtags-find-project)
+                        (not (ggtags-project-oversize-p))
+                        (ggtags-project-dirty-p (ggtags-find-project))))
+         (ggtags-with-current-project
+           (ggtags-with-temp-message "`global -u' in progress..."
+             (ggtags-process-string "global" "-u")
+             (ggtags-update-tags-finish))))))
+
+(defun ggtags-update-tags-finish (&optional buf how)
+  (if (and how buf (string-prefix-p "exited abnormally" how))
+      (display-buffer buf)
+    (setf (ggtags-project-dirty-p (ggtags-find-project)) nil)
+    (setf (ggtags-project-mtime (ggtags-find-project)) (float-time))))
 
 (defun ggtags-update-tags-single (file &optional nowait)
   ;; NOTE: NOWAIT is ignored if file is remote file; see
@@ -735,8 +756,10 @@ Do nothing if GTAGS exceeds the oversize limit unless FORCE."
   (cl-check-type file string)
   (let ((nowait (unless (file-remote-p file) nowait)))
     (ggtags-with-current-project
-      (process-file (ggtags-program-path "global") nil (and nowait 0) nil
-                    "--single-update" (ggtags-project-relative-file file)))))
+      ;; See comment in `ggtags-project-file-p'.
+      (let ((default-directory (ggtags-current-project-root)))
+        (process-file (ggtags-program-path "global") nil (and nowait 0) nil
+                      "--single-update" (ggtags-project-relative-file file))))))
 
 (defun ggtags-delete-tags ()
   "Delete file GTAGS, GRTAGS, GPATH, ID etc. generated by gtags."