From 863fd1c276549fd70cd765e56f73d9649759ab90 Mon Sep 17 00:00:00 2001 From: Stephen Gildea Date: Thu, 16 Jan 2025 15:33:12 -0800 Subject: [PATCH] Property definition-type becomes find-function-type-alist lisp/emacs-lisp/find-func.el (find-function-search-for-symbol): Use symbol property 'find-function-type-alist' instead of 'definition-type' (find-function-update-type-alist): New convenience function. * doc/lispref/symbols.texi (Standard Properties): Update example to use 'find-function-type-alist' and 'find-function-update-type-alist' * doc/lispref/functions.texi (Defining Functions): * doc/lispref/tips.texi (Coding Conventions): * doc/misc/ert.texi (How to Write Tests): * etc/NEWS: Change reference to 'definition-type' to name 'find-function-type-alist' instead --- doc/lispref/functions.texi | 2 +- doc/lispref/symbols.texi | 45 +++++++++++++++--------------------- doc/lispref/tips.texi | 2 +- doc/misc/ert.texi | 2 +- etc/NEWS | 11 +++++---- lisp/emacs-lisp/find-func.el | 27 +++++++++++++++------- 6 files changed, 48 insertions(+), 41 deletions(-) diff --git a/doc/lispref/functions.texi b/doc/lispref/functions.texi index bad3c926b27..2b5847d2f64 100644 --- a/doc/lispref/functions.texi +++ b/doc/lispref/functions.texi @@ -754,7 +754,7 @@ to find the source code because generating a function dynamically usually looks very different from the usual static calls to @code{defun}. You can make the job of finding the code that generates such functions easier by using the @code{definition-name} -or @code{definition-type} property, @pxref{Standard Properties}. +or @code{find-function-type-alist} property, @pxref{Standard Properties}. @cindex override existing functions @cindex redefine existing functions diff --git a/doc/lispref/symbols.texi b/doc/lispref/symbols.texi index 508ee13a244..5ac2a32dba0 100644 --- a/doc/lispref/symbols.texi +++ b/doc/lispref/symbols.texi @@ -536,9 +536,9 @@ Do not set them directly; they are managed by @code{defcustom} and related functions. @xref{Variable Definitions}. @cindex @code{definition-name} (symbol property) -@cindex @code{definition-type} (symbol property) +@cindex @code{find-function-type-alist} (symbol property) @item definition-name -@itemx definition-type +@itemx find-function-type-alist These properties help find the definition of a symbol in the source code when it might be hard to find the definition by textual search of the source file. @@ -563,16 +563,19 @@ definition of another symbol. For example, a test file might use a macro to generate calls to @code{ert-deftest} (@pxref{,,,ert, ERT: Emacs Lisp Regression Testing}) where the code is boiler plate and only varying data need to be passed in. -In such cases, the @code{definition-type} property of the symbol can -be a symbol that has an entry in @code{find-function-regexp-alist} +In such cases, the @code{find-function-type-alist} property of the +symbol can be an alist that augments @code{find-function-regexp-alist} telling how to find the definition of symbols of this type. In the example of a macro defining calls to @code{ert-deftest}, -the macro could put the property @code{definition-type} on each -test defined. The file defining the macro would also define a -definition-finding function or regexp and add it to -@code{find-function-regexp-alist} after that variable is loaded. -Here is an example using a function to find the definition: +the macro could put the property @code{find-function-type-alist} on each +test defined, associating @code{ert--test} (the internal type of ERT +tests) with the name of a regexp or function that can find the correct +macro call. The file defining the macro would also have to provide that +definition-finding function or regexp. +Here is an example using a function to find the definition. +The example updates the property using convenience function +@code{find-function-update-type-alist}. @example @group @@ -581,29 +584,19 @@ Here is an example using a function to find the definition: (declare (debug (&rest sexp))) (let ((test-name (intern (concat ...)))) `(progn - (put ',test-name 'definition-type 'foo-test-type) - (ert-deftest ,test-name () - ,(concat "Test foo with " ...) - ...)))) + (find-function-update-type-alist + ',test-name 'ert--test 'foo-find-test-def-function) + (ert-deftest ,test-name () + ,(concat "Test foo with " ...) + ...)))) @end group @group (defun foo-find-test-def-function (test-name) "Search for the `define-foo-test' call defining TEST-NAME. Return non-nil if the definition is found." - (save-match-data - (let ((regexp ...)) - (save-restriction - (widen) - (goto-char (point-min)) - (re-search-forward regexp nil t))))) -@end group - -@group -(with-eval-after-load "find-func" - (add-to-list - 'find-function-regexp-alist - '(foo-test-type . foo-find-test-def-function))) + (let ((regexp ...)) + (re-search-forward regexp nil t))) @end group @end example diff --git a/doc/lispref/tips.texi b/doc/lispref/tips.texi index c2fba3cba8d..1bf52886971 100644 --- a/doc/lispref/tips.texi +++ b/doc/lispref/tips.texi @@ -228,7 +228,7 @@ definition automatically. Avoid constructing the names in the macro itself, since that would confuse these tools. If your macro cannot be written in this style, the macro can still help these tools find the defining call by putting the property -@code{definition-name} or @code{definition-type} on the name. +@code{definition-name} or @code{find-function-type-alist} on the name. @xref{Standard Properties}. @item diff --git a/doc/misc/ert.texi b/doc/misc/ert.texi index c8aac971ec7..0e03afc98ff 100644 --- a/doc/misc/ert.texi +++ b/doc/misc/ert.texi @@ -524,7 +524,7 @@ find where a test was defined only if the test was loaded from a file. If the test definition is generated by a macro, the macro may want to help ERT find the defining call to the macro by putting the property -@code{definition-type} on the test name. +@code{find-function-type-alist} on the test name. @xref{Standard Properties,,,elisp, GNU Emacs Lisp Reference Manual}. diff --git a/etc/NEWS b/etc/NEWS index 9efe16da791..e86bb80cec8 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1175,11 +1175,14 @@ It offers a more concise way to create a completion table with metadata. ** 'all-completions' and 'unintern' no longer support old calling conventions. +++ -** New symbol property 'definition-type' used by 'find-function' and friends. +** New symbol property 'find-function-type-alist' used by 'find-function' etc. Macros that define an object in a way that makes the object's name and -the macro call site defining the object hard to associate can put the -property 'definition-type' on the object's name to provide instructions -for finding the definition. +the macro call site defining the object hard to associate can add an +entry to the property 'find-function-type-alist' on the object's name to +provide instructions for finding the definition. + +New convenience function 'find-function-update-type-alist' offers a +concise way to update a symbol's 'find-function-type-alist' property. * Changes in Emacs 31.1 on Non-Free Operating Systems diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index 40bcdfe756a..c367d4a3624 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el @@ -152,7 +152,11 @@ Each regexp variable's value should actually be a format string to be used to substitute the desired symbol name into the regexp. 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.") +we're looking for) and it should search for it. + +Symbols can have their own version of this alist on +the property `find-function-type-alist'. +See the function `find-function-update-type-alist'.") (put 'find-function-regexp-alist 'risky-local-variable t) (define-obsolete-variable-alias 'find-function-source-path @@ -402,9 +406,9 @@ or just (BUFFER . nil) if the definition can't be found in the file. If TYPE is nil, look for a function definition, otherwise, TYPE specifies the kind of definition. -If SYMBOL has a property `definition-type', -the property value is used instead of TYPE. -TYPE is interpreted via `find-function-regexp-alist'. +TYPE is looked up in SYMBOL's property `find-function-type-alist' +(which can be maintained with `find-function-update-type-alist') +or the variable `find-function-regexp-alist'. The search is done in the source for library LIBRARY." (if (null library) @@ -413,9 +417,6 @@ The search is done in the source for library LIBRARY." ;; that defines something else. (while (and (symbolp symbol) (get symbol 'definition-name)) (setq symbol (get symbol 'definition-name))) - (setq type (or (and (symbolp symbol) - (get symbol 'definition-type)) - type)) (if (string-match "\\`src/\\(.*\\.\\(c\\|m\\)\\)\\'" library) (find-function-C-source symbol (match-string 1 library) type) (when (string-match "\\.el\\(c\\)\\'" library) @@ -425,7 +426,10 @@ The search is done in the source for library LIBRARY." (when (string-match "\\.emacs\\(.el\\)\\'" library) (setq library (substring library 0 (match-beginning 1)))) (let* ((filename (find-library-name library)) - (regexp-symbol (cdr (assq type find-function-regexp-alist)))) + (regexp-symbol + (or (and (symbolp symbol) + (alist-get type (get symbol 'find-function-type-alist))) + (alist-get type find-function-regexp-alist)))) (with-current-buffer (find-file-noselect filename) (let ((regexp (if (functionp regexp-symbol) regexp-symbol (format (symbol-value regexp-symbol) @@ -467,6 +471,13 @@ The search is done in the source for library LIBRARY." (find-function--search-by-expanding-macros (current-buffer) symbol type)))))))))) +;;;###autoload +(defun find-function-update-type-alist (symbol type variable) + "Update SYMBOL property `find-function-type-alist' with (TYPE . VARIABLE). +Property `find-function-type-alist' is a symbol-specific version +of variable `find-function-regexp-alist' and has the same format." + (setf (alist-get type (get symbol 'find-function-type-alist)) variable)) + (defun find-function--try-macroexpand (form) "Try to macroexpand FORM in full or partially. This is a best-effort operation in which if macroexpansion fails,