tpope / vim-fireplace

fireplace.vim: Clojure REPL support
https://www.vim.org/scripts/script.php?script_id=4978
1.75k stars 139 forks source link

Connect error: unexpected end of bencode data^@ #139

Closed ywangd closed 10 years ago

ywangd commented 10 years ago

I am having trouble connecting to nREPL. Fireplace gives the error as nREPL: unexpected end of bencode data^@

Is it something related to the firewall? But I am able to connect to the nREPL server using Eclipse.

tpope commented 10 years ago

Typically this means nREPL had an error midway through response. Are you running lein repl? Check it for errors.

ywangd commented 10 years ago

Yes I am running lei repl Not sure how to check it for errors ... hint please?

But I had a look at the python code nrepl_fireplace.py and found out the message it passes to the socket seems to be erroneous.

The main function is called when a clojure file is loaded. The argument args was set to ('228:d2:id35:fireplace-CSSVIC006531-1395282542-24:code116:(do (println ""success"") (symbol (str (System/getProperty ""path.separator"") (System/getProperty ""java.class.path""))))7:session36:8f6c9b0c-e602-42d2-9806-f59eec4ee8782:op4:evale', 'l4:donee', 'd2:id35:fireplace-CSSVIC006531-1395282542-2e')

The message has a wrong count (6 characters short) for the code string length. The leading number 228 shall be 234 and the number 116 immediately after code shall be 122.

I manually fixed that and get a new error message as the follows:

E716: Key not present in Dictionary: new-session E15: Invalid expression: client.process({'op': 'clone', 'session': 0})['new-session']

ywangd commented 10 years ago

I just noticed the double double-quote pattern ("") in the message. They are where the 6 characters come from. I added a crude fix in the python code to replace "" with " and now it works!

tpope commented 10 years ago

Sounds like broken shell escaping. This is Windows? What does :set shell? shellslash? report?

tpope commented 10 years ago

Actually we have our own custom shell escaping for Windows. You might try tweaking this line. Start with shellescape(a:arg).

Related: #41

tpope commented 10 years ago

Another source of inspiration: https://github.com/tpope/vim-dispatch/blob/acfd302ffab5b67dc7a3498c107c844f70d9ee5c/autoload/dispatch/windows.vim#L8-17

ywangd commented 10 years ago

Yes Windows 7 x64. :set shell? shellslash? gives shell=C:\Windows\System32\cmd.exe noshellslash

I don't really know much about vim scripting. I'll see what I can do to mess up with the code :)

ywangd commented 10 years ago

So I found the easy solution: In file fireplace_connection.vim change line return '"'.substitute(substitute(a:arg, '"', '""""', 'g'), '%', '"%"', 'g').'"' to return '"'.substitute(substitute(a:arg, '"', '"""', 'g'), '%', '"%"', 'g').'"'

i.e., Four consecutive double-quotes became three.

Now the startup is fine and cqc, cqp work normaly. But cpp does not work. The error message is as follows: nrepl_transport_dispath: Can't open file C:\Users\ywangd\AppData\Local\Temp\1\VIoB4c0.tmp Error detected while processing function 37_Eval: Missing :endif

tpope commented 10 years ago

Had to make the opposite change the last time this came up, so I know it won't work for everyone.

Can you tell me the values of :set shellquote? shellxquote? shellxescape?

ywangd commented 10 years ago
shellquote=
shellxquote=(
shellxescape="&|<>()@^
tpope commented 10 years ago

Can you try the dispatch_escape branch and report back on your success there?

ywangd commented 10 years ago

I assume you mean the branch starts with let escaped = shellescape(a:arg) Yes it worked.

tpope commented 10 years ago

Actually I meant the branch I just pushed to the repository; please try that.

ywangd commented 10 years ago

With the new branch, it just keeps giving out an error message as Can't open file C:\Users\ywangd\AppData\Local\Temp\1\VioF988.tmp

ywangd commented 10 years ago

There really was no such file in the temp directory. For an example, when the error message says it cannot find VIo36B6.tmp I only see VIG36B4.tmp and VIH36B5.tmp in the temp directory.

tpope commented 10 years ago

"No such file" typically just means a syntax error so bad the shell couldn't even parse the redirect. I guess since that escaping algorithm was designed for :! rather than system() it's not that surprising it wouldn't work.

@raymond-w-ko any thoughts on why this would differ from our experience? My VM is kaput so I can't easily test right now.

tpope commented 10 years ago

@ywangd it just occurred to me that if you get the Vim Python interface working (such that :echo has('python') returns 1), you could sidestep this whole mess and get a better experience to boot. Make sure you have the right architecture of Python installed (32 bit Python unless :echo has('win64') is 1) and in you path.

ywangd commented 10 years ago

I tested the plugin on another windows 7 x64 machine and it worked straight away. I am not sure why it didn't work on the previous windows machine. Maybe it's just vim external calls are not really designed for Windows.

I don't really get what you mean by sidestep this whole mess and get a better experience to boot. I do have 32 bit python and 32 bit vim. What am I supposed to do?

tpope commented 10 years ago

I'd guess (or at least hope) there's a difference in one of those shell options we could check and leverage. If you can compare the two maybe we can put the issue to rest once and for all.

Fireplace can either shell out to Python, or call Python directly using the Vim interface to it. The latter is an infinitely better experience but won't work unless has('python') is true.

ywangd commented 10 years ago

The Windows machine where the plugin works has the following shell options

shell=C:\Windows\system32\cmd.exe
noshellslash    
shellquote=
shellxquote=(
shellxescape="&|<>()@^

They are the same as those from the other windows machines. Please let me know if there are more options you wanna check.

I do have :echo has('python') = 1 and :echo has('win64') = 0. However, the system python is a 64-bit one. I can install a 32-bit version. Once I have the 32bit python installed, will fireplace automatically detects that and choose to use Vim interface for python calls? Or do I need to setup some options?

tpope commented 10 years ago

Yes, it will detect it automatically. But if has('python') is 1, then it sounds like things are already working properly.

ywangd commented 10 years ago

I just found out: On the windows machine where fireplace did not work straight away, has('python') is 0. This is because I recently installed the latest 7.4 (32-bit) which has only dynamic python support (+python/dyn), while my system python is 64-bit. Vim 7.3, on the contrary, has static python support (+python), and this is the case on the other windows machine.

So the solution really is to install a 32-bit system python and fireplace just worked. Sorry for all the confusions. You may now close this issue. Thanks!

L1fescape commented 10 years ago

Just ran into a similar issue on Arch. vim --version showed no python support. Uninstalled vim, downloaded it (via ftp://ftp.gr.vim.org/pub/vim/unix/vim-7.4.tar.bz2), then configured it with --enable-pythoninterp --with-features=huge. Seems to be working!

tpope commented 10 years ago

Similar or the same? Shelling out should work fine on Linux.

L1fescape commented 10 years ago

The same issue.

tpope commented 10 years ago

I'm in a much better position to debug UNIX shell escaping if anyone wants to pursue. Start with the value of :set shell?.

johnpmayer commented 10 years ago

Thanks for this write up, I also had to downgrade to vim73-64 on Windows 8

tpope commented 10 years ago

Vim 7.3/7.4 might be the key difference, actually.

tpope commented 10 years ago

I've disabled the broken shell escaping behavior on Windows and instead throw an error if if_pyth isn't available. That's a much better experience on Windows anyways so not a big sacrifice.