kovisoft / slimv

Official mirror of Slimv versions released on vim.org
454 stars 60 forks source link

Swank can't create directory #56

Open tormaroe opened 7 years ago

tormaroe commented 7 years ago

I have a new installation of gVim on Windows and added the slimv plugin. Getting an issue when trying to connect to swank server. Tried to manually debug by starting SBCL from the bundle directory and do:

(load "swank-loader.lisp")
(swank-loader:init)

Getting this error:

;;
;; Error ???ing c:/Users/tormar/vimfiles/bundle/slimv/slime/packages.lisp:
\;   Can't create directory c:\Users\tormar\.slime\fasl\2.18
;;

debugger invoked on a SB-INT:SIMPLE-FILE-ERROR in thread
#<THREAD "main thread" RUNNING {23F74541}>:
\ Can't create directory c:\Users\tormar\.slime\fasl\2.18

Type HELP for debugger help, or (SB-EXT:EXIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [RETRY   ] Retry directory creation.
  1: [CONTINUE] Continue as if directory creation was successful.
  2: [ABORT   ] Exit debugger, returning to top level.

/sbcl-1.3.0-win32-x86/packages.fasl" :VERBOSE NIL :MODE 511)8
0] 2
;
; compilation unit aborted
;   caught 1 fatal ERROR condition

Path c:\Users\tormar\.slime\fasl\ exist (from previously experimenting with slime from Sublime Text), even tried with manually adding 2.18. Also tried running SBCL as administrator.

Any idea what the problem might be, and how to solve this?

SBCL version 1.3.0.

kovisoft commented 7 years ago

Is it possible that the fasl file mentioned in the error message (/sbcl-1.3.0-win32-x86/packages.fasl) was compiled by another lisp system/version and that the fasl file is incompatible with your current sbcl version? Could you please delete the packages.fasl file (and perhaps any other .fas and .fasl files) and then retry? Those files will be regenerated anyway when you start the swank server.

tormaroe commented 7 years ago

I deleted everything under c:\Users\tormar.slime\fasl\, including a sbcl-1.3.0-win32-x86 folder. Trying to load swank yields the same result. Nothing is now generated under c:\Users\tormar.slime\fasl\, and nowhere else can I find a sbcl-1.3.0-win32-x86 folder, even though error output remains the same.

VariableVictor commented 7 years ago
;; Error ???ing d:/Soft/Vim/bundle/slimv/slime/packages.lisp:
/".  Can't create directory "C:/Users/ZhuChenkai/.slime/fasl/2.18
;;
/".rror: Can't create directory "C:/Users/ZhuChenkai/.slime/fasl/2.18
> While executing: ENSURE-DIRECTORIES-EXIST, in process listener(1).
> Type :GO to continue, :POP to abort, :R for a list of available restarts.
> If continued: Skip loading "d:/Soft/Vim/bundle/slimv/slime/start-swank.lisp"
> Type :? for other options.
1 >

I can't create the directory about fasl either, And I use the CCL rather then SBCL

kovisoft commented 7 years ago

First of all I must admit that I'm not quite familiar with the swank and sbcl/ccl code, I just "borrowed" the swank server code from SLIME. The swank server should be able to run in sbcl/ccl even without slimv (but of course there may also be a problem in the way how slimv starts it).

The header of slime/swank-loader.lisp contains this comment:

;; If you want customize the source- or fasl-directory you can set
;; swank-loader:*source-directory* resp. swank-loader:*fasl-directory*
;; before loading this files.
;; E.g.:
;;
;;   (load ".../swank-loader.lisp")
;;   (setq swank-loader::*fasl-directory* "/tmp/fasl/")
;;   (swank-loader:init)

So I'd like to ask you to check what happens when you set swank-loader::*fasl-directory* to a directory of your choice (one that your user has write access to). You can do this by modifying slime/start-swank.lisp by adding the setq line before the (swank-loader:init ...) call:

(load (merge-pathnames "swank-loader.lisp" *load-truename*))

(setq swank-loader::*fasl-directory* "/your_custom_fasl_directory_goes_here")
(swank-loader:init
 :delete nil         ; delete any existing SWANK packages
 :reload nil         ; reload SWANK, even if the SWANK package already exists
 :load-contribs nil) ; load all contribs

Does this help?

VariableVictor commented 7 years ago

Hello, I got the code of slime/slime in github,and replace the file swank-loder.lisp in slimv with the file in slime version v2.18. Then,the swank server can be launched successfully. So, I think it was the difference between this 2 file cause the problem. I have upload the swank-loader.lisp (only filetypes like zip can be uploaded,so I compressed it),please have a look. swank-loader.zip

Wish you a maseterpiece.

kovisoft commented 7 years ago

@VariableVictor Thank you, this information was very useful. The difference between 2.18 and 2.19 versions of swank-loader.lisp is the way the swank version string is generated. In 2.18 it was taken from slime/ChangeLog and it was actually a date of form YYYY-MM-DD. Since 2.19 it's a normal X.XX type version string taken from slime/slime.el. As I see, the version string is then used to generate the fasl directory path: user-home-directory/.slime/fasl/version-string. If the version string is not found for some reason then a unique directory name is generated. I guess that when you replaced swank-loader.lisp with the 2.18 version then the version string was actually not found (there is no slime/ChangeLog file any longer), and therefore a unique directory name was generated for you. It seems that your lisp liked that directory so swank did not complain and started successfully. But even if the swank server started, slimv will not function properly because slimv also needs a proper swank version string.

Could you please tell me what fasl directory was generated for you when finally swank started? Please type these in the swank window:

(cl:in-package :swank-loader)
(slime-version-string)
*fasl-directory*
(default-fasl-dir)
VariableVictor commented 7 years ago

The directory it made is "C:\Users\ZhuChenkai.slime\fasl\clozure-version_1.11-r16635__(windowsx8632)-windows-x86"

kovisoft commented 7 years ago

Thanks. So there is no swank version information in the fasl directory, this probably means that (slime-version-string) returned nil, right?

I have no idea why this directory is accepted by your lisp and why the other one containing the swank version is rejected. Anyway, now that we have a directory that works, could you please try my suggestion above about manually setting a custom fasl directory? Please restore the original version of swank-loader.lisp and modify start-swank.lisp by adding the below setq line:

(load (merge-pathnames "swank-loader.lisp" *load-truename*))

(setq swank-loader::*fasl-directory* "C:/Users/ZhuChenkai.slime/fasl/clozure-version_1.11-r16635__(windowsx8632)-windows-x86")
(swank-loader:init
 :delete nil         ; delete any existing SWANK packages
 :reload nil         ; reload SWANK, even if the SWANK package already exists
 :load-contribs nil) ; load all contribs

Does this work? (I'm not sure about using forward or backward slashes)

kovisoft commented 7 years ago

Sorry, you need to add a slash (/) at the end of the fasl directory path, otherwise the leaf if treated as a file. So this is the correct test case, I tried it on my Windows machine with CCL and it worked (but for me the default setting works too):

(load (merge-pathnames "swank-loader.lisp" *load-truename*))

(setq swank-loader::*fasl-directory* "C:/Users/ZhuChenkai.slime/fasl/clozure-version_1.11-r16635__(windowsx8632)-windows-x86/")
(swank-loader:init
 :delete nil         ; delete any existing SWANK packages
 :reload nil         ; reload SWANK, even if the SWANK package already exists
 :load-contribs nil) ; load all contribs
elevatorsimulator commented 7 years ago

I had the same issue trying to load to connect to the SWANK server (Windows 7; slimv = commit acf9b30be71c54... version). Trying to understand the cause of this issue, I tried calling ensure-directories-exist manually to see why it failed to create a directory.

Apparently, the problem wasn't due to missing file permissions, as I successfully managed to create a directory from the REPL. However, it turns out that directory names must be terminated by a separator (\ in this case). For example, evaluating

(ensure-directories-exist "c:\\Users\\foo\\.slime\\fasl\\2.19")

did not create a directory, while

(ensure-directories-exists "c:\\Users\\foo\\.slime\\fasl\\2.19\\")

did. Judging from the initial error message Can't create directory c:\Users\tormar\.slime\fasl\2.18, it seems that the trailing separator was missing. In fact, loading swank-loader.lisp manually and evaluating (default-fasl-dir) results in the following strange output

/sbcl-1.3.18-win32-x86-64/"ime/fasl/2.19
kovisoft commented 7 years ago

Could you please load swank-loader.lisp (manually if automatic startup doesn't work). Then please go into the REPL window, set package to swank-loader (press ,g in the REPL window and enter the package name), then please evaluate the below s-expressions. What is the output?

(slime-version-string)

(unique-dir-name)

(user-homedir-pathname)

(make-pathname
 :directory `(:relative ".slime" "fasl"
              ,@(if (slime-version-string) (list (slime-version-string)))
              ,(unique-dir-name)))

(merge-pathnames
 (make-pathname
  :directory `(:relative ".slime" "fasl"
               ,@(if (slime-version-string) (list (slime-version-string)))
               ,(unique-dir-name)))
 (user-homedir-pathname))

(default-fasl-dir)
elevatorsimulator commented 7 years ago

I get the following.

(slime-version-string)
"2.19^M"

(unique-dir-name)
"sbcl-1.3.18-windows-x86-64"

(user-homedir-pathname)
#P"C:/Users/foo/"

(make-pathname
 :directory `(:relative ".slime" "fasl"
              ,@(if (slime-version-string) (list (slime-version-string)))
              ,(unique-dir-name)))
#P".slime/fasl/2.19^M/sbcl-1.3.18-windows-x86-64/"

(merge-pathnames
 (make-pathname
  :directory `(:relative ".slime" "fasl"
               ,@(if (slime-version-string) (list (slime-version-string)))
               ,(unique-dir-name)))
 (user-homedir-pathname))
#P"C:/Users/foo/.slime/fasl/2.19^M/sbcl-1.3.18-windows-x86-64/"

(default-fasl-dir)
#P"C:/Users/foo/.slime/fasl/2.19^M/sbcl-1.3.18-windows-x86-64/"

This I get when evaluating the forms in the SLIME-REPL. When manually loading swank-loader.lisp into SBCL and evaluating it from the SBCL-REPL, I get this:

(slime-version-string)
"2.19"

(unique-dir-name)
"sbcl-1.3.18-windows-x86-64"

(user-homedir-pathname)
#P"C:/Users/foo/"

(make-pathname
 :directory `(:relative ".slime" "fasl"
              ,@(if (slime-version-string) (list (slime-version-string)))
              ,(unique-dir-name)))
/sbcl-1.3.18-win32-x86-64/"

(merge-pathnames
 (make-pathname
  :directory `(:relative ".slime" "fasl"
               ,@(if (slime-version-string) (list (slime-version-string)))
               ,(unique-dir-name)))
 (user-homedir-pathname))
/sbcl-1.3.18-windows-x86-64/"ime/fasl/2.19

(default-fasl-dir)
/sbcl-1.3.18-windows-x86-64/"ime/fasl/2.19

Finally, trying to evaluate (ensure-directories-exist (default-fasl-dir)) from the SLIME-REPL results in the following error

Can't create directory C:\Users\foo\.slime\fasl\2.19^M\
      [Condition of type SB-INT:SIMPLE-FILE-ERROR]

Evaluating (ensure-directories-exist #P"C:/Users/foo/.slime/fasl/2.19/sbcl-1.3.18-windows-x86-64/") on the other hand succeeds.

kovisoft commented 7 years ago

Thank you. Now I think I see what the problem is. There is a carriage return character (^M) at the end of the slime version string, and that ^M also appears in the fasl directory name that was built up. The slime version string is taken from line 6 of slime.el (e.g ;; Version: 2.19). Normally slime.el is a unix format text file, i.e. lines end with the line feed (0x0A, ^@) character. In a dos (windows) format text file lines end with the carriage return (0x0D, ^M) plus the line feed (0x0A, ^@) character-pair. Therefore when a dos-format file is read on linux, then each line will get an extra ^M at the end.

I think something similar happened here: for some reason your slime.el file was converted from unix to dos format. Please check the line endings in a hex editor. If this is the case then the solution is to convert slime.el back to unix format.

If you read a file into vim, you can check the file format with :set fileformat?. If this displays fileformat=dos then you can convert it to unix format with this command: set fileformat=unix, then you need to save the file.

elevatorsimulator commented 7 years ago

Yes, you were right. The file slime.el was indeed in fileformat=dos. Maybe this was because I cloned directly from the git repo. Maybe git converted it to dos format.

Just checked: git config core.autocrlf reports true. When I checked out from the repo, it therefore must have automatically converted all LFs to CRLFs.