Luke Gorrie wrote:
First consider the case where the source file hasn't been changed but the Emacs buffer has. The new idea is: since Lisp pulls up the source and finds the exact right position, how about grabbing the opening snippet of the function (a hundred bytes, say) and sending it to Emacs as a "hint"? Then Emacs can jump to the hopefully-right position and then do a bi-directional isearch for the longest match of the actual function prelude.
That is certainly better than using only the name and "kind" (defun defvar ...) of the definition. It seems to me that using a good hash code over the entire s-expression of the definition would be even better. In that way, if there are multiple definitions (the original definition and one or more alternate definitions being tested, or reader-macro conditioned definitions), they can be distinguished.
This solution seems near ideal, but it does only work when Lisp can find the source file version that the code was compiled from. If it ever finds such a version then it caches the whole file in the Lisp image so that the next `C-x C-s' won't spoil the fun. Files will go into the cache the first time you M-. into them -- probably it would be better to suck them in as soon as they enter slime-mode, but I haven't tried that yet.
Now for the case where the file on disk has been changed. Source-paths can tollerate a bit of this but it does get nasty easily, e.g. M-. on CMUCL symbols usually doesn't work for me because I run random binaries but always against the CVS sources, and usually land one or two defuns away from the real definition.
It would be useful if the underlying lisp implementation could be convinced to include more source location information in the compiled object file. In this way, source version info, such as RCSID, and/or file date and time stored in the object file. In the absence of RCSID, file date and time could be useful in determining the source file version associated with the object file. Similarly, the sexpr hash code could be stored for each definition in object file.
For this case it now just detects that the file is modified and falls back to regexp-based search, the same way e.g. the OpenMCL backend works. This seems to work pretty well. I also tweaked the regexps a bit, hopefully for the better.
Unfortunately, using totally different strategies for finding the definition source depending on whether the file has changed, is likely to lead to confusion for the user, as is often the situation with Ilisp. There are several things that might improve the situation:
a) Provide a "confidence" indication about the source code that is found. For an unchanged buffer, or exact match of the hash-code of the resulting source code, the confidence should be "very high". Also provide an indication when there are other possible matches for the definition.
b) Provide two forms of EDIT-DEFINITION:
. EDIT-CURRENT-DEFINITION attempts to find the definition that matches the currently loaded definition. (This is presently called EDIT-DEFINITION).
. EDIT-ALL-DEFINITIONS finds all definitions of the symbol and "kind" (defvar, defun, defmethod, ...), including reader-match conditioned definitions which fail. It might be useful to flag each definition in the *XREF[definition: xxx]* buffer with the confidence score that it is the "current definition".