[slime-devel] Strange behavior in edit-definition
![](https://secure.gravatar.com/avatar/a3870a59e9b39746885d6b5efef6b388.jpg?s=120&d=mm&r=g)
Hi all, I've been experiencing some strange bugs related to the slime-show-xrefs function trying to access the 'void variable' package. This behavior occurs more or less consistently while editing (on a Linux machine) a set of files that where written using the Franz Emacs Lisp Interface on a MacOSX. Here is one example of the stacktrace: Debugger entered--Lisp error: (void-variable package) (slime-init-xref-buffer package G88189 G88190) (progn (slime-init-xref-buffer package G88189 G88190) (make-local-variable (quote slime-xref-saved-window-configuration)) (setq slime-xref-saved-window-configuration (current-window-configuration))) (prog2 (progn (slime-init-xref-buffer package G88189 G88190) (make-local-variable ...) (setq slime-xref-saved-window-configuration ...)) (progn (slime-insert-xrefs xrefs) (goto-char ...) (forward-line) (skip-chars-forward " ")) (setq buffer-read-only t) (select-window (or ... ...)) (shrink-window-if-larger-than-buffer)) (save-current-buffer (set-buffer (get-buffer-create ...)) (prog2 (progn ... ... ...) (progn ... ... ... ...) (setq buffer-read-only t) (select-window ...) (shrink-window-if-larger-than-buffer))) (with-current-buffer (get-buffer-create (format "*XREF[%s: %s]*" G88189 G88190)) (prog2 (progn ... ... ...) (progn ... ... ... ...) (setq buffer-read-only t) (select-window ...) (shrink-window-if-larger-than-buffer))) (let ((G88189 type) (G88190 symbol)) (with-current-buffer (get-buffer-create ...) (prog2 ... ... ... ... ...))) (slime-with-xref-buffer (package type symbol) (slime-insert-xrefs xrefs) (goto-char (point-min)) (forward-line) (skip-chars-forward " ")) (if (null xrefs) (message "No references found for %s." symbol) (setq slime-next-location-function (quote slime-goto-next-xref)) (slime-with-xref-buffer (package type symbol) (slime-insert-xrefs xrefs) (goto-char ...) (forward-line) (skip-chars-forward " "))) slime-show-xrefs((("expression-right-operand" ("(:OPERATOR (METHOD EXPRESSION-RIGHT-OPERAND (INFIX-EXPRESSION)))" :location ... ... nil) ("(:OPERATOR (METHOD EXPRESSION-RIGHT-OPERAND (INSTANCEOF-EXPRESSION)))" :location ... ... nil) ("(:OPERATOR (METHOD EXPRESSION-RIGHT-OPERAND :AROUND (NODE)))" :location ... ... nil) ("(:OPERATOR EXPRESSION-RIGHT-OPERAND)" :location ... ... nil))) definition "expression-right-operand" ":jnil") slime-show-definitions("expression-right-operand" (("(:OPERATOR (METHOD EXPRESSION-RIGHT-OPERAND (INFIX-EXPRESSION)))" (:location ... ... nil)) ("(:OPERATOR (METHOD EXPRESSION-RIGHT-OPERAND (INSTANCEOF-EXPRESSION)))" (:location ... ... nil)) ("(:OPERATOR (METHOD EXPRESSION-RIGHT-OPERAND :AROUND (NODE)))" (:location ... ... nil)) ("(:OPERATOR EXPRESSION-RIGHT-OPERAND)" (:location ... ... nil)))) (if (slime-length> definitions 1) (slime-show-definitions name definitions) (let (...) (destructure-case ... ... ...))) slime-goto-definition("expression-right-operand" (("(:OPERATOR (METHOD EXPRESSION-RIGHT-OPERAND (INFIX-EXPRESSION)))" (:location ... ... nil)) ("(:OPERATOR (METHOD EXPRESSION-RIGHT-OPERAND (INSTANCEOF-EXPRESSION)))" (:location ... ... nil)) ("(:OPERATOR (METHOD EXPRESSION-RIGHT-OPERAND :AROUND (NODE)))" (:location ... ... nil)) ("(:OPERATOR EXPRESSION-RIGHT-OPERAND)" (:location ... ... nil))) nil) (if (null definitions) (if slime-edit-definition-fallback-function (funcall slime-edit-definition-fallback-function name) (error "No known definition for: %s" name)) (slime-goto-definition name definitions where)) (let ((definitions ...)) (if (null definitions) (if slime-edit-definition-fallback-function ... ...) (slime-goto-definition name definitions where))) slime-edit-definition("expression-right-operand") call-interactively(slime-edit-definition) Here is (what I think is) the relevant function: (defun slime-show-xrefs (xrefs type symbol package) "Show the results of an XREF query." (if (null xrefs) (message "No references found for %s." symbol) (setq slime-next-location-function 'slime-goto-next-xref) (slime-with-xref-buffer (package type symbol) (slime-insert-xrefs xrefs) (goto-char (point-min)) (forward-line) (skip-chars-forward " \t")))) This function uses the macro slime-with-xref-buffer: (defmacro* slime-with-xref-buffer ((package ref-type symbol) &body body) "Execute BODY in a xref buffer, then show that buffer." (let ((type (gensym)) (sym (gensym))) `(let ((,type ,ref-type) (,sym ,symbol)) (with-current-buffer (get-buffer-create (format "*XREF[%s: %s]*" ,type ,sym)) (prog2 (progn (slime-init-xref-buffer ,package ,type ,sym) (make-local-variable 'slime-xref-saved-window-configuration) (setq slime-xref-saved-window-configuration (current-window-configuration))) (progn ,@body) (setq buffer-read-only t) (select-window (or (get-buffer-window (current-buffer) t) (display-buffer (current-buffer) t))) (shrink-window-if-larger-than-buffer)))))) I confess that I couldn't identify the cause for the bug. However, I noticed that the macrocall expands into a (with-current-buffer ... (slime-init-xref-buffer package ...)) and maybe it was that 'package' variable being referenced after changing to a different buffer that was causing the problem. An hard to believe explanation, I'm sure, but just in case, I experimented replacing that 'package' variable by another gensym, using: (defmacro* slime-with-xref-buffer ((package ref-type symbol) &body body) "Execute BODY in a xref buffer, then show that buffer." (let ((type (gensym)) (sym (gensym)) (pkg (gensym))) `(let ((,type ,ref-type) (,sym ,symbol) (,pkg ,package)) (with-current-buffer (get-buffer-create (format "*XREF[%s: %s]*" ,type ,sym)) (prog2 (progn (slime-init-xref-buffer ,pkg ,type ,sym) (make-local-variable 'slime-xref-saved-window-configuration) (setq slime-xref-saved-window-configuration (current-window-configuration))) (progn ,@body) (setq buffer-read-only t) (select-window (or (get-buffer-window (current-buffer) t) (display-buffer (current-buffer) t))) (shrink-window-if-larger-than-buffer)))))) and after redefining slime-show-xrefs, everything worked OK. Maybe a Slime expert can understand the problem. Best regards, António Leitão.
![](https://secure.gravatar.com/avatar/4b09f3ff1f75487b361645fd66b9bfd8.jpg?s=120&d=mm&r=g)
Antonio Menezes Leitao <aml@gia.ist.utl.pt> writes:
and maybe it was that 'package' variable being referenced after changing to a different buffer that was causing the problem. An hard to believe explanation, I'm sure, but just in case, I experimented replacing that 'package' variable by another gensym, using:
I can believe that. The reason for problems like this are those -*- package: ... -*- file variables. This make package a buffer local variable in Emacs and interacts badly dynamic bindings. E.g.: (progn (make-variable-buffer-local 'my-var) (setq my-var 1) (message "%s" my-var) (let ((my-var 2)) (message "%s" my-var) (with-temp-buffer (message "%s" my-var)))) my-var in the temp buffer is nil. One would think that a simple rule like: first search let-bound variables, then buffer local variables and then global variables would avoid such problems but this is obviously not what Emacs does. It's probably a good idea to avoid the -*- package: ... -*- thing as the file has probably a in-package form already or a least rename it to Package. I committed you change. Thanks. Helmut.
![](https://secure.gravatar.com/avatar/a3870a59e9b39746885d6b5efef6b388.jpg?s=120&d=mm&r=g)
Hi, Helmut Eller <heller@common-lisp.net> writes:
Antonio Menezes Leitao <aml@gia.ist.utl.pt> writes:
and maybe it was that 'package' variable being referenced after changing to a different buffer that was causing the problem. An hard to believe explanation, I'm sure, but just in case, I experimented replacing that 'package' variable by another gensym, using:
I can believe that. The reason for problems like this are those -*- package: ... -*- file variables. This make package a buffer local variable in Emacs and interacts badly dynamic bindings. E.g.:
(progn (make-variable-buffer-local 'my-var) (setq my-var 1) (message "%s" my-var) (let ((my-var 2)) (message "%s" my-var) (with-temp-buffer (message "%s" my-var))))
my-var in the temp buffer is nil. One would think that a simple rule like: first search let-bound variables, then buffer local variables and then global variables would avoid such problems but this is obviously not what Emacs does.
It's probably a good idea to avoid the -*- package: ... -*- thing as the file has probably a in-package form already or a least rename it to Package.
I committed you change. Thanks.
Here's another one that is causing problems: (defun slime-repl-set-package (package) "Set the package of the REPL buffer to PACKAGE." (interactive (list (slime-read-package-name "Package: " (slime-find-buffer-package)))) (with-current-buffer (slime-output-buffer) (let ((unfinished-input (slime-repl-current-input))) (destructuring-bind (name prompt-string) (slime-eval `(swank:set-package ,package)) (setf (slime-lisp-package) name) (setf (slime-lisp-package-prompt-string) prompt-string) (slime-repl-insert-prompt "" 0) (insert unfinished-input))))) Again, using pkg in place of package solves the problem but, as you explained, the problem seems to be on Emacs and not on Slime. Thanks for the explanation. António Leitão.
participants (2)
-
Antonio Menezes Leitao
-
Helmut Eller