diff options
Diffstat (limited to 'lisp/emacs-lisp/find-func.el')
-rw-r--r-- | lisp/emacs-lisp/find-func.el | 61 |
1 files changed, 40 insertions, 21 deletions
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index 455095c9be6..c2101617ac3 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el @@ -144,6 +144,16 @@ Instead of regexp variable, types can be mapped to functions as well, in which case the function is called with one argument (the object we're looking for) and it should search for it. +A value can also be a cons (REGEX . EXPANDED-FORM-MATCHER-FACTORY). +REGEX is as above; EXPANDED-FORM-MATCHER-FACTORY is a function of one +argument, the same as we'd pass to a REGEX function, that returns +another function of one argument that returns true if we're looking at a +macroexpanded form that defines what we're looking for. If you want to +use EXPANDED-FORM-MATCHER-FACTORY exclusively, you can set REGEX to a +never-match regex and force the fallback to +EXPANDED-FORM-MATCHER-FACTORY. The buffer to search is current during +the call to EXPANDED-FORM-MATCHER-FACTORY. + Symbols can have their own version of this alist on the property `find-function-type-alist'. See the function `find-function-update-type-alist'.") @@ -434,7 +444,13 @@ The search is done in the source for library LIBRARY." (regexp-symbol (or (and (symbolp symbol) (alist-get type (get symbol 'find-function-type-alist))) - (alist-get type find-function-regexp-alist)))) + (alist-get type find-function-regexp-alist))) + (form-matcher-factory + (and (functionp (cdr-safe regexp-symbol)) + (cdr regexp-symbol))) + (regexp-symbol (if form-matcher-factory + (car regexp-symbol) + regexp-symbol))) (with-current-buffer (find-file-noselect filename) (let ((regexp (if (functionp regexp-symbol) regexp-symbol (format (symbol-value regexp-symbol) @@ -474,7 +490,8 @@ The search is done in the source for library LIBRARY." ;; expands macros until it finds the symbol. (cons (current-buffer) (find-function--search-by-expanding-macros - (current-buffer) symbol type)))))))))) + (current-buffer) symbol type + form-matcher-factory)))))))))) ;;;###autoload (defun find-function-update-type-alist (symbol type variable) @@ -506,19 +523,13 @@ Return t if any PRED returns t." (find-function--any-subform-p left-child pred) (find-function--any-subform-p right-child pred)))))) -(defun find-function--search-by-expanding-macros (buf symbol type) +(defun find-function--search-by-expanding-macros + (buf symbol type matcher-factory) "Expand macros in BUF to search for the definition of SYMBOL of TYPE." - (catch 'found - (with-current-buffer buf - (save-excursion - (goto-char (point-min)) - (condition-case nil - (while t - (let ((form (read (current-buffer))) - (expected-symbol-p - (lambda (form) - (cond - ((null type) + (with-current-buffer buf + (when-let* ((expected-symbol-p + (cond ((null type) + (lambda (form) ;; Check if a given form is a `defalias' to ;; SYM, the function name we are searching ;; for. All functions in Emacs Lisp @@ -526,20 +537,28 @@ Return t if any PRED returns t." ;; after several steps of macroexpansion. (and (eq (car-safe form) 'defalias) (equal (car-safe (cdr form)) - `(quote ,symbol)))) - ((eq type 'defvar) + `(quote ,symbol))))) + ((eq type 'defvar) + (lambda (form) ;; Variables generated by macros ultimately ;; expand to `defvar'. (and (eq (car-safe form) 'defvar) - (eq (car-safe (cdr form)) symbol))) - (t nil))))) + (eq (car-safe (cdr form)) symbol)))) + (matcher-factory + (funcall matcher-factory symbol))))) + (catch 'found + (save-excursion + (goto-char (point-min)) + (condition-case nil + (while t (when (find-function--any-subform-p - (find-function--try-macroexpand form) + (find-function--try-macroexpand + (read (current-buffer))) expected-symbol-p) ;; We want to return the location at the beginning ;; of the macro, so move back one sexp. - (throw 'found (progn (backward-sexp) (point)))))) - (end-of-file nil)))))) + (throw 'found (progn (backward-sexp) (point))))) + (end-of-file nil))))))) (defun find-function-library (function &optional lisp-only verbose) "Return the pair (ORIG-FUNCTION . LIBRARY) for FUNCTION. |