Closed kendagriff closed 6 years ago
That's weird. You should check if :echo has('python')
is 1
, as shelling out is flakier.
Thanks for replying: it's echoing 0
. I'm using MacVim—does that mean it's not supporting Python?
Yes. It might support has('python3')
, in which case you can try swapping out python
for python3
in autoload/fireplace/nrepl_connection.vim
and see if that helps.
Thank you. Here's my attempt to update the vimscript:
" Location: autoload/nrepl/fireplace_connection.vim
if exists("g:autoloaded_nrepl_fireplace_connection") || &cp
finish
endif
let g:autoloaded_nrepl_fireplace_connection = 1
let s:python_dir = fnamemodify(expand("<sfile>"), ':p:h:h:h') . '/python'
function! s:function(name) abort
return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '.*\zs<SNR>\d\+_'),''))
endfunction
" Bencode {{{1
function! fireplace#nrepl_connection#bencode(value) abort
if type(a:value) == type(0)
return 'i'.a:value.'e'
elseif type(a:value) == type('')
return strlen(a:value).':'.a:value
elseif type(a:value) == type([])
return 'l'.join(map(copy(a:value),'fireplace#nrepl_connection#bencode(v:val)'),'').'e'
elseif type(a:value) == type({})
return 'd'.join(map(
\ sort(keys(a:value)),
\ 'fireplace#nrepl_connection#bencode(v:val) . ' .
\ 'fireplace#nrepl_connection#bencode(a:value[v:val])'
\ ),'').'e'
else
throw "Can't bencode ".string(a:value)
endif
endfunction
" }}}1
function! s:shellesc(arg) abort
if a:arg =~ '^[A-Za-z0-9_/.-]\+$'
return a:arg
elseif &shell =~# 'cmd'
throw 'Python interface not working. See :help python-dynamic'
else
let escaped = shellescape(a:arg)
if &shell =~# 'sh' && &shell !~# 'csh'
return substitute(escaped, '\\\n', '\n', 'g')
else
return escaped
endif
endif
endfunction
if !exists('s:id')
let s:vim_id = localtime()
let s:id = 0
endif
function! s:id() abort
let s:id += 1
return 'fireplace-'.hostname().'-'.s:vim_id.'-'.s:id
endfunction
function! fireplace#nrepl_connection#prompt() abort
return fireplace#input_host_port()
endfunction
function! fireplace#nrepl_connection#open(arg) abort
if a:arg =~# '^\d\+$'
let host = 'localhost'
let port = a:arg
elseif a:arg =~# ':\d\+$'
let host = matchstr(a:arg, '.*\ze:')
let port = matchstr(a:arg, ':\zs.*')
else
throw "nREPL: Couldn't find [host:]port in " . a:arg
endif
let transport = deepcopy(s:nrepl_transport)
let transport.host = host
let transport.port = port
return fireplace#nrepl#for(transport)
endfunction
function! s:nrepl_transport_close() dict abort
return self
endfunction
let s:keepalive = tempname()
call writefile([getpid()], s:keepalive)
function! s:nrepl_transport_command(cmd, args) dict abort
return 'python3'
\ . ' ' . s:shellesc(s:python_dir.'/nrepl_fireplace.py')
\ . ' ' . s:shellesc(self.host)
\ . ' ' . s:shellesc(self.port)
\ . ' ' . s:shellesc(s:keepalive)
\ . ' ' . s:shellesc(a:cmd)
\ . ' ' . join(map(copy(a:args), 's:shellesc(fireplace#nrepl_connection#bencode(v:val))'), ' ')
endfunction
function! s:nrepl_transport_dispatch(cmd, ...) dict abort
let in = self.command(a:cmd, a:000)
let out = system(in)
if !v:shell_error
return eval(out)
endif
throw 'nREPL: '.out
endfunction
function! s:nrepl_transport_call(msg, terms, sels, ...) dict abort
let payload = fireplace#nrepl_connection#bencode(a:msg)
let response = self.dispatch('call', payload, a:terms, a:sels)
if !a:0
return response
elseif a:1 !=# 'ignore'
return map(response, 'fireplace#nrepl#callback(v:val, "synchronous", a:000)')
endif
endfunction
let s:nrepl_transport = {
\ 'close': s:function('s:nrepl_transport_close'),
\ 'command': s:function('s:nrepl_transport_command'),
\ 'dispatch': s:function('s:nrepl_transport_dispatch'),
\ 'call': s:function('s:nrepl_transport_call')}
if !has('python3') || $FIREPLACE_NO_IF_PYTHON
finish
endif
if !exists('s:python')
exe 'python3 sys.path.insert(0, "'.escape(s:python_dir, '\"').'")'
let s:python = 1
python3 import nrepl_fireplace
else
python3 reload(nrepl_fireplace)
endif
python3 << EOF
import vim
def fireplace_let(var, value):
return vim.command('let ' + var + ' = ' + nrepl_fireplace.vim_encode(value))
def fireplace_check():
vim.eval('getchar(1)')
def fireplace_repl_dispatch(command, *args):
try:
fireplace_let('out', nrepl_fireplace.dispatch(vim.eval('self.host'), vim.eval('self.port'), fireplace_check, None, command, *args))
except Exception, e:
fireplace_let('err', str(e))
EOF
function! s:nrepl_transport_dispatch(command, ...) dict abort
python3 fireplace_repl_dispatch(vim.eval('a:command'), *vim.eval('a:000'))
if !exists('err')
return out
endif
throw 'nREPL Connection Error: '.err
endfunction
Upon form evaluation, I get the following error:
Error detected while processing /Users/kendallbuchanan/dotfiles/vim/bundle/vim-fireplace/autoload/fireplace/nrepl_connection.vim:
line 148:
File "<string>", line 12
Which seems related to this section of the Python script:
def fireplace_repl_dispatch(command, *args):
try:
fireplace_let('out', nrepl_fireplace.dispatch(vim.eval('self.host'), vim.eval('self.port'), fireplace_check, None, command, *args))
except Exception, e:
fireplace_let('err', str(e))
Looks to me like you found the line that handles the error, not the line that causes it. I'm not really a Python person so my ability to help here is limited. But I can say this used to work with Python 3.
K, thanks... Knowing it's related to Python is a big help. I'll report back when I know more.
Python was indeed the culprit. I reinstalled macvim w/ support for both versions:
$ brew tap macvim-dev/macvim
$ brew install --HEAD macvim-dev/macvim/macvim --with-properly-linked-python2-python3
And everything's peachy again.
(Source: https://github.com/macvim-dev/macvim/wiki/Python-2.x-and-Python-3.x)
I upgraded to Vim 8.1.1 and the newest vim-fireplace, and performance has dropped substantially. The first time an exception is thrown from Clojure, it may wait 30 seconds before the REPL responds. From then on exceptions are three or four seconds. Properly evaluated forms respond in about 500ms. Not crazy slow, but slow enough to notice.
Any suggestions for isolating the problem?