Quick
index
main
eev
eepitch
maths
angg
blogme
dednat6
littlelangs
PURO
(C2,C3,C4,
 λ,ES,
 GA,MD,
 Caepro,
 textos,
 Chapa 1)

emacs
lua
(la)tex
maxima
git
agda
forth
squeak
icon
tcl
tikz
fvwm
debian
irc
contact

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.