1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2025-12-15 10:30:25 -08:00

* doc/lispref: new node "Finding Definitions"

How to use variable 'find-function-regexp-alist',
properties 'definition-name' and 'find-function-type-alist',
and function 'find-function-update-type-alist' to help Emacs
locate the definition of objects defined by macros.

This material is moved from node "Standard Properties" and expanded.
This commit is contained in:
Stephen Gildea 2025-01-22 18:27:26 -08:00
parent 331bcfaee5
commit aa6d2a396a
5 changed files with 97 additions and 62 deletions

View file

@ -15,6 +15,7 @@ define them.
* Lambda Expressions:: How functions are expressed as Lisp objects.
* Function Names:: A symbol can serve as the name of a function.
* Defining Functions:: Lisp expressions for defining functions.
* Finding Definitions:: Finding function definitions created by macros.
* Calling Functions:: How to use an existing function.
* Mapping Functions:: Applying a function to each element of a list, etc.
* Anonymous Functions:: Lambda expressions are functions with no names.
@ -832,6 +833,97 @@ and tells the Lisp compiler to perform inline expansion on it.
To undefine a function name, use @code{fmakunbound}.
@xref{Function Cells}.
@menu
* Finding Definitions:: Finding function definitions created by macros.
@end menu
@node Finding Definitions
@subsection Finding Definitions
Tools such as Emacs's built-in help command @kbd{C-h f} (@pxref{Help,,,
emacs, The GNU Emacs Manual}) can find the definition site of functions
and other Lisp objects in the source code. To do this, they use the
variable @code{find-function-regexp-alist}.
@vindex @code{find-function-regexp-alist}
The alist @code{find-function-regexp-alist} associates object types with
a regexp or function that finds the definition of that object in its
source file. Each element's car is a symbol the describes the type of
object, or @code{nil} to identify functions defined with @code{defun}.
Each element's cdr is a symbol: either the value of that symbol is a
string interpreted as a regexp, or that symbol names a function that can
find the definition.
A regexp string is actually a format string, and @code{%s} will be
substituted with the name of the symbol we are looking for.
A function will be called with one argument, the (symbol for) the object
we are searching for.
@cindex @code{definition-name} (symbol property)
If the function to be found is defined by a macro, it may be hard for
Emacs to find the definition site in the source code. A macro call may
have an unexpected look to it, and @code{find-function-regexp-alist}
will fail to identify the definition.
For example, a @code{define-derived-mode} (@pxref{Derived Modes}) might
define a mode-specific function or a variable implicitly; or your Lisp
program might generate a run-time call to @code{defun} to define a
function. In these and similar cases, the @code{definition-name}
property of the symbol should be another symbol whose definition can be
found by textual search and whose code defines the original symbol. In
the example with @code{define-derived-mode}, the value of this property
of the functions and variables it defines should be the mode symbol.
@cindex @code{find-function-type-alist} (symbol property)
In some cases, the definition cannot be found by looking for the
definition of another symbol. For example, a test file might use a
macro to generate calls to @code{ert-deftest} (@pxref{How to Write
Tests,,,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{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.
The @code{find-function-regexp-alist} property is most easily maintained
with the convenience function @code{find-function-update-type-alist}.
@defun find-function-update-type-alist symbol type variable
Update property @code{find-function-type-alist} of @var{symbol} with
a new element containing key @var{type} and value @var{variable}.
@end defun
In the example of a macro defining calls to @code{ert-deftest},
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:
@example
@group
(defmacro define-foo-test (data)
"Define a test of the foo system using DATA."
(declare (debug (&rest sexp)))
(let ((test-name (intern (concat ...))))
`(progn
(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."
(let ((regexp ...))
(re-search-forward regexp nil t)))
@end group
@end example
@node Calling Functions
@section Calling Functions
@cindex function invocation