diff options
Diffstat (limited to 'lisp/progmodes/elisp-mode.el')
| -rw-r--r-- | lisp/progmodes/elisp-mode.el | 88 |
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 |
