xref-find-by-kind 34c8ed0ae55: xref-find-by-kind: Do filter by "kind" in identifier completion
Dmitry Gutov <[email protected]>
| Newsgroups | gmane.emacs.diffs |
|---|---|
| Message-ID | <[email protected]> |
branch: xref-find-by-kind commit 34c8ed0ae5521a0ad6ea95ca3efc39060a229aa9 Author: Dmitry Gutov <[email protected]> Commit: Dmitry Gutov <[email protected]> xref-find-by-kind: Do filter by "kind" in identifier completion When the backend allows, of course. * lisp/progmodes/elisp-mode.el (xref-backend-identifier-kind-predicate): One implementation. (xref-backend-xrefs-by-kind): Make sure generic functions and methods are recognized as "functions" too. * lisp/progmodes/xref.el (xref-backend-identifier-kind-predicate): New generic function. (xref-find-by-kind): Use it here. (xref-read-identifier): New argument PREDICATE. --- lisp/progmodes/elisp-mode.el | 24 +++++++++++++++++++++++- lisp/progmodes/xref.el | 13 ++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el index 0b44d228991..c303aefa75b 100644 --- a/lisp/progmodes/elisp-mode.el +++ b/lisp/progmodes/elisp-mode.el @@ -1683,7 +1683,10 @@ namespace but with lower confidence." (let* ((defs (elisp--xref-find-definitions sym))) (cl-loop for d in defs for def-kind = (xref-elisp-location-type (xref-item-location d)) - when (eq def-kind kind) + when (if kind + (eq def-kind kind) + (memq def-kind '( nil cl-defgeneric cl-defmethod + define-type defalias))) collect d))))) (declare-function xref-apropos-regexp "xref" (pattern)) @@ -1710,6 +1713,25 @@ namespace but with lower confidence." (eql 'elisp))) elisp--xref-identifier-completion-table) +(cl-defmethod xref-backend-identifier-kind-predicate ((_backend (eql 'elisp)) kind) + (lambda (identifier) + (let ((sym (intern-soft identifier))) + (cl-ecase kind + ((nil) (fboundp sym)) + (defvar (boundp sym)) + (cl-defgeneric (cl--generic sym)) + (cl-defmethod (and (cl--generic sym) + (cl--generic-method-table (cl--generic sym)))) + (define-type (and (functionp sym) + (let ((doc (documentation sym t))) + (and doc + (string-search "Constructor for objects of type" doc))))) + (defalias (and (symbolp sym) + (symbol-function sym) + (symbolp (symbol-function sym)))) + (defface (facep sym)) + (feature (featurep sym)))))) + (cl-defstruct (xref-elisp-location (:constructor xref-make-elisp-location (symbol type file))) "Location of an Emacs Lisp symbol definition." diff --git a/lisp/progmodes/xref.el b/lisp/progmodes/xref.el index 2e6037e742a..10db6229520 100644 --- a/lisp/progmodes/xref.el +++ b/lisp/progmodes/xref.el @@ -312,6 +312,10 @@ recognize and then delegate the work to an external process." "Return the completion table for identifiers." nil) +(cl-defgeneric xref-backend-identifier-kind-predicate (_backend _kind) + "Return the completion predicate for identifiers based on KIND." + nil) + (cl-defgeneric xref-backend-identifier-completion-ignore-case (_backend) "Return t if case is not significant in identifier completion." completion-ignore-case) @@ -1697,7 +1701,7 @@ The meanings of both arguments are the same as documented in (not (memq command (cdr xref-prompt-for-identifier))) (memq command xref-prompt-for-identifier)))) -(defun xref-read-identifier (prompt) +(defun xref-read-identifier (prompt &optional predicate) "Return the identifier at point or read it from the minibuffer. Reads and returns the identifier to use as input for the command being @@ -1726,7 +1730,8 @@ from `xref-backend-identifier-completion-table'." def) prompt)) (xref-backend-identifier-completion-table backend) - nil nil nil + predicate + nil nil 'xref--read-identifier-history def t))) (if (equal id "") (or def (user-error "There is no default identifier")) @@ -1844,7 +1849,9 @@ When called programmatically, KIND should be one of supported symbols." ;; probably only the elisp backend would have it. (xref-read-identifier (format-message (or (plist-get desc :prompt-format) "Find %s") - (plist-get desc :name))) + (plist-get desc :name)) + (xref-backend-identifier-kind-predicate (xref-find-backend) + kind)) kind))) (let ((kind-desc (cl-find-if (lambda (kind-desc) (eq (plist-get kind-desc :kind) kind))