summaryrefslogtreecommitdiff
path: root/lisp/progmodes/elisp-mode.el
diff options
context:
space:
mode:
authorDmitry Gutov <dgutov@yandex.ru>2014-12-25 22:08:19 +0200
committerDmitry Gutov <dgutov@yandex.ru>2014-12-25 22:19:28 +0200
commit394ce9514f0f0b473e4e8974b8529d0389fb627e (patch)
treef1fe158638ee0a0f581fcd743c042c780d2453de /lisp/progmodes/elisp-mode.el
parentac549019742bac11c249814d7744670a56671f97 (diff)
downloademacs-394ce9514f0f0b473e4e8974b8529d0389fb627e.tar.gz
Consolidate cross-referencing commands
Move autoloaded bindings for `M-.', `M-,', `C-x 4 .' and `C-x 5 .' from etags.el to xref.el. * progmodes/xref.el: New file. * progmodes/elisp-mode.el (elisp--identifier-types): New variable. (elisp--identifier-location): New function, extracted from `elisp--company-location'. (elisp--company-location): Use it. (elisp--identifier-completion-table): New variable. (elisp-completion-at-point): Use it. (emacs-lisp-mode): Set the local values of `xref-find-function' and `xref-identifier-completion-table-function'. (elisp-xref-find, elisp--xref-find-definitions) (elisp--xref-identifier-completion-table): New functions. * progmodes/etags.el (find-tag-marker-ring): Mark obsolete in favor of `xref--marker-ring'. (tags-lazy-completion-table): Autoload. (tags-reset-tags-tables): Use `xref-clear-marker-stack'. (find-tag-noselect): Use `xref-push-marker-stack'. (pop-tag-mark): Make an alias for `xref-pop-marker-stack'. (etags--xref-limit): New constant. (etags-xref-find, etags--xref-find-definitions): New functions.
Diffstat (limited to 'lisp/progmodes/elisp-mode.el')
-rw-r--r--lisp/progmodes/elisp-mode.el88
1 files changed, 71 insertions, 17 deletions
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index ba70f903b4b..e73c20df263 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -227,10 +227,15 @@ Blank lines separate paragraphs. Semicolons start comments.
\\{emacs-lisp-mode-map}"
:group 'lisp
+ (defvar xref-find-function)
+ (defvar xref-identifier-completion-table-function)
(lisp-mode-variables nil nil 'elisp)
(setq imenu-case-fold-search nil)
(setq-local eldoc-documentation-function
#'elisp-eldoc-documentation-function)
+ (setq-local xref-find-function #'elisp-xref-find)
+ (setq-local xref-identifier-completion-table-function
+ #'elisp--xref-identifier-completion-table)
(add-hook 'completion-at-point-functions
#'elisp-completion-at-point nil 'local))
@@ -414,17 +419,39 @@ It can be quoted, or be inside a quoted form."
(declare-function find-library-name "find-func" (library))
+(defvar elisp--identifier-types '(defun defvar feature defface))
+
+(defun elisp--identifier-location (type sym)
+ (pcase (cons type sym)
+ (`(defun . ,(pred fboundp))
+ (find-definition-noselect sym nil))
+ (`(defvar . ,(pred boundp))
+ (find-definition-noselect sym 'defvar))
+ (`(defface . ,(pred facep))
+ (find-definition-noselect sym 'defface))
+ (`(feature . ,(pred featurep))
+ (require 'find-func)
+ (cons (find-file-noselect (find-library-name
+ (symbol-name sym)))
+ 1))))
+
(defun elisp--company-location (str)
- (let ((sym (intern-soft str)))
- (cond
- ((fboundp sym) (find-definition-noselect sym nil))
- ((boundp sym) (find-definition-noselect sym 'defvar))
- ((featurep sym)
- (require 'find-func)
- (cons (find-file-noselect (find-library-name
- (symbol-name sym)))
- 0))
- ((facep sym) (find-definition-noselect sym 'defface)))))
+ (catch 'res
+ (let ((sym (intern-soft str)))
+ (when sym
+ (dolist (type elisp--identifier-types)
+ (let ((loc (elisp--identifier-location type sym)))
+ (and loc (throw 'res loc))))))))
+
+(defvar elisp--identifier-completion-table
+ (apply-partially #'completion-table-with-predicate
+ obarray
+ (lambda (sym)
+ (or (boundp sym)
+ (fboundp sym)
+ (featurep sym)
+ (symbol-plist sym)))
+ 'strict))
(defun elisp-completion-at-point ()
"Function used for `completion-at-point-functions' in `emacs-lisp-mode'."
@@ -466,13 +493,8 @@ It can be quoted, or be inside a quoted form."
:company-docsig #'elisp--company-doc-string
:company-location #'elisp--company-location))
((elisp--form-quoted-p beg)
- (list nil obarray
- ;; Don't include all symbols
- ;; (bug#16646).
- :predicate (lambda (sym)
- (or (boundp sym)
- (fboundp sym)
- (symbol-plist sym)))
+ ;; Don't include all symbols (bug#16646).
+ (list nil elisp--identifier-completion-table
:annotation-function
(lambda (str) (if (fboundp (intern-soft str)) " <f>"))
:company-doc-buffer #'elisp--company-doc-buffer
@@ -548,6 +570,38 @@ It can be quoted, or be inside a quoted form."
(define-obsolete-function-alias
'lisp-completion-at-point 'elisp-completion-at-point "25.1")
+;;; Xref backend
+
+(declare-function xref-make-buffer-location "xref" (buffer position))
+(declare-function xref-make-bogus-location "xref" (message))
+(declare-function xref-make "xref" (description location))
+
+(defun elisp-xref-find (action id)
+ (when (eq action 'definitions)
+ (let ((sym (intern-soft id)))
+ (when sym
+ (remove nil (elisp--xref-find-definitions sym))))))
+
+(defun elisp--xref-find-definitions (symbol)
+ (save-excursion
+ (mapcar
+ (lambda (type)
+ (let ((loc
+ (condition-case err
+ (let ((buf-pos (elisp--identifier-location type symbol)))
+ (when buf-pos
+ (xref-make-buffer-location (car buf-pos)
+ (or (cdr buf-pos) 1))))
+ (error
+ (xref-make-bogus-location (error-message-string err))))))
+ (when loc
+ (xref-make (format "(%s %s)" type symbol)
+ loc))))
+ elisp--identifier-types)))
+
+(defun elisp--xref-identifier-completion-table ()
+ elisp--identifier-completion-table)
+
;;; Elisp Interaction mode
(defvar lisp-interaction-mode-map