aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2019-05-24 04:50:44 +0300
committerDmitry Gutov2019-05-24 04:50:44 +0300
commit62349fe82ad42d7d2a7fb19e40860ee5d6ebd017 (patch)
tree38c815c6ac736d801b314d5ddb067bcfdf076542
parent1cadab78e242834adab0fae3cb1feb691d52f8c5 (diff)
downloademacs-62349fe82ad42d7d2a7fb19e40860ee5d6ebd017.tar.gz
emacs-62349fe82ad42d7d2a7fb19e40860ee5d6ebd017.zip
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.
-rw-r--r--lisp/dired-aux.el21
-rw-r--r--lisp/progmodes/project.el10
-rw-r--r--lisp/progmodes/xref.el53
3 files changed, 62 insertions, 22 deletions
diff --git a/lisp/dired-aux.el b/lisp/dired-aux.el
index f699b79432b..51749acb217 100644
--- a/lisp/dired-aux.el
+++ b/lisp/dired-aux.el
@@ -2906,15 +2906,18 @@ REGEXP should use constructs supported by your local `grep' command."
2906 #'file-name-as-directory 2906 #'file-name-as-directory
2907 (rgrep-find-ignored-directories default-directory)) 2907 (rgrep-find-ignored-directories default-directory))
2908 grep-find-ignored-files)) 2908 grep-find-ignored-files))
2909 (xrefs (mapcan 2909 (fetcher
2910 (lambda (file) 2910 (lambda ()
2911 (xref-collect-matches regexp "*" file 2911 (let ((xrefs (mapcan
2912 (and (file-directory-p file) 2912 (lambda (file)
2913 ignores))) 2913 (xref-collect-matches regexp "*" file
2914 files))) 2914 (and (file-directory-p file)
2915 (unless xrefs 2915 ignores)))
2916 (user-error "No matches for: %s" regexp)) 2916 files)))
2917 (xref--show-xrefs xrefs nil))) 2917 (unless xrefs
2918 (user-error "No matches for: %s" regexp))
2919 xrefs))))
2920 (xref--show-xrefs fetcher nil)))
2918 2921
2919;;;###autoload 2922;;;###autoload
2920(defun dired-do-find-regexp-and-replace (from to) 2923(defun dired-do-find-regexp-and-replace (from to)
diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el
index e44cee2133f..d494efa493a 100644
--- a/lisp/progmodes/project.el
+++ b/lisp/progmodes/project.el
@@ -351,7 +351,9 @@ requires quoting, e.g. `\\[quoted-insert]<space>'."
351 (project--files-in-directory dir 351 (project--files-in-directory dir
352 nil 352 nil
353 (grep-read-files regexp)))))) 353 (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)))
355 357
356(defun project--dir-ignores (project dir) 358(defun project--dir-ignores (project dir)
357 (let* ((roots (project-roots project)) 359 (let* ((roots (project-roots project))
@@ -376,7 +378,9 @@ pattern to search for."
376 (project-files pr (append 378 (project-files pr (append
377 (project-roots pr) 379 (project-roots pr)
378 (project-external-roots pr))))) 380 (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)))
380 384
381(defun project--find-regexp-in-files (regexp files) 385(defun project--find-regexp-in-files (regexp files)
382 (pcase-let* 386 (pcase-let*
@@ -418,7 +422,7 @@ pattern to search for."
418 (setq xrefs (xref--convert-hits (nreverse hits) regexp)) 422 (setq xrefs (xref--convert-hits (nreverse hits) regexp))
419 (unless xrefs 423 (unless xrefs
420 (user-error "No matches for: %s" regexp)) 424 (user-error "No matches for: %s" regexp))
421 (xref--show-xrefs xrefs nil))) 425 xrefs))
422 426
423(defun project--process-file-region (start end program 427(defun project--process-file-region (start end program
424 &optional buffer display 428 &optional buffer display
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el
index b226a41929f..6a4906a2325 100644
--- a/lisp/progmodes/xref.el
+++ b/lisp/progmodes/xref.el
@@ -477,6 +477,9 @@ If SELECT is non-nil, select the target window."
477(defvar-local xref--original-window nil 477(defvar-local xref--original-window nil
478 "The original window this xref buffer was created from.") 478 "The original window this xref buffer was created from.")
479 479
480(defvar-local xref--fetcher nil
481 "The original function to call to fetch the list of xrefs.")
482
480(defun xref--show-pos-in-buf (pos buf) 483(defun xref--show-pos-in-buf (pos buf)
481 "Goto and display position POS of buffer BUF in a window. 484 "Goto and display position POS of buffer BUF in a window.
482Honor `xref--original-window-intent', run `xref-after-jump-hook' 485Honor `xref--original-window-intent', run `xref-after-jump-hook'
@@ -692,6 +695,7 @@ references displayed in the current *xref* buffer."
692 ;; suggested by Johan Claesson "to further reduce finger movement": 695 ;; suggested by Johan Claesson "to further reduce finger movement":
693 (define-key map (kbd ".") #'xref-next-line) 696 (define-key map (kbd ".") #'xref-next-line)
694 (define-key map (kbd ",") #'xref-prev-line) 697 (define-key map (kbd ",") #'xref-prev-line)
698 (define-key map (kbd "g") #'xref--revert-xref-buffer)
695 map)) 699 map))
696 700
697(define-derived-mode xref--xref-buffer-mode special-mode "XREF" 701(define-derived-mode xref--xref-buffer-mode special-mode "XREF"
@@ -777,8 +781,9 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
777 (xref-location-group (xref-item-location x))) 781 (xref-location-group (xref-item-location x)))
778 #'equal)) 782 #'equal))
779 783
780(defun xref--show-xref-buffer (xrefs alist) 784(defun xref--show-xref-buffer (fetcher alist)
781 (let ((xref-alist (xref--analyze xrefs))) 785 (let* ((xrefs (if (functionp fetcher) (funcall fetcher) fetcher))
786 (xref-alist (xref--analyze xrefs)))
782 (with-current-buffer (get-buffer-create xref-buffer-name) 787 (with-current-buffer (get-buffer-create xref-buffer-name)
783 (setq buffer-undo-list nil) 788 (setq buffer-undo-list nil)
784 (let ((inhibit-read-only t) 789 (let ((inhibit-read-only t)
@@ -790,8 +795,28 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
790 (goto-char (point-min)) 795 (goto-char (point-min))
791 (setq xref--original-window (assoc-default 'window alist) 796 (setq xref--original-window (assoc-default 'window alist)
792 xref--original-window-intent (assoc-default 'display-action alist)) 797 xref--original-window-intent (assoc-default 'display-action alist))
798 (when (functionp fetcher)
799 (setq xref--fetcher fetcher))
793 (current-buffer))))) 800 (current-buffer)))))
794 801
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
795(defun xref--show-defs-buffer (xrefs alist) 820(defun xref--show-defs-buffer (xrefs alist)
796 (cond 821 (cond
797 ((not (cdr xrefs)) 822 ((not (cdr xrefs))
@@ -811,9 +836,9 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
811 836
812(defvar xref--read-pattern-history nil) 837(defvar xref--read-pattern-history nil)
813 838
814(defun xref--show-xrefs (xrefs display-action) 839(defun xref--show-xrefs (fetcher display-action)
815 (xref--push-markers) 840 (xref--push-markers)
816 (funcall xref-show-xrefs-function xrefs 841 (funcall xref-show-xrefs-function fetcher
817 `((window . ,(selected-window)) 842 `((window . ,(selected-window))
818 (display-action . ,display-action)))) 843 (display-action . ,display-action))))
819 844
@@ -860,12 +885,20 @@ Return an alist of the form ((FILENAME . (XREF ...)) ...)."
860;;; Commands 885;;; Commands
861 886
862(defun xref--find-xrefs (input kind arg display-action) 887(defun xref--find-xrefs (input kind arg display-action)
863 (let ((xrefs (funcall (intern (format "xref-backend-%s" kind)) 888 (let* ((orig-buffer (current-buffer))
864 (xref-find-backend) 889 (orig-position (point))
865 arg))) 890 (backend (xref-find-backend))
866 (unless xrefs 891 (method (intern (format "xref-backend-%s" kind)))
867 (xref--not-found-error kind input)) 892 (fetcher (lambda ()
868 (xref--show-xrefs xrefs display-action))) 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)))
869 902
870(defun xref--find-definitions (id display-action) 903(defun xref--find-definitions (id display-action)
871 (let ((xrefs (funcall #'xref-backend-definitions 904 (let ((xrefs (funcall #'xref-backend-definitions