Hi,
I would like to propose an small improvement to slime-edit-definition
so that it correctly identifies setf forms (which it doesn't, at the
moment).
The change is limited to the interactive pseudo-call. Instead of
(defun slime-edit-definition (name &optional where)
"Lookup the definition of the name at point.
If there's no name at point, or a prefix argument is given, then the
function name is prompted."
(interactive (list (slime-read-symbol-name "Name: ")))
...)
use
(defun slime-edit-definition (name &optional where)
"Lookup the definition of the name at point.
If there's no name at point, or a prefix argument is given, then the
function name is prompted."
(interactive (list (slime-edit-definition-query (slime-extract-context))))
...)
The function slime-edit-definition-query is just a stripped down
version of slime-trace-query:
(defun slime-edit-definition-query (spec)
"Ask the user which function to edit; SPEC is the default.
The result is a string."
(cond ((null spec)
(slime-read-from-minibuffer "Name: "))
((symbolp spec)
(symbol-name spec))
(t
(destructure-case spec
((setf n)
(prin1-to-string spec))
(((:defun :defmacro :defgeneric) n)
(prin1-to-string n))
((:defmethod n &rest _)
(prin1-to-string n))
((:call caller callee)
(prin1-to-string callee))
(((:labels :flet) &rest _)
(slime-read-from-minibuffer "Name: "))))))
That would be enough, if it were not for the fact that, in some cases,
Slime is not correctly identifying the relevant context information.
One reason seems to be the slime-in-expression-p function. Here are a
few examples (the . is the cursor):
(defun zdzz () (setfabble-p fo.o)) -> (:defun (setf foo))
(defun zdzz () (setfab.ble-p foo)) -> (:defun (setf setfabble-p))
(defmacro-transform bla () (bo.o)) -> (:call (:defmacro bla) boo)
(defmacro-transform b.la () (boo)) -> (:defmacro bla)
(defmacro-tran.sform bla () (boo)) -> (:defmacro defmacro-transform)
(defunia (bsd.o)) -> (:call (:defun (bsdo)) bsdo)
(defun.ia (bsdo)) -> (:defun defunia)
One problem is the (looking-at (symbol-name p)) form in
slime-in-expression-p that, obviously, is happy even if the symbol
being searched only _partially_ matches the actual text. So either we
replace it with something similar to
(looking-at (concat (symbol-name p) "\\S_"))
or, in order to deal with end-of-buffer limits, with something similar
to
(let ((symbol
(buffer-substring-no-properties
(point)
(save-excursion (forward-sexp 1) (point)))))
(string= symbol (symbol-name p)))
With this change, the examples now produce:
(defun zdzz () (setfabble-p fo.o)) -> foo
(defun zdzz () (setfab.ble-p foo)) -> (:call (:defun zdzz) setfabble-p)
(defmacro-transform bla () (bo.o)) -> (:call bla boo)
(defmacro-transform b.la () (boo)) -> bla
(defmacro-tran.sform bla () (boo)) -> (:call bla defmacro-transform)
(defunia (bsd.o)) -> (:call (bsdo) bsdo)
(defun.ia (bsdo)) -> (:call (bsdo) defunia)
It's better but there are still some problems, visible in the last
three examples. Fortunately, they don't severely affect what I want
to do and, besides, I'm not sure about the inner workings of the
slime-in-expression-p function (it seems incomplete, imho), so I'll
leave it that way for now.
BTW, this was only superficially tested, but it seems to work.
Best regards,
António Leitão.