aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Gutov2015-05-01 21:54:33 +0300
committerDmitry Gutov2015-05-01 23:41:27 +0300
commitfed6a0d6b1c11e45ee49549954ad306df89873ad (patch)
treeba713ed9b37eec633ede5c978694d5d9483ec662
parentb621e97436c6d9fd255d2ff84a237ddc79a4b8b9 (diff)
downloademacs-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.el21
-rw-r--r--lisp/progmodes/etags.el4
-rw-r--r--lisp/progmodes/xref.el46
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.
682Uses the Semantic Symbol Reference API, see
683`semantic-symref-find-references-by-name' for details on which
684tools 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