find-function
won't find macro-generated function definitions due to limitations of Emacs load-history
and the workarounds find-function
has to resort to.
find-function
has to explicitly search for the actual source code location of a function definition because Emacs only tracks the defining library but not the actual location of the definition during reading and evaluation. It uses the regular expression in find-function-regexp
which matches a couple of known built-in forms that define functions but knows nothing of 3rd party libraries that might also define functions.
Naturally find-function
will thus fail to find any defining form which doesn't match find-function-regexp
, which implies that it fails for almost all 3rd party macros that define functions.
You can manually add these to find-function-regexp
however.
More detailed background information follows:
To track where exactly symbol cells are filled (with function definitions for instance) Emacs would have to track source file positions in a way to preserve locations through reading up to eval
which it currently simply doesn't do—just take a look at compiled byte code (i.e. after read, but before evaluation), there are no source positions.
To be able to track loads (and thus be able to unload features and find definitions) Emacs has a load-history
instead where certain forms (such as defun
) leave entries during evaluation. When Emacs loads a library it puts a new entry into load-history
and all defun
and related forms in the library being loaded add to that entry.
But in this way Emacs only knows about the library that defined a function but not about the actual position of the source of the function within the library. find-function
has to workaround the lack of this information, and it does so in a very dumb way: It visits the source library file, goes to the beginning of the buffer… and runs a literal search for a pattern that could match the definition of the function. In other words it does C-s <THE-NAME-OF-THE-FUNCTION>
, just with a slightly more sophisticated pattern which you can actually inspect—and change, fwiw—in find-function-regexp
.
If you take a look at the pattern you'll see that it quite literally looks for certain known forms that define functions, including defun
, define-minor-mode
and a couple of related forms, and thus it'll fail to find functions defined by macros whose names don't match that pattern.