Skip to content

Commit 4ce1f8f

Browse files
committed
Python all the way
1 parent fa4e0ed commit 4ce1f8f

File tree

5 files changed

+64
-45
lines changed

5 files changed

+64
-45
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
/doc/tags
2+
*.pyc

README.markdown

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ to multiple instances of nREPL for different projects, and it will use the
3737
right one automatically.
3838

3939
The only external dependency is that you have either a Vim with Python support
40-
compiled in, or `ruby` in your path. (Don't ask.)
40+
compiled in, or `python` in your path.
4141

4242
Oh, and if you don't have an nREPL connection, installing [classpath.vim][]
4343
lets it fall back to using `java clojure.main`, using a class path based on

autoload/nrepl/fireplace_connection.vim

Lines changed: 23 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ if exists("g:autoloaded_nrepl_fireplace_connection") || &cp
66
endif
77
let g:autoloaded_nrepl_fireplace_connection = 1
88

9+
let s:python_dir = fnamemodify(expand("<sfile>"), ':p:h:h:h') . '/python'
10+
911
function! s:function(name) abort
1012
return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\d\+_'),''))
1113
endfunction
@@ -197,22 +199,16 @@ function! s:extract_last_stacktrace(nrepl)
197199
endfunction
198200

199201
function! s:nrepl_call(payload) dict abort
200-
let in = 'ruby -rsocket -e '.s:shellesc(
201-
\ 'begin;' .
202-
\ 'TCPSocket.open(%(' . self.host . '), ' . self.port . ') {|s|' .
203-
\ 's.write(ARGV.first); loop {' .
204-
\ 'body = s.readpartial(8192);' .
205-
\ 'raise %(not an nREPL server: upgrade to Leiningen 2) if body =~ /=> $/;' .
206-
\ 'print body;' .
207-
\ 'break if body =~ /6:statusl(5:error|14:session-closed)?4:done/ }};' .
208-
\ 'rescue; abort $!.to_s;' .
209-
\ 'end') . ' ' .
210-
\ s:shellesc(nrepl#fireplace_connection#bencode(a:payload))
202+
let in = 'python'
203+
\ . ' ' . s:shellesc(s:python_dir.'/nrepl_fireplace.py')
204+
\ . ' ' . s:shellesc(self.host)
205+
\ . ' ' . s:shellesc(self.port)
206+
\ . ' ' . s:shellesc(nrepl#fireplace_connection#bencode(a:payload))
211207
let out = system(in)
212208
if !v:shell_error
213209
return nrepl#fireplace_connection#bdecode('l'.out.'e')
214210
endif
215-
throw 'nREPL: '.split(out, "\n")[0]
211+
throw 'nREPL: '.out
216212
endfunction
217213

218214
let s:nrepl = {
@@ -225,12 +221,16 @@ if !has('python')
225221
finish
226222
endif
227223

224+
if !exists('s:python')
225+
exe 'python sys.path.insert(0, "'.s:python_dir.'")'
226+
let s:python = 1
227+
python import nrepl_fireplace
228+
else
229+
python reload(nrepl_fireplace)
230+
endif
231+
228232
python << EOF
229233
import vim
230-
import select
231-
import socket
232-
import string
233-
import re
234234

235235
def fireplace_string_encode(input):
236236
str_list = []
@@ -244,38 +244,19 @@ def fireplace_string_encode(input):
244244
def fireplace_let(var, value):
245245
return vim.command('let ' + var + " = " + fireplace_string_encode(value))
246246

247+
def fireplace_check():
248+
vim.eval('getchar(1)')
249+
247250
def fireplace_repl_interact():
248-
buffer = ''
249-
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
250-
host = vim.eval('self.host')
251-
port = int(vim.eval('self.port'))
252-
s.settimeout(8)
253251
try:
254-
try:
255-
s.connect((host, port))
256-
s.setblocking(1)
257-
s.sendall(vim.eval('payload'))
258-
while True:
259-
while len(select.select([s], [], [], 0.1)[0]) == 0:
260-
vim.eval('getchar(1)')
261-
body = s.recv(8192)
262-
if re.search("=> $", body) != None:
263-
raise Exception("not an nREPL server: upgrade to Leiningen 2")
264-
buffer += body
265-
if re.search('6:statusl(5:error|14:session-closed)?4:done', body):
266-
break
267-
fireplace_let('out', buffer)
268-
except Exception, e:
269-
fireplace_let('err', str(e))
270-
finally:
271-
s.close()
252+
fireplace_let('out', nrepl_fireplace.repl_send(vim.eval('self.host'), int(vim.eval('self.port')), vim.eval('payload'), fireplace_check))
253+
except Exception, e:
254+
fireplace_let('err', str(e))
272255
EOF
273256

274257
function! s:nrepl_call(payload) dict abort
275258
let payload = nrepl#fireplace_connection#bencode(a:payload)
276-
python << EOF
277-
fireplace_repl_interact()
278-
EOF
259+
python fireplace_repl_interact()
279260
if !exists('err')
280261
return nrepl#fireplace_connection#bdecode('l'.out.'e')
281262
endif

doc/fireplace.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@ buffer and classpath.vim is installed, java (or $JAVA_CMD) is invoked
2626
directly, which can be quite slow depending on your setup.
2727

2828
The only adapter shipped with fireplace.vim is for nREPL. You need either
29-
|if_pyth| or the ruby command in your PATH. (This curious combination is an
30-
accident of history.)
29+
|if_pyth| or the python command in your PATH.
3130

3231
LEININGEN *fireplace-leiningen*
3332

python/nrepl_fireplace.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import sys
2+
import select
3+
import socket
4+
import re
5+
6+
def repl_send(host, port, payload, callback):
7+
buffer = ''
8+
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
9+
s.settimeout(8)
10+
try:
11+
s.connect((host, port))
12+
s.setblocking(1)
13+
s.sendall(payload)
14+
while True:
15+
while len(select.select([s], [], [], 0.1)[0]) == 0:
16+
callback()
17+
body = s.recv(8192)
18+
if re.search("=> $", body) != None:
19+
raise Exception("not an nREPL server: upgrade to Leiningen 2")
20+
buffer += body
21+
if re.search('6:statusl(5:error|14:session-closed)?4:done', body):
22+
break
23+
return buffer
24+
finally:
25+
s.close()
26+
27+
def noop():
28+
pass
29+
30+
def main(host, port, payload):
31+
try:
32+
sys.stdout.write(repl_send(host, int(port), payload, noop))
33+
except Exception, e:
34+
print(e)
35+
exit(1)
36+
37+
if __name__ == "__main__":
38+
main(*sys.argv[1:])

0 commit comments

Comments
 (0)