Subject: bug#50067: Context menus

From: Dmitry Gutov <[email-masked]>
Date: Tue, 24 Aug 2021 20:59:40 +0300

On 23.08.2021 19:02, Juri Linkov wrote:
>>> We could add an option, at the very least.
>> An option to display the first match right away will be most
>> appreciated, thanks.
> Like compilation-auto-jump-to-first-error.

So we even have a precedent, very good.

Could you both check out the attached patch?

Together with (setq xref-auto-jump-to-first-definition t)

Questions for feedback:

1. Does the new behavior work okay window management-wise (it does 
occupy +1 window, after all)?

2. Should this setting also extend to other commands like 
xref-find-references? Asking for personal preferences here.
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index d004a0c32c..ca055a36af 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -416,6 +416,12 @@ xref-after-update-hook
   :version "28.1"
   :package-version '(xref . "1.0.4"))
 
+(defcustom xref-auto-jump-to-first-definition nil
+  "If non-nil, `xref-find-definitions' always jumps to the first result."
+  :type 'boolean
+  :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.")
 
@@ -1060,19 +1066,30 @@ xref-revert-buffer
            (error-message-string err)
            'face 'error)))))))
 
+(defun xref--auto-jump-first (buf)
+  (select-window (get-buffer-window buf))
+  (goto-char (point-min))
+  (xref-next-line-no-show)
+  (xref-goto-xref))
+
 (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)))
+      (when (assoc-default 'auto-jump alist)
+        (xref--auto-jump-first buf))
+      buf))))
 
 (define-obsolete-function-alias
   'xref--show-defs-buffer #'xref-show-definitions-buffer "28.1")
@@ -1088,7 +1105,8 @@ xref-show-definitions-buffer-at-bottom
          ;; 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)
@@ -1101,7 +1119,10 @@ xref-show-definitions-buffer-at-bottom
         (pop-to-buffer (current-buffer)
                        `(display-buffer-in-direction . ((direction . below)
                                                         (window-height . ,size-fun))))
-        (current-buffer))))))
+        (setq buf (current-buffer)))
+      (when (assoc-default 'auto-jump alist)
+        (xref--auto-jump-first buf))
+      buf))))
 
 (define-obsolete-function-alias 'xref--show-defs-buffer-at-bottom
   #'xref-show-definitions-buffer-at-bottom "28.1")
@@ -1236,7 +1257,8 @@ xref--show-defs
   (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))