joaotavora / sly

Sylvester the Cat's Common Lisp IDE
1.24k stars 140 forks source link

Sly inspector does not seem to handle * correctly #510

Closed wsgac closed 2 years ago

wsgac commented 2 years ago

When I'm dealing with any kind of object in the REPL, e.g. a vector #(1 2 3), I can easily inspect it - either via C-c I and supplying the variable name, or by positioning the cursor at the object and hitting Enter. However, I cannot use * immediately after evaluating some expression, e.g.:

CL-USER> #(1 2 3)
#(1 2 3)
CL-USER> *
#(1 2 3)

but when I then do C-c I and type *, I get:

#<NULL {50100117}>
--------------------
Its name is: "NIL"
It is a constant of value: @1=NIL [unbind]
It has no function value.
It is external to the package: COMMON-LISP [unintern]
Property list: @1=NIL
It names a primitive type-specifier.

The same thing worked flawlessly in SLIME.

Sly version: SLY 1.0.43 SBCL 2.2.2

wsgac commented 2 years ago

UPDATE I looked into the workings of sly-inspect and was able to reduce my problem to the CL-side evaluation of (slynk:eval-for-inspector nil nil #'slynk:init-inspector "*"), which complained first about unbound slynk::*buffer-package* and then, similarly, about slynk::*buffer-readtable*. So finally I was able to produce the expected correct behavior by running:

CL-USER> (let ((slynk::*buffer-package* *package*)
           (slynk:*buffer-readtable* *readtable*))
       (slynk:eval-for-inspector nil nil #'slynk:init-inspector "*"))
(:TITLE "#<(SIMPLE-VECTOR 3) {100A46D43F}>" :ID 0 :CONTENT
 (("Dimensions" ": " (:VALUE "(3)" 1) "
"
   "Element type" ": " (:VALUE "T" 2) "
"
   "Total size" ": " (:VALUE "3" 3) "
"
   "Adjustable" ": " (:VALUE "@1=NIL" 4) "
"
   "Fill pointer" ": " (:VALUE "@1=NIL" 5) "
"
   "Contents:" "
"
   "0" ": " (:VALUE "1" 6) "
"
   "1" ": " (:VALUE "2" 7) "
"
   "2" ": " (:VALUE "3" 8) "
")
  34 0 500))

So my guess now, as to why Sly fails to produce this behavior, is that either slynk::*buffer-package*, or slynk::*buffer-readtable*, or both are incorrectly set when invoking the inspector. I'll investigate this further and report my findings.

joaotavora commented 2 years ago

Thanks for this investigation. I think supporting C-c I * RET is a very good thing, and indeed I remember that it doesn't support it. In the meantime I suggest you use the REPL, type * and then inspect the resulting presentation.

wsgac commented 2 years ago

@joaotavora Yup, that's what I'm doing for the time being.

UPDATE In order to check my above hypothesis, I modified slightly the CL code inside sly-eval-for-inspector to report on the bindings of these two variables:

`(cl-user::progn
               (cl-user::format slynk::*current-standard-output* "Package: ~a Readtable: ~a" slynk::*buffer-package* slynk::*buffer-readtable*)
               (slynk:eval-for-inspector
                       ,sly--this-inspector-name ; current inspector, if any
                       ,inspector-name  ; target inspector, if any
                       ',(car slyfun-and-args)
                       ,@(cdr slyfun-and-args)))

Re-running the experiment resulted in the following being printed to the REPL:

Package: #<PACKAGE "COMMON-LISP-USER"> Readtable: #<READTABLE {1000023A43}>

But these are the exact values of *package* and *readtable* respectively. That leaves me puzzled...

wsgac commented 2 years ago

UPDATE The trail led me to sly-eval-async, which takes an optional argument PACKAGE (but when that is not supplied, it defaults to (sly-current-package)). I tried hardcoding common-lisp-user just to be sure, but it failed. Also, I checked (sly-current-package) and it works. So my next suspicion is that somewhere inside sly-rex something might be amiss with the bindings.

joaotavora commented 2 years ago

You should first become aware of the fact that there can be multiple REPLs. So the operation C-c I * RET, which is normally associated with the minibuffer, must know where the original invocation came from.

This might not be an easy feature to implement.

wsgac commented 2 years ago

Oh, so the result of (sly-current-package) also might depend on the REPL of origin?

joaotavora commented 2 years ago

I'm not 100% sure how that Elisp function works right now (has been a while), but basically yes, different REPLs can be in different "current " packages.

wsgac commented 2 years ago

Thanks for clarifying. I'll play around some more. If I find anything promising, I'll report here.

joaotavora commented 2 years ago

Re-reading this issue, it doesn't seem like there's much that can be done in the immediate. There hasn't been much activity, so I'm closing it. If you think this should be reopened, just say so.