Skip to content

Commit 62349fe

Browse files
committed
Support "reverting" Xref buffers (bug#35702)
* lisp/progmodes/xref.el (xref--fetcher): New variable. (xref--xref-buffer-mode-map): Add binding for 'g'. (xref--revert-xref-buffer): New command. (xref--show-xref-buffer): Accept a function as the first argument. (xref--show-xrefs): Same. (xref--find-xrefs): Pass the above a fetcher function. * lisp/progmodes/project.el (project-find-regexp) (project-or-external-find-regexp): Same. * lisp/dired-aux.el (dired-do-find-regexp): Same.
1 parent 1cadab7 commit 62349fe

File tree

3 files changed

+62
-22
lines changed

3 files changed

+62
-22
lines changed

lisp/dired-aux.el

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2906,15 +2906,18 @@ REGEXP should use constructs supported by your local `grep' command."
29062906
#'file-name-as-directory
29072907
(rgrep-find-ignored-directories default-directory))
29082908
grep-find-ignored-files))
2909-
(xrefs (mapcan
2910-
(lambda (file)
2911-
(xref-collect-matches regexp "*" file
2912-
(and (file-directory-p file)
2913-
ignores)))
2914-
files)))
2915-
(unless xrefs
2916-
(user-error "No matches for: %s" regexp))
2917-
(xref--show-xrefs xrefs nil)))
2909+
(fetcher
2910+
(lambda ()
2911+
(let ((xrefs (mapcan
2912+
(lambda (file)
2913+
(xref-collect-matches regexp "*" file
2914+
(and (file-directory-p file)
2915+
ignores)))
2916+
files)))
2917+
(unless xrefs
2918+
(user-error "No matches for: %s" regexp))
2919+
xrefs))))
2920+
(xref--show-xrefs fetcher nil)))
29182921

29192922
;;;###autoload
29202923
(defun dired-do-find-regexp-and-replace (from to)

lisp/progmodes/project.el

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,9 @@ requires quoting, e.g. `\\[quoted-insert]<space>'."
351351
(project--files-in-directory dir
352352
nil
353353
(grep-read-files regexp))))))
354-
(project--find-regexp-in-files regexp files)))
354+
(xref--show-xrefs
355+
(apply-partially #'project--find-regexp-in-files regexp files)
356+
nil)))
355357

356358
(defun project--dir-ignores (project dir)
357359
(let* ((roots (project-roots project))
@@ -376,7 +378,9 @@ pattern to search for."
376378
(project-files pr (append
377379
(project-roots pr)
378380
(project-external-roots pr)))))
379-
(project--find-regexp-in-files regexp files)))
381+
(xref--show-xrefs
382+
(apply-partially #'project--find-regexp-in-files regexp files)
383+
nil)))
380384

381385
(defun project--find-regexp-in-files (regexp files)
382386
(pcase-let*
@@ -418,7 +422,7 @@ pattern to search for."
418422
(setq xrefs (xref--convert-hits (nreverse hits) regexp))
419423
(unless xrefs
420424
(user-error "No matches for: %s" regexp))
421-
(xref--show-xrefs xrefs nil)))
425+
xrefs))
422426

423427
(defun project--process-file-region (start end program
424428
&optional buffer display

lisp/progmodes/xref.el

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,9 @@ If SELECT is non-nil, select the target window."
477477
(defvar-local xref--original-window nil
478478
"The original window this xref buffer was created from.")
479479

480+
(defvar-local xref--fetcher nil
481+
"The original function to call to fetch the list of xrefs.")
482+
480483
(defun xref--show-pos-in-buf (pos buf)
481484
"Goto and display position POS of buffer BUF in a window.
482485
Honor `xref--original-window-intent', run `xref-after-jump-hook'
@@ -692,6 +695,7 @@ references displayed in the current *xref* buffer."
692695
;; suggested by Johan Claesson "to further reduce finger movement":
693696
(define-key map (kbd ".") #'xref-next-line)
694697
(define-key map (kbd ",") #'xref-prev-line)
698+
(define-key map (kbd "g") #'xref--revert-xref-buffer)
695699
map))
696700

697701
(define-derived-mode xref--xref-buffer-mode special-mode "XREF"
@@ -777,8 +781,9 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
777781
(xref-location-group (xref-item-location x)))
778782
#'equal))
779783

780-
(defun xref--show-xref-buffer (xrefs alist)
781-
(let ((xref-alist (xref--analyze xrefs)))
784+
(defun xref--show-xref-buffer (fetcher alist)
785+
(let* ((xrefs (if (functionp fetcher) (funcall fetcher) fetcher))
786+
(xref-alist (xref--analyze xrefs)))
782787
(with-current-buffer (get-buffer-create xref-buffer-name)
783788
(setq buffer-undo-list nil)
784789
(let ((inhibit-read-only t)
@@ -790,8 +795,28 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
790795
(goto-char (point-min))
791796
(setq xref--original-window (assoc-default 'window alist)
792797
xref--original-window-intent (assoc-default 'display-action alist))
798+
(when (functionp fetcher)
799+
(setq xref--fetcher fetcher))
793800
(current-buffer)))))
794801

802+
(defun xref--revert-xref-buffer ()
803+
(interactive)
804+
(unless xref--fetcher
805+
(user-error "Reverting not supported"))
806+
(let ((inhibit-read-only t)
807+
(buffer-undo-list t))
808+
(save-excursion
809+
(erase-buffer)
810+
(condition-case err
811+
(xref--insert-xrefs
812+
(xref--analyze (funcall xref--fetcher)))
813+
(user-error
814+
(insert
815+
(propertize
816+
(error-message-string err)
817+
'face 'error))))
818+
(goto-char (point-min)))))
819+
795820
(defun xref--show-defs-buffer (xrefs alist)
796821
(cond
797822
((not (cdr xrefs))
@@ -811,9 +836,9 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
811836

812837
(defvar xref--read-pattern-history nil)
813838

814-
(defun xref--show-xrefs (xrefs display-action)
839+
(defun xref--show-xrefs (fetcher display-action)
815840
(xref--push-markers)
816-
(funcall xref-show-xrefs-function xrefs
841+
(funcall xref-show-xrefs-function fetcher
817842
`((window . ,(selected-window))
818843
(display-action . ,display-action))))
819844

@@ -860,12 +885,20 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
860885
;;; Commands
861886

862887
(defun xref--find-xrefs (input kind arg display-action)
863-
(let ((xrefs (funcall (intern (format "xref-backend-%s" kind))
864-
(xref-find-backend)
865-
arg)))
866-
(unless xrefs
867-
(xref--not-found-error kind input))
868-
(xref--show-xrefs xrefs display-action)))
888+
(let* ((orig-buffer (current-buffer))
889+
(orig-position (point))
890+
(backend (xref-find-backend))
891+
(method (intern (format "xref-backend-%s" kind)))
892+
(fetcher (lambda ()
893+
(save-excursion
894+
(when (buffer-live-p orig-buffer)
895+
(set-buffer orig-buffer)
896+
(ignore-errors (goto-char orig-position)))
897+
(let ((xrefs (funcall method backend arg)))
898+
(unless xrefs
899+
(xref--not-found-error kind input))
900+
xrefs)))))
901+
(xref--show-xrefs fetcher display-action)))
869902

870903
(defun xref--find-definitions (id display-action)
871904
(let ((xrefs (funcall #'xref-backend-definitions

0 commit comments

Comments
 (0)