diff options
| author | Dmitry Gutov | 2019-05-24 04:50:44 +0300 |
|---|---|---|
| committer | Dmitry Gutov | 2019-05-24 04:50:44 +0300 |
| commit | 62349fe82ad42d7d2a7fb19e40860ee5d6ebd017 (patch) | |
| tree | 38c815c6ac736d801b314d5ddb067bcfdf076542 | |
| parent | 1cadab78e242834adab0fae3cb1feb691d52f8c5 (diff) | |
| download | emacs-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.el | 21 | ||||
| -rw-r--r-- | lisp/progmodes/project.el | 10 | ||||
| -rw-r--r-- | lisp/progmodes/xref.el | 53 |
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. |
| 482 | Honor `xref--original-window-intent', run `xref-after-jump-hook' | 485 | Honor `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 |