From 1be8bfae6b1f9a0291a0be36fef0417a14657fc3 Mon Sep 17 00:00:00 2001 From: Dmitry Gutov Date: Sun, 5 Sep 2021 03:35:43 +0300 Subject: [PATCH] Xref: automatic jumping to the first definition or reference * 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 | 60 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 9045f941b13..45ee86cf5c5 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -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)) -- 2.39.2