vim-fireplace/autoload/fireplace/nrepl_connection.vim

157 lines
4.3 KiB
VimL
Raw Normal View History

2014-07-04 20:06:43 +00:00
" Location: autoload/nrepl/fireplace_connection.vim
2012-12-04 06:06:22 +00:00
2013-03-12 19:37:37 +00:00
if exists("g:autoloaded_nrepl_fireplace_connection") || &cp
2012-12-04 06:06:22 +00:00
finish
endif
2013-03-12 19:37:37 +00:00
let g:autoloaded_nrepl_fireplace_connection = 1
2012-12-04 06:06:22 +00:00
2014-01-07 03:41:03 +00:00
let s:python_dir = fnamemodify(expand("<sfile>"), ':p:h:h:h') . '/python'
2012-12-04 06:06:22 +00:00
function! s:function(name) abort
return function(substitute(a:name,'^s:',matchstr(expand('<sfile>'), '<SNR>\d\+_'),''))
endfunction
" Bencode {{{1
2014-06-27 15:17:13 +00:00
function! fireplace#nrepl_connection#bencode(value) abort
2012-12-04 06:06:22 +00:00
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([])
2014-06-27 15:17:13 +00:00
return 'l'.join(map(copy(a:value),'fireplace#nrepl_connection#bencode(v:val)'),'').'e'
2012-12-04 06:06:22 +00:00
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'
2012-12-04 06:06:22 +00:00
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'
2012-12-04 06:06:22 +00:00
else
let escaped = shellescape(a:arg)
if &shell =~# 'sh' && &shell !~# 'csh'
return substitute(escaped, '\\\n', '\n', 'g')
else
return escaped
endif
endif
endfunction
2014-01-08 01:03:06 +00:00
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
2014-06-27 15:17:13 +00:00
function! fireplace#nrepl_connection#prompt() abort
2013-03-12 19:37:37 +00:00
return fireplace#input_host_port()
2012-12-04 06:06:22 +00:00
endfunction
2014-06-27 15:17:13 +00:00
function! fireplace#nrepl_connection#open(arg) abort
2012-12-04 06:06:22 +00:00
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)
2012-12-04 06:06:22 +00:00
endfunction
function! s:nrepl_transport_close() dict abort
2014-01-09 01:40:42 +00:00
return self
endfunction
let s:keepalive = tempname()
call writefile([getpid()], s:keepalive)
function! s:nrepl_transport_command(cmd, args) dict abort
2014-01-08 05:50:46 +00:00
return 'python'
2014-01-07 03:41:03 +00:00
\ . ' ' . s:shellesc(s:python_dir.'/nrepl_fireplace.py')
\ . ' ' . s:shellesc(self.host)
\ . ' ' . s:shellesc(self.port)
\ . ' ' . s:shellesc(s:keepalive)
\ . ' ' . s:shellesc(a:cmd)
2014-06-27 15:17:13 +00:00
\ . ' ' . join(map(copy(a:args), 's:shellesc(fireplace#nrepl_connection#bencode(v:val))'), ' ')
2014-01-08 05:50:46 +00:00
endfunction
function! s:nrepl_transport_dispatch(cmd, ...) dict abort
let in = self.command(a:cmd, a:000)
2012-12-04 06:06:22 +00:00
let out = system(in)
if !v:shell_error
return eval(out)
2012-12-04 06:06:22 +00:00
endif
2014-01-07 03:41:03 +00:00
throw 'nREPL: '.out
2012-12-04 06:06:22 +00:00
endfunction
function! s:nrepl_transport_call(msg, terms, sels, ...) dict abort
2014-06-27 15:17:13 +00:00
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')}
2012-12-04 06:06:22 +00:00
2014-01-08 04:26:26 +00:00
if !has('python') || $FIREPLACE_NO_IF_PYTHON
finish
endif
2014-01-07 03:41:03 +00:00
if !exists('s:python')
exe 'python sys.path.insert(0, "'.escape(s:python_dir, '\"').'")'
2014-01-07 03:41:03 +00:00
let s:python = 1
python import nrepl_fireplace
else
python reload(nrepl_fireplace)
endif
python << EOF
import vim
2013-03-12 19:37:37 +00:00
def fireplace_let(var, value):
return vim.command('let ' + var + ' = ' + nrepl_fireplace.vim_encode(value))
2014-01-07 03:41:03 +00:00
def fireplace_check():
vim.eval('getchar(1)')
def fireplace_repl_dispatch(command, *args):
try:
2014-01-08 04:53:20 +00:00
fireplace_let('out', nrepl_fireplace.dispatch(vim.eval('self.host'), vim.eval('self.port'), fireplace_check, None, command, *args))
2014-01-07 03:41:03 +00:00
except Exception, e:
fireplace_let('err', str(e))
EOF
function! s:nrepl_transport_dispatch(command, ...) dict abort
python fireplace_repl_dispatch(vim.eval('a:command'), *vim.eval('a:000'))
if !exists('err')
return out
endif
throw 'nREPL Connection Error: '.err
endfunction