|
Some tricks with the load-history (preliminary title)
Introduction: two problems
This page is about this problem, that looks very important and very
much worth blogging about,
How do I find the source code of a function when the
"find function's definition" button in the page generated by `C-h f'
fails with the error "Unable to find location in
file"?
and also about this other problem, that only very eev-minded people
will find interesting:
In functions like `cl-struct-p--cmacro' the standard way to go to
their source code, that is
(find-efunction 'cl-struct-p--cmacro)
doesn't work... it opens the file in which that function is defined,
but it doesn't go to its definition. This happens because in this
case find-function-noselect doesn't return a position. Try:
(find-function-noselect 'cl-struct-p--cmacro)
(find-function-noselect 'cl-struct-p)
;; The first sexp returns: (#<buffer cl-preloaded.el>)
;; The second sexp returns: (#<buffer cl-preloaded.el> . 14565)
The docstring for `find-function-noselect' says:
Return a pair (BUFFER . POINT) pointing to the definition of FUNCTION.
Finds the source file containing the definition of FUNCTION in a
buffer and the point of the definition. The buffer is not
selected. If the function definition can't be found in the buffer,
returns (BUFFER).
The "point of the definition" of `cl-struct-p--cmacro' is not
found because that function is defined in a way that is not in the
cases supported by `find-function-search-for-symbol'. Let's use a
shorter term for these functions: they are "functions
defined in unsupported ways".
How can we create sexp hyperlinks that find the source code of
"functions defined in unsupported ways"? And how can we point to the
"exact position" in which these functions are defined, whatever that
means?
2. Three screenshots
The screenshots below explain this in a visual way:
The first screenshot shows:
- the page generated by `C-h f cl-struct-p--cmacro',
- the button that should point to its definition,
- the file in which that function is defined, and
- the error.
The second screenshot shows:
- the part of the file cl-preloaded.el that apparently defines `cl-struct-p--cmacro' - look at the
"(:predicate cl-struct-p)" inside the `cl-defstruct';
- a temporary buffer with a copy of that (cl-defstruct ...), wrapped
in a (find-eppm ...) - `find-eppm' runs `expand-macro' on its
argument, pretty-prints the result, and shows that in a temporary
buffer;
- the output of that `find-eppm'. It contains a (cl-defsubst
cl-struct-p ...), and I guess that that is what defines the
`cl-struct-p--cmacro', but at this moment I don't
know.
And the third screenshot shows:
- the top part of the definition of `find-function-search-for-symbol',
- the comment that explains one of the fallbacks that try to cover
other cases.
- the code of that fallback - that uses `re-search-forward' on a
regexp that doesn't find the "(:predicate cl-struct-p)" inside the
`cl-defstruct' in the second screenshot.
|