I'd like to make M-. work in abcl, and it looks like it wouldn't be too hard to record source file name, kind (ie. function, macro, etc.), and approximate file-position ("the next form after this position") info in fasl files. Exact file-position is doable, but harder.
Ideally, what information is expected from swank-backend:find-definitions, and how accurate should it be? Is there a minimal subset which slime can go by? Which lisp/swank backend has the best support for M-.?
Andras
Andras Simon andras@renyi.hu writes:
I'd like to make M-. work in abcl, and it looks like it wouldn't be too hard to record source file name, kind (ie. function, macro, etc.), and approximate file-position ("the next form after this position") info in fasl files. Exact file-position is doable, but harder.
Ideally, what information is expected from swank-backend:find-definitions, and how accurate should it be? Is there a minimal subset which slime can go by? Which lisp/swank backend has the best support for M-.?
[FIND-DEFINITIONS returns a list of dspec/location pairs. 'dspec' is just some description of the definition that makes sense to the user, e.g. "variable foo". 'location' tells Emacs how to find the source: basically the buffer and the offset in the buffer. We support different kinds of locations.]
Ideally, Lisp tells us exactly this: the name of the buffer and the position.
The minimal information we can handle at the moment, is the filename together with the name of the definition. In this case, Emacs opens the file and jumps to the first occurrence of a "(def.* <name>". We can also add something like "skip to the first expression after some position".
CMUCL/SBCL have probably the best support. I don't now the internals for LispWorks or Allegro, so I can't quite tell.
For functions compiled from a file, CMUCL records the filename, file-offset, the "toplevel form number", and the "form number". The toplevel form number is the number of the toplevel form as seen by the reader [comments and #+nil-ed expressions are not counted]. Form numbers are assigned with a top-down, left-right walk across the expression tree. With some trickery it's possible to translate those numbers to file positions. That's what the code in swank-source-path-parser.lisp is good for. Form numbers are in principle redundant if we have the file-offset, but form numbers are more robust against small edits. Form numbers can also be used to find the "current expression" in the debugger [i.e. not only the toplevel form].
CMUCL has also special support to compile from a stream (not only from a file) and can add user supplied info to functions compiled from a stream. We use that to implement C-c C-c: we record the buffer name, the offset in the buffer, and the toplevel form as string.
For interpreted functions or for functions created with COMPILE, CMUCL records the entire source expression. Recently, we added source location recording for variables: the form numbers for variables are recorded in an extra table. The source location information for functions is attached to function objects; similar for classes.
IIUC, Allegro, LispWorks, and OpenMCL only record some description, like (defmethod foo (bla)), together with the filename. To find the position, the file is READ until the description is found. The approach is simple and relatively robust against edits, but doesn't work so well for macros, e.g. defstruct. LispWorks has an interface to tell the parser how to handle user defined macros, but this must be done for each macro.
Helmut.