[slime-devel] Minor problem

Antonio Menezes Leitao aml at gia.ist.utl.pt
Sun Feb 26 23:40:13 UTC 2006


Hi,

I would like to report a small problem in Slime.  Here is the
scenario:

1. On a lisp file, change one definition and slime-compile-defun it
   (C-c C-c).

2. Save the changed buffer.

3. Kill the saved buffer.

4. slime-edit-definition for the changed definition.

5. Emacs complains that it is trying to set-buffer on a non-existent
   buffer.

This occurs with, at least, SBCL, CMUCL, and Allegro.

As far as I can see, the problem is that the implementation of
swank-compile-string (which is used by slime-compile-defun) ignores
the buffer's filename-directory and this makes it impossible for emacs
to recover the correct file.  I agree that when we are using a buffer
that is not connected to a file, that's the proper behavior.  However,
IMHO, that's not a frequent situation.

To solve this problem for Allegro, I made the following quick (and
ugly) hack in swank-allegro.lisp:

(defimplementation swank-compile-string (string &key buffer position directory)
  ;; We store the source buffer in excl::*source-pathname* as a string
  ;; of the form <buffername>;<start-offset>.  Quite ugly encoding, but
  ;; the fasl file is corrupted if we use some other datatype.
  (with-compilation-hooks ()
    (let ((*buffer-name* buffer)
          (*buffer-start-position* position)
          (*buffer-string* string)
          (*default-pathname-defaults*
           (if directory
             (merge-pathnames (pathname directory))
             *default-pathname-defaults*)))
      (compile-from-temp-file
       (format nil "~S ~S~%~A" 
               `(in-package ,(package-name *package*))
               `(eval-when (:compile-toplevel :load-toplevel)
                 (setq excl::*source-pathname*
                  ,(format nil "~A~A;~D" (or directory "") buffer position)))
               string)))))

Then, to recover the source pathname, I changed the following
function:

(defun find-definition-in-buffer (filename)
  (let ((directory-p (find #\/ filename :from-end t)))
    (let ((pos (position #\; filename :from-end t)))
      (multiple-value-bind (name position)
          (values (subseq filename 0 pos) (parse-integer (subseq filename (1+ pos))))
        (make-location
         (if directory-p (list :file name) (list :buffer name))
         (list :position position))))))

As I said before, it's not a pretty solution :-)

Best regards,

António Leitão.



More information about the slime-devel mailing list