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.
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
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
If you take a look at the pattern you'll see that it quite literally looks for certain known forms that define functions, including
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.