]> 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 0f822a3e6b610a539862e7eb5861b32c4e473343..f01400cfa6133026c1199bc63e9898a61a6aa5c3 100644 (file)
@@ -3,7 +3,7 @@
 ;; Copyright (C) 2013  Free Software Foundation, Inc.
 
 ;; Author: Leo Liu <sdl.web@gmail.com>
-;; Version: 0.7.6
+;; Version: 0.7.7
 ;; Keywords: tools, convenience
 ;; Created: 2013-01-29
 ;; URL: https://github.com/leoliu/ggtags
@@ -189,6 +189,12 @@ properly update `ggtags-mode-map'."
   :type 'key-sequence
   :group 'ggtags)
 
+(defcustom ggtags-enable-completion-at-point t
+  "Non-nil to enable completion at point using the tag table."
+  :safe 'booleanp
+  :type 'boolean
+  :group 'ggtags)
+
 (defcustom ggtags-completing-read-function completing-read-function
   "Ggtags specific `completing-read-function' (which see)."
   :type 'function
@@ -354,6 +360,13 @@ properly update `ggtags-mode-map'."
 (defun ggtags-check-project ()
   (or (ggtags-find-project) (error "File GTAGS not found")))
 
+(defun ggtags-ensure-project ()
+  (or (ggtags-find-project)
+      (when (or (yes-or-no-p "File GTAGS not found; run gtags? ")
+                (user-error "Aborted"))
+        (call-interactively #'ggtags-create-tags)
+        (ggtags-find-project))))
+
 (defun ggtags-save-project-settings (&optional noconfirm)
   "Save Gnu Global's specific environment variables."
   (interactive "P")
@@ -406,26 +419,23 @@ properly update `ggtags-mode-map'."
       (message "Project read-only-mode is %s" (if val "on" "off")))
     val))
 
-(defun ggtags-ensure-project ()
-  (interactive)
-  (or (ggtags-find-project)
-      (when (or (yes-or-no-p "File GTAGS not found; run gtags? ")
-                (user-error "Aborted"))
-        (let ((root (read-directory-name "Directory: " nil nil t))
-              (process-environment process-environment))
-          (and (zerop (length root)) (user-error "No directory chosen"))
-          (setenv "GTAGSROOT"
-                  (directory-file-name (file-name-as-directory root)))
-          (ggtags-with-process-environment
-           (and (not (getenv "GTAGSLABEL"))
-                (yes-or-no-p "Use `ctags' backend? ")
-                (setenv "GTAGSLABEL" "ctags"))
-           (with-temp-message "`gtags' in progress..."
-             (let ((default-directory (file-name-as-directory root)))
-               (apply #'ggtags-process-string
-                      "gtags" (and ggtags-use-idutils '("--idutils"))))))
-          (message "GTAGS generated in `%s'" root)
-          (ggtags-find-project)))))
+(defun ggtags-create-tags (root)
+  "Run `gtags' in directory ROOT to create tag files."
+  (interactive "DRoot directory: ")
+  (let ((process-environment process-environment))
+    (when (zerop (length root)) (error "No root directory provided"))
+    (setenv "GTAGSROOT"
+            (directory-file-name (file-name-as-directory root)))
+    (ggtags-with-process-environment
+     (and (not (getenv "GTAGSLABEL"))
+          (yes-or-no-p "Use `ctags' backend? ")
+          (setenv "GTAGSLABEL" "ctags"))
+     (with-temp-message "`gtags' in progress..."
+       (let ((default-directory (file-name-as-directory root)))
+         (apply #'ggtags-process-string
+                "gtags" (and ggtags-use-idutils '("--idutils"))))))
+    (message "GTAGS generated in `%s'" root)
+    root))
 
 (defun ggtags-update-tags (&optional force)
   "Update GNU Global tag database.
@@ -459,6 +469,12 @@ non-nil."
                      "\n" t)))))
      (cdr ggtags-completion-cache))))
 
+(defun ggtags-completion-at-point ()
+  "A function for `completion-at-point-functions'."
+  (when-let (bounds (funcall ggtags-bounds-of-tag-function))
+    (and (< (car bounds) (cdr bounds))
+         (list (car bounds) (cdr bounds) ggtags-completion-table))))
+
 (defun ggtags-read-tag ()
   (ggtags-ensure-project)
   (let ((default (ggtags-tag-at-point))
@@ -509,7 +525,15 @@ non-nil."
 
 (defun ggtags-global-start (command &optional root)
   (let* ((default-directory (or root (ggtags-current-project-root)))
-         (split-window-preferred-function ggtags-split-window-function))
+         (split-window-preferred-function ggtags-split-window-function)
+         ;; See http://debbugs.gnu.org/13594
+         (display-buffer-overriding-action
+          (if (not ggtags-auto-jump-to-first-match)
+              display-buffer-overriding-action
+            (cons (lambda (buf _action)
+                    (with-current-buffer buf
+                      (derived-mode-p 'ggtags-global-mode)))
+                  (list #'display-buffer-no-window)))))
     (setq ggtags-global-start-marker (point-marker))
     (ggtags-navigation-mode +1)
     (setq ggtags-global-exit-status 0
@@ -647,8 +671,10 @@ Global and Emacs."
   "Delete the tag files generated by gtags."
   (interactive)
   (when (ggtags-current-project-root)
-    (let ((files (directory-files (ggtags-current-project-root) t
-                                  (regexp-opt '("GPATH" "GRTAGS" "GTAGS" "ID"))))
+    (let ((files (directory-files
+                  (ggtags-current-project-root) t
+                  (concat "\\`" (regexp-opt '("GPATH" "GRTAGS" "GTAGS" "ID"))
+                          "\\'")))
           (buffer "*GTags File List*"))
       (or files (user-error "No tag files found"))
       (with-output-to-temp-buffer buffer
@@ -881,14 +907,23 @@ Global and Emacs."
 
 (defun ggtags-global-filter ()
   "Called from `compilation-filter-hook' (which see)."
-  ;; Get rid of line "Using config file '/PATH/TO/.globalrc'."
-  (when (re-search-backward "^ *Using config file '.*\n"
-                            compilation-filter-start t)
+  ;; Get rid of line "Using config file '/PATH/TO/.globalrc'." or
+  ;; "Using default configuration."
+  (when (re-search-backward
+         "^ *Using \\(?:config file '.*\\|default configuration.\\)\n"
+         compilation-filter-start t)
     (replace-match ""))
   (ansi-color-apply-on-region compilation-filter-start (point))
   (incf ggtags-global-output-lines
         (count-lines compilation-filter-start (point)))
+  (when (and (> ggtags-global-output-lines 5)
+             (not (get-buffer-window (current-buffer))))
+    (let* ((split-window-preferred-function ggtags-split-window-function)
+           (w (display-buffer (current-buffer) '(nil (allow-no-window . t)))))
+      (and w (compilation-set-window-height w))))
+  (make-local-variable 'ggtags-global-large-output)
   (when (> ggtags-global-output-lines ggtags-global-large-output)
+    (incf ggtags-global-large-output 500)
     (let ((message-log-max nil))
       (message "Output %d lines (Type `C-c C-k' to cancel)"
                ggtags-global-output-lines))))
@@ -1223,7 +1258,7 @@ Global and Emacs."
       '(menu-item "Update tag files" ggtags-update-tags
                   :visible (ggtags-find-project)))
     (define-key menu [run-gtags]
-      '(menu-item "Run gtags" ggtags-ensure-project
+      '(menu-item "Run gtags" ggtags-create-tags
                   :visible (not (ggtags-find-project))))
     map))
 
@@ -1237,9 +1272,13 @@ Global and Emacs."
   (if ggtags-mode
       (progn
         (add-hook 'after-save-hook 'ggtags-after-save-function nil t)
+        (when ggtags-enable-completion-at-point
+          (add-hook 'completion-at-point-functions
+                    #'ggtags-completion-at-point nil t))
         (or (executable-find "global")
             (message "Failed to find GNU Global")))
     (remove-hook 'after-save-hook 'ggtags-after-save-function t)
+    (remove-hook 'completion-at-point-functions #'ggtags-completion-at-point t)
     (and (overlayp ggtags-highlight-tag-overlay)
          (delete-overlay ggtags-highlight-tag-overlay))
     (setq ggtags-highlight-tag-overlay nil)))