]> code.delx.au - gnu-emacs-elpa/blobdiff - ggtags.el
Fix #44: New variable ggtags-enable-navigation-keys
[gnu-emacs-elpa] / ggtags.el
index 700d16bf4eaa7380b6fd98a2bb3379b5e9548944..faf4d06e5ff2f3638234992e049b155e5821372e 100644 (file)
--- a/ggtags.el
+++ b/ggtags.el
@@ -34,8 +34,7 @@
 ;; `ggtags-mode'. See the README in https://github.com/leoliu/ggtags
 ;; for more details.
 ;;
-;; All commands are made available in the menu-bar entry `Ggtags' in
-;; `ggtags-mode'.
+;; All commands are available from the `Ggtags' menu in `ggtags-mode'.
 
 ;;; Code:
 
@@ -144,8 +143,8 @@ directory local variables is not enabled by default per
 (defcustom ggtags-auto-jump-to-match 'first
   "Strategy on how to jump to match: nil, first or history.
 
-  nil:   never automatically jump to any match;
-first:   jump to the first match;
+    nil: never automatically jump to any match;
+  first: jump to the first match;
 history: jump to the match stored in search history."
   :type '(choice (const :tag "First match" first)
                  (const :tag "Search History" history)
@@ -214,8 +213,9 @@ This affects `ggtags-find-file' and `ggtags-grep'."
   :type 'integer
   :group 'ggtags)
 
-(defcustom ggtags-suppress-navigation-keys nil
-  "If non-nil key bindings in `ggtags-navigation-map' are suppressed."
+(defcustom ggtags-enable-navigation-keys t
+  "If non-nil key bindings in `ggtags-navigation-map' are enabled."
+  :safe 'booleanp
   :type 'boolean
   :group 'ggtags)
 
@@ -943,7 +943,7 @@ Global and Emacs."
     (erase-buffer)
     (special-mode)
     (use-local-map ggtags-global-rerun-search-map)
-    (setq-local ggtags-navigation-mode nil)
+    (setq-local ggtags-enable-navigation-keys nil)
     (setq-local bookmark-make-record-function #'ggtags-make-bookmark-record)
     (setq truncate-lines t)
     (cl-labels ((prop (s) (propertize s 'face 'minibuffer-prompt))
@@ -1292,13 +1292,20 @@ commands `next-error' and `previous-error'.
            (count-lines compilation-filter-start (point)))
   (when (and (> ggtags-global-output-lines 5) ggtags-navigation-mode)
     (ggtags-global--display-buffer))
-  (when (and (numberp ggtags-auto-jump-to-match-target)
+  (when (and (eq ggtags-auto-jump-to-match 'history)
+             (numberp ggtags-auto-jump-to-match-target)
              ;; `ggtags-global-output-lines' is imprecise.
              (> (line-number-at-pos (point-max))
                 ggtags-auto-jump-to-match-target))
     (ggtags-forward-to-line ggtags-auto-jump-to-match-target)
     (setq-local ggtags-auto-jump-to-match-target nil)
-    (with-demoted-errors (compile-goto-error)))
+    ;;
+    ;; Can't call `compile-goto-error' here becuase
+    ;; `compilation-filter' restores point and as a result commands
+    ;; dependent on point such as `ggtags-navigation-next-file' and
+    ;; `ggtags-navigation-previous-file' fail to work.
+    (setq-local compilation-auto-jump-to-first-error t)
+    (run-with-idle-timer 0 nil #'compilation-auto-jump (current-buffer) (point)))
   (make-local-variable 'ggtags-global-large-output)
   (when (> ggtags-global-output-lines ggtags-global-large-output)
     (cl-incf ggtags-global-large-output 500)
@@ -1306,24 +1313,24 @@ commands `next-error' and `previous-error'.
       (message "Output %d lines (Type `C-c C-k' to cancel)"
                ggtags-global-output-lines))))
 
-(defun ggtags-handle-single-match (buf how)
-  (if (string-prefix-p "exited abnormally" how)
-      ;; If exit abnormally display the buffer for inspection.
-      (ggtags-global--display-buffer)
-    (when (and ggtags-auto-jump-to-match
-               (save-excursion
-                 (goto-char (point-min))
-                 (not (ignore-errors
-                        (goto-char (compilation-next-single-property-change
-                                    (point) 'compilation-message))
-                        (end-of-line)
-                        (compilation-next-single-property-change
-                         (point) 'compilation-message)))))
-      ;; For the `compilation-auto-jump' in idle timer to run. See also:
-      ;; http://debbugs.gnu.org/13829
-      (sit-for 0)
-      (ggtags-navigation-mode -1)
-      (ggtags-navigation-mode-cleanup buf 0))))
+(defun ggtags-global-handle-exit (buf how)
+  "A function for `compilation-finish-functions' (which see)."
+  (cond
+   ((string-prefix-p "exited abnormally" how)
+    ;; If exit abnormally display the buffer for inspection.
+    (ggtags-global--display-buffer))
+   ((and ggtags-auto-jump-to-match
+         (not (pcase (compilation-next-single-property-change
+                      (point-min) 'compilation-message)
+                ((and pt (guard pt))
+                 (compilation-next-single-property-change
+                  (save-excursion (goto-char pt) (end-of-line) (point))
+                  'compilation-message)))))
+    ;; For the `compilation-auto-jump' in idle timer to run.
+    ;; See also: http://debbugs.gnu.org/13829
+    (sit-for 0)
+    (ggtags-navigation-mode -1)
+    (ggtags-navigation-mode-cleanup buf 0))))
 
 (defvar ggtags-global-mode-font-lock-keywords
   '(("^Global \\(exited abnormally\\|interrupt\\|killed\\|terminated\\)\\(?:.*with code \\([0-9]+\\)\\)?.*"
@@ -1359,9 +1366,9 @@ commands `next-error' and `previous-error'.
   (setq-local truncate-lines t)
   (jit-lock-register #'ggtags-abbreviate-files)
   (add-hook 'compilation-filter-hook 'ggtags-global-filter nil 'local)
-  (add-hook 'compilation-finish-functions 'ggtags-handle-single-match nil t)
+  (add-hook 'compilation-finish-functions 'ggtags-global-handle-exit nil t)
   (setq-local bookmark-make-record-function #'ggtags-make-bookmark-record)
-  (setq-local ggtags-navigation-mode nil)
+  (setq-local ggtags-enable-navigation-keys nil)
   (add-hook 'kill-buffer-hook (lambda () (ggtags-navigation-mode -1)) nil t))
 
 ;; NOTE: Need this to avoid putting menu items in
@@ -1388,7 +1395,7 @@ commands `next-error' and `previous-error'.
     map))
 
 (defvar ggtags-mode-map-alist
-  `((ggtags-navigation-mode . ,ggtags-navigation-map)))
+  `((ggtags-enable-navigation-keys . ,ggtags-navigation-map)))
 
 (defvar ggtags-navigation-mode-map
   (let ((map (make-sparse-keymap))
@@ -1461,13 +1468,13 @@ commands `next-error' and `previous-error'.
 (defun ggtags-navigation-mode-abort ()
   (interactive)
   (ggtags-navigation-mode -1)
+  (ggtags-navigation-mode-cleanup nil 0)
   ;; Run after (ggtags-navigation-mode -1) or
   ;; ggtags-global-start-marker might not have been saved.
   (when (and ggtags-global-start-marker
              (not (markerp ggtags-global-start-marker)))
     (setq ggtags-global-start-marker nil)
-    (pop-tag-mark))
-  (ggtags-navigation-mode-cleanup nil 0))
+    (pop-tag-mark)))
 
 (defun ggtags-navigation-next-file (n)
   (interactive "p")
@@ -1561,8 +1568,7 @@ commands `next-error' and `previous-error'.
       (progn
         ;; Higher priority for `ggtags-navigation-mode' to avoid being
         ;; hijacked by modes such as `view-mode'.
-        (unless ggtags-suppress-navigation-keys
-          (add-to-list 'emulation-mode-map-alists 'ggtags-mode-map-alist))
+        (add-to-list 'emulation-mode-map-alists 'ggtags-mode-map-alist)
         (add-hook 'next-error-hook 'ggtags-global-next-error-function)
         (add-hook 'minibuffer-setup-hook 'ggtags-minibuffer-setup-function))
     (setq emulation-mode-map-alists
@@ -1572,7 +1578,7 @@ commands `next-error' and `previous-error'.
 
 (defun ggtags-minibuffer-setup-function ()
   ;; Disable ggtags-navigation-mode in minibuffer.
-  (setq-local ggtags-navigation-mode nil))
+  (setq-local ggtags-enable-navigation-keys nil))
 
 (defun ggtags-kill-file-buffers (&optional interactive)
   "Kill all buffers visiting files in current project."