[slime-devel] slime-apropos-package doesn't work with readtable-case = :invert

The subject says it all, I think. I run my lisps with (setf (readtable-case *readtable*) :invert) and if I try C-c C-d C-p cl-user <RET> I get the error: No such package: "CL-USER" The reason being as follows: slime-apropos-package calls slime-read-package-name which does a completing-read on the result of (swank:list-all-package-names t) which simply returns all package names as strings: In particular, they are all typically upper case. So the package name is passed to swank:apropos-list-for-emacs which calls (find-package (string-to-package-designator package)), and swank::string-to-package-designator passes the string through read-from-string, ending with a symbol whose name is all lower case. But :|cl-user| does not designated a package. Surely, there is some inconsistency, but I can't tell which part can be corrected without introducing another inconsistency. - Harald

Harald Hanche-Olsen <hanche@math.ntnu.no> writes:
The subject says it all, I think. I run my lisps with
(setf (readtable-case *readtable*) :invert)
and if I try C-c C-d C-p cl-user <RET> I get the error:
No such package: "CL-USER"
The reason being as follows:
slime-apropos-package calls slime-read-package-name which does a completing-read on the result of (swank:list-all-package-names t) which simply returns all package names as strings: In particular, they are all typically upper case.
the "problem" here is that the completions are leading you to supply the wrong package name. I assume that if you ignored the completions and wrote the package-names yourself, in lower case, everything would Just Work right?
Surely, there is some inconsistency, but I can't tell which part can be corrected without introducing another inconsistency.
i think we can make swank:list-all-package-names smarter, but i wouldn't touch anything post completing-read (iow i wouldn't change how we process package names but, at most, how we help the user type them) -- -Marco Ring the bells that still can ring. Forget your perfect offering. There is a crack in everything. That's how the light gets in. -Leonard Cohen

+ Marco Baringer <mb@bese.it>: | the "problem" here is that the completions are leading you to supply | the wrong package name. I assume that if you ignored the completions | and wrote the package-names yourself, in lower case, everything would | Just Work right? Er, no, the completing-read upcases the package name anyway, even if I carefully avoid hitting the TAB key. In any case, it should not offer package names that will not work in the context they're going to be used anyhow. | > Surely, there is some inconsistency, but I can't tell which part can | > be corrected without introducing another inconsistency. | | i think we can make swank:list-all-package-names smarter, but i | wouldn't touch anything post completing-read (iow i wouldn't change | how we process package names but, at most, how we help the user type | them) So we're basically assuming that the user will think of package names as symbols, to be read according to the current value of (readtable-case *readtable*), and should make swank:list-all-package-names do the right thing: Invert if necessary, and escape if necessary. So if (readtable-case *readtable*) is :upcase and the package name is "foo" then what goes in the list is "|foo|". The user will have to use the initial vertical bar in order for completion to succeed, but that's a reasonable price to pay for naming packages in un-nameable ways I suppose. 8-) Oh, wait a minute. slime-repl-set-package works differently: It treats package names like strings, not symbols. Shouldn't the two functions treat package names identically? Are you suggesting we change the behaviour of slime-repl-set-package as well? - Harald

+ Harald Hanche-Olsen <hanche@math.ntnu.no>: | So we're basically assuming that the user will think of package names | as symbols, to be read according to the current value of | (readtable-case *readtable*), and should make | swank:list-all-package-names do the right thing [...] and the easiest way to do that, might be to run each package name through this function? (lambda (name) (let ((*package* *swank-io-package*)) (with-output-to-string (str) (write (intern name) :stream str)))) - Harald

* Harald Hanche-Olsen [2007-01-24 16:46+0100] writes:
+ Harald Hanche-Olsen <hanche@math.ntnu.no>:
| So we're basically assuming that the user will think of package names | as symbols, to be read according to the current value of | (readtable-case *readtable*), and should make | swank:list-all-package-names do the right thing [...]
and the easiest way to do that, might be to run each package name through this function?
(lambda (name) (let ((*package* *swank-io-package*)) (with-output-to-string (str) (write (intern name) :stream str))))
I've added something like this. Thank you for the report. Helmut.

+ Helmut Eller <heller@common-lisp.net>: | * Harald Hanche-Olsen [2007-01-24 16:46+0100] writes: | | > and the easiest way to do that, might be to run each package name | > through this function? | > | > (lambda (name) | > (let ((*package* *swank-io-package*)) | > (with-output-to-string (str) | > (write (intern name) :stream str)))) | | I've added something like this. Thank you for the report. Works well for me, thanks. And in the process, I found that it seems ok to upgrade slime on a running system: Take down the slime connection, run the commands (asdf:operate 'asdf:load-op :swank) (swank:create-server :dont-close nil) in the *inferior-lisp* buffer, reload slime.el in emacs, and top it off with M-x slime-connect. Back in business. Almost makes me wonder if there is already a feature to automate this process. - Harald

In response to my suggestion, Helmut added the function unparse-name and applied it in list-all-package-names. Turns out it needs to be applied in swank:set-package too, or else a push-directory followed by pop-directory won't work due to the wrong case being used. Patch: --- swank.lisp 25 Jan 2007 00:36:00 +0100 1.458 +++ swank.lisp 04 Feb 2007 10:13:30 +0100 @@ -2669,7 +2669,7 @@ Return its name and the string to use in the prompt." (let ((p (parse-package package))) (setq *package* p) - (list (package-name p) (package-string-for-prompt p)))) + (list (unparse-name (package-name p)) (package-string-for-prompt p)))) (defun send-repl-results-to-emacs (values) (flet ((send (value) But woe unto the person who does a push-package, changes his readtable-case and then tries a pop-package. 8-) - Harald
participants (3)
-
Harald Hanche-Olsen
-
Helmut Eller
-
Marco Baringer