]> git.eshelyaron.com Git - emacs.git/commitdiff
Xref: automatic jumping to the first definition or reference
authorDmitry Gutov <dgutov@yandex.ru>
Sun, 5 Sep 2021 00:35:43 +0000 (03:35 +0300)
committerDmitry Gutov <dgutov@yandex.ru>
Sun, 5 Sep 2021 00:35:43 +0000 (03:35 +0300)
* lisp/progmodes/xref.el (xref-auto-jump-to-first-definition)
(xref-auto-jump-to-first-xref): New user options.
Discussed in bug#50067.
(xref--show-xrefs, xref--show-defs): Use them here.
(xref--auto-jump-first): New function, handles different values.
(xref-show-definitions-buffer)
(xref-show-definitions-buffer-at-bottom): Use it.

lisp/progmodes/xref.el

index 9045f941b13f8ee172f4912840450c6b25410567..45ee86cf5c50e46a62eedff273ff6d4eff51ef72 100644 (file)
@@ -416,6 +416,28 @@ elements is negated: these commands will NOT prompt."
   :version "28.1"
   :package-version '(xref . "1.0.4"))
 
+(defcustom xref-auto-jump-to-first-definition nil
+  "If t, `xref-find-definitions' always jumps to the first result.
+`show' means to show the first result's location, but keep the
+focus on the Xref buffer's window.
+`move' means to only move point to the first result."
+  :type '(choice (const t :tag "Jump")
+                 (const show :tag "Show")
+                 (const move :tag "Move point only"))
+  :version "28.1"
+  :package-version '(xref . "1.2.0"))
+
+(defcustom xref-auto-jump-to-first-xref nil
+  "If t, xref commands always jump to the first result.
+`show' means to show the first result's location, but keep the
+focus on the Xref buffer's window.
+`move' means to only move point to the first result."
+  :type '(choice (const t :tag "Jump")
+                 (const show :tag "Show")
+                 (const move :tag "Move point only"))
+  :version "28.1"
+  :package-version '(xref . "1.2.0"))
+
 (defvar xref--marker-ring (make-ring xref-marker-ring-length)
   "Ring of markers to implement the marker stack.")
 
@@ -1064,19 +1086,36 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
            (error-message-string err)
            'face 'error)))))))
 
+(defun xref--auto-jump-first (buf value)
+  (when value
+    (select-window (get-buffer-window buf))
+    (goto-char (point-min)))
+  (cond
+   ((eq value t)
+    (xref-next-line-no-show)
+    (xref-goto-xref))
+   ((eq value 'show)
+    (xref-next-line))
+   ((eq value 'move)
+    (forward-line 1))))
+
 (defun xref-show-definitions-buffer (fetcher alist)
   "Show the definitions list in a regular window.
 
 When only one definition found, jump to it right away instead."
-  (let ((xrefs (funcall fetcher)))
+  (let ((xrefs (funcall fetcher))
+        buf)
     (cond
      ((not (cdr xrefs))
       (xref-pop-to-location (car xrefs)
                             (assoc-default 'display-action alist)))
      (t
-      (xref--show-xref-buffer fetcher
-                              (cons (cons 'fetched-xrefs xrefs)
-                                    alist))))))
+      (setq buf
+            (xref--show-xref-buffer fetcher
+                                    (cons (cons 'fetched-xrefs xrefs)
+                                          alist)))
+      (xref--auto-jump-first buf (assoc-default 'auto-jump alist))
+      buf))))
 
 (define-obsolete-function-alias
   'xref--show-defs-buffer #'xref-show-definitions-buffer "28.1")
@@ -1092,7 +1131,8 @@ local keymap that binds `RET' to `xref-quit-and-goto-xref'."
          ;; XXX: Make percentage customizable maybe?
          (max-height (/ (window-height) 2))
          (size-fun (lambda (window)
-                     (fit-window-to-buffer window max-height))))
+                     (fit-window-to-buffer window max-height)))
+         buf)
     (cond
      ((not (cdr xrefs))
       (xref-pop-to-location (car xrefs)
@@ -1105,7 +1145,9 @@ local keymap that binds `RET' to `xref-quit-and-goto-xref'."
         (pop-to-buffer (current-buffer)
                        `(display-buffer-in-direction . ((direction . below)
                                                         (window-height . ,size-fun))))
-        (current-buffer))))))
+        (setq buf (current-buffer)))
+      (xref--auto-jump-first buf (assoc-default 'auto-jump alist))
+      buf))))
 
 (define-obsolete-function-alias 'xref--show-defs-buffer-at-bottom
   #'xref-show-definitions-buffer-at-bottom "28.1")
@@ -1234,13 +1276,15 @@ definitions."
                   (setq xrefs 'called-already)))))))
   (funcall xref-show-xrefs-function fetcher
            `((window . ,(selected-window))
-             (display-action . ,display-action))))
+             (display-action . ,display-action)
+             (auto-jump . ,xref-auto-jump-to-first-xref))))
 
 (defun xref--show-defs (xrefs display-action)
   (xref--push-markers)
   (funcall xref-show-definitions-function xrefs
            `((window . ,(selected-window))
-             (display-action . ,display-action))))
+             (display-action . ,display-action)
+             (auto-jump . ,xref-auto-jump-to-first-definition))))
 
 (defun xref--push-markers ()
   (unless (region-active-p) (push-mark nil t))