diff options
| author | Dmitry Gutov | 2015-05-01 21:54:33 +0300 |
|---|---|---|
| committer | Dmitry Gutov | 2015-05-01 23:41:27 +0300 |
| commit | fed6a0d6b1c11e45ee49549954ad306df89873ad (patch) | |
| tree | ba713ed9b37eec633ede5c978694d5d9483ec662 | |
| parent | b621e97436c6d9fd255d2ff84a237ddc79a4b8b9 (diff) | |
| download | emacs-fed6a0d6b1c11e45ee49549954ad306df89873ad.tar.gz emacs-fed6a0d6b1c11e45ee49549954ad306df89873ad.zip | |
Implement xref-find-references in etags and elisp-mode
* lisp/progmodes/elisp-mode.el (elisp--xref-find-references): New function.
(elisp-xref-find): Use it.
* lisp/progmodes/etags.el (etags-xref-find): Use `xref-collect-references'.
* lisp/progmodes/xref.el (xref-collect-references):
(xref--collect-reference): New functions.
| -rw-r--r-- | lisp/progmodes/elisp-mode.el | 21 | ||||
| -rw-r--r-- | lisp/progmodes/etags.el | 4 | ||||
| -rw-r--r-- | lisp/progmodes/xref.el | 46 |
3 files changed, 71 insertions, 0 deletions
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index f2890686e79..ef477d64fcc 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el | |||
| @@ -587,6 +587,8 @@ It can be quoted, or be inside a quoted form." | |||
| 587 | (let ((sym (intern-soft id))) | 587 | (let ((sym (intern-soft id))) |
| 588 | (when sym | 588 | (when sym |
| 589 | (elisp--xref-find-definitions sym)))) | 589 | (elisp--xref-find-definitions sym)))) |
| 590 | (`references | ||
| 591 | (elisp--xref-find-references id)) | ||
| 590 | (`apropos | 592 | (`apropos |
| 591 | (elisp--xref-find-apropos id)))) | 593 | (elisp--xref-find-apropos id)))) |
| 592 | 594 | ||
| @@ -635,6 +637,25 @@ It can be quoted, or be inside a quoted form." | |||
| 635 | lst)))) | 637 | lst)))) |
| 636 | lst))) | 638 | lst))) |
| 637 | 639 | ||
| 640 | (defun elisp--xref-find-references (symbol) | ||
| 641 | (let* ((dirs (sort | ||
| 642 | (mapcar | ||
| 643 | (lambda (dir) | ||
| 644 | (file-name-as-directory (expand-file-name dir))) | ||
| 645 | (cons package-user-dir load-path)) | ||
| 646 | #'string<)) | ||
| 647 | (ref dirs)) | ||
| 648 | ;; Delete subdirectories from the list. | ||
| 649 | (while (cdr ref) | ||
| 650 | (if (string-prefix-p (car ref) (cadr ref)) | ||
| 651 | (setcdr ref (cddr ref)) | ||
| 652 | (setq ref (cdr ref)))) | ||
| 653 | (mapcan | ||
| 654 | (lambda (dir) | ||
| 655 | (and (file-exists-p dir) | ||
| 656 | (xref-collect-references symbol dir))) | ||
| 657 | dirs))) | ||
| 658 | |||
| 638 | (defun elisp--xref-find-apropos (regexp) | 659 | (defun elisp--xref-find-apropos (regexp) |
| 639 | (apply #'nconc | 660 | (apply #'nconc |
| 640 | (let (lst) | 661 | (let (lst) |
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index b4ce8b11c9c..9a57d8ad886 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el | |||
| @@ -2082,6 +2082,10 @@ for \\[find-tag] (which see)." | |||
| 2082 | (defun etags-xref-find (action id) | 2082 | (defun etags-xref-find (action id) |
| 2083 | (pcase action | 2083 | (pcase action |
| 2084 | (`definitions (etags--xref-find-definitions id)) | 2084 | (`definitions (etags--xref-find-definitions id)) |
| 2085 | (`references (mapcan | ||
| 2086 | (lambda (file) | ||
| 2087 | (xref-collect-references id (file-name-directory file))) | ||
| 2088 | tags-table-list)) | ||
| 2085 | (`apropos (etags--xref-find-definitions id t)))) | 2089 | (`apropos (etags--xref-find-definitions id t)))) |
| 2086 | 2090 | ||
| 2087 | (defun etags--xref-find-definitions (pattern &optional regexp?) | 2091 | (defun etags--xref-find-definitions (pattern &optional regexp?) |
diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index fc27c268845..ea705fc852b 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el | |||
| @@ -674,6 +674,52 @@ and just use etags." | |||
| 674 | (setq-local xref-identifier-completion-table-function | 674 | (setq-local xref-identifier-completion-table-function |
| 675 | (cdr xref-etags-mode--saved)))) | 675 | (cdr xref-etags-mode--saved)))) |
| 676 | 676 | ||
| 677 | (declare-function semantic-symref-find-references-by-name "semantic/symref") | ||
| 678 | (declare-function semantic-find-file-noselect "semantic/fw") | ||
| 679 | |||
| 680 | (defun xref-collect-references (name dir) | ||
| 681 | "Collect mentions of NAME inside DIR. | ||
| 682 | Uses the Semantic Symbol Reference API, see | ||
| 683 | `semantic-symref-find-references-by-name' for details on which | ||
| 684 | tools are used, and when." | ||
| 685 | (require 'semantic/symref) | ||
| 686 | (defvar semantic-symref-tool) | ||
| 687 | (cl-assert (directory-name-p dir)) | ||
| 688 | (let* ((default-directory dir) | ||
| 689 | (semantic-symref-tool 'detect) | ||
| 690 | (res (semantic-symref-find-references-by-name name 'subdirs)) | ||
| 691 | (hits (and res (oref res :hit-lines))) | ||
| 692 | (orig-buffers (buffer-list)) | ||
| 693 | xrefs) | ||
| 694 | (unwind-protect | ||
| 695 | (setq xrefs | ||
| 696 | (mapcar (lambda (hit) (xref--collect-reference hit name)) | ||
| 697 | hits)) | ||
| 698 | (mapc #'kill-buffer | ||
| 699 | (cl-set-difference (buffer-list) orig-buffers))) | ||
| 700 | (delq nil xrefs))) | ||
| 701 | |||
| 702 | (defun xref--collect-reference (hit name) | ||
| 703 | (pcase-let* ((`(,line . ,file) hit) | ||
| 704 | (buf (or (find-buffer-visiting file) | ||
| 705 | (semantic-find-file-noselect file)))) | ||
| 706 | (with-current-buffer buf | ||
| 707 | (save-excursion | ||
| 708 | (goto-char (point-min)) | ||
| 709 | (forward-line (1- line)) | ||
| 710 | (when (re-search-forward (format "\\_<%s\\_>" | ||
| 711 | (regexp-quote name)) | ||
| 712 | (line-end-position) t) | ||
| 713 | (goto-char (match-beginning 0)) | ||
| 714 | (xref-make (format | ||
| 715 | "%d: %s" | ||
| 716 | line | ||
| 717 | (buffer-substring | ||
| 718 | (line-beginning-position) | ||
| 719 | (line-end-position))) | ||
| 720 | (xref-make-file-location file line | ||
| 721 | (current-column)))))))) | ||
| 722 | |||
| 677 | 723 | ||
| 678 | (provide 'xref) | 724 | (provide 'xref) |
| 679 | 725 | ||