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.