Generalize call and add message abstraction
This commit is contained in:
parent
40bad28354
commit
fc0ab71587
@ -98,7 +98,7 @@ function! s:nrepl_close() dict abort
|
|||||||
if has_key(self, 'session')
|
if has_key(self, 'session')
|
||||||
try
|
try
|
||||||
unlet! g:nrepl_fireplace_sessions[self.session]
|
unlet! g:nrepl_fireplace_sessions[self.session]
|
||||||
call self.call({'op': 'close'})
|
call self.message({'op': 'close'})
|
||||||
catch //
|
catch //
|
||||||
finally
|
finally
|
||||||
unlet self.session
|
unlet self.session
|
||||||
@ -111,9 +111,9 @@ function! s:nrepl_path() dict abort
|
|||||||
return split(self._path[1:-1], self._path[0])
|
return split(self._path[1:-1], self._path[0])
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:nrepl_process(payload) dict abort
|
function! s:nrepl_process(responses) dict abort
|
||||||
let combined = {'status': [], 'session': []}
|
let combined = {'status': [], 'session': []}
|
||||||
for response in self.call(a:payload)
|
for response in self.message(a:responses)
|
||||||
for key in keys(response)
|
for key in keys(response)
|
||||||
if key ==# 'id' || key ==# 'ns'
|
if key ==# 'id' || key ==# 'ns'
|
||||||
let combined[key] = response[key]
|
let combined[key] = response[key]
|
||||||
@ -143,35 +143,35 @@ function! s:nrepl_process(payload) dict abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:nrepl_eval(expr, ...) dict abort
|
function! s:nrepl_eval(expr, ...) dict abort
|
||||||
let payload = {"op": "eval"}
|
let msg = {"op": "eval"}
|
||||||
let payload.code = a:expr
|
let msg.code = a:expr
|
||||||
let options = a:0 ? a:1 : {}
|
let options = a:0 ? a:1 : {}
|
||||||
if has_key(options, 'ns')
|
if has_key(options, 'ns')
|
||||||
let payload.ns = options.ns
|
let msg.ns = options.ns
|
||||||
elseif has_key(self, 'ns')
|
elseif has_key(self, 'ns')
|
||||||
let payload.ns = self.ns
|
let msg.ns = self.ns
|
||||||
endif
|
endif
|
||||||
if has_key(options, 'session')
|
if has_key(options, 'session')
|
||||||
let payload.session = options.session
|
let msg.session = options.session
|
||||||
endif
|
endif
|
||||||
if has_key(options, 'file_path')
|
if has_key(options, 'file_path')
|
||||||
let payload.op = 'load-file'
|
let msg.op = 'load-file'
|
||||||
let payload['file-path'] = options.file_path
|
let msg['file-path'] = options.file_path
|
||||||
let payload['file-name'] = fnamemodify(options.file_path, ':t')
|
let msg['file-name'] = fnamemodify(options.file_path, ':t')
|
||||||
if has_key(payload, 'ns')
|
if has_key(msg, 'ns')
|
||||||
let payload.file = "(in-ns '".payload.ns.") ".payload.code
|
let msg.file = "(in-ns '".msg.ns.") ".msg.code
|
||||||
call remove(payload, 'ns')
|
call remove(msg, 'ns')
|
||||||
else
|
else
|
||||||
let payload.file = payload.code
|
let msg.file = msg.code
|
||||||
endif
|
endif
|
||||||
call remove(payload, 'code')
|
call remove(msg, 'code')
|
||||||
endif
|
endif
|
||||||
let response = self.process(payload)
|
let response = self.process(msg)
|
||||||
if has_key(response, 'ns') && !a:0
|
if has_key(response, 'ns') && !a:0
|
||||||
let self.ns = response.ns
|
let self.ns = response.ns
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if has_key(response, 'ex') && !empty(get(payload, 'session', 1))
|
if has_key(response, 'ex') && !empty(get(msg, 'session', 1))
|
||||||
let response.stacktrace = s:extract_last_stacktrace(self)
|
let response.stacktrace = s:extract_last_stacktrace(self)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -184,9 +184,9 @@ endfunction
|
|||||||
function! s:extract_last_stacktrace(nrepl) abort
|
function! s:extract_last_stacktrace(nrepl) abort
|
||||||
let format_st = '(clojure.core/symbol (clojure.core/str "\n\b" (clojure.core/apply clojure.core/str (clojure.core/interleave (clojure.core/repeat "\n") (clojure.core/map clojure.core/str (.getStackTrace *e)))) "\n\b\n"))'
|
let format_st = '(clojure.core/symbol (clojure.core/str "\n\b" (clojure.core/apply clojure.core/str (clojure.core/interleave (clojure.core/repeat "\n") (clojure.core/map clojure.core/str (.getStackTrace *e)))) "\n\b\n"))'
|
||||||
let stacktrace = split(get(split(a:nrepl.process({'op': 'eval', 'code': '['.format_st.' *3 *2 *1]', 'session': a:nrepl.session}).value[0], "\n\b\n"), 1, ""), "\n")
|
let stacktrace = split(get(split(a:nrepl.process({'op': 'eval', 'code': '['.format_st.' *3 *2 *1]', 'session': a:nrepl.session}).value[0], "\n\b\n"), 1, ""), "\n")
|
||||||
call a:nrepl.call({'op': 'eval', 'code': '(nth *1 1)', 'session': a:nrepl.session})
|
call a:nrepl.message({'op': 'eval', 'code': '(nth *1 1)', 'session': a:nrepl.session})
|
||||||
call a:nrepl.call({'op': 'eval', 'code': '(nth *2 2)', 'session': a:nrepl.session})
|
call a:nrepl.message({'op': 'eval', 'code': '(nth *2 2)', 'session': a:nrepl.session})
|
||||||
call a:nrepl.call({'op': 'eval', 'code': '(nth *3 3)', 'session': a:nrepl.session})
|
call a:nrepl.message({'op': 'eval', 'code': '(nth *3 3)', 'session': a:nrepl.session})
|
||||||
return stacktrace
|
return stacktrace
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@ -212,42 +212,59 @@ function! s:nrepl_dispatch(cmd, ...) dict abort
|
|||||||
throw 'nREPL: '.out
|
throw 'nREPL: '.out
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:nrepl_prepare(payload) dict abort
|
function! s:nrepl_prepare(msg) dict abort
|
||||||
let payload = copy(a:payload)
|
let msg = copy(a:msg)
|
||||||
if !has_key(payload, 'id')
|
if !has_key(msg, 'id')
|
||||||
let payload.id = s:id()
|
let msg.id = s:id()
|
||||||
endif
|
endif
|
||||||
if empty(get(payload, 'session', 1))
|
if empty(get(msg, 'session', 1))
|
||||||
unlet payload.session
|
unlet msg.session
|
||||||
elseif !has_key(self, 'session')
|
elseif !has_key(self, 'session')
|
||||||
if &verbose
|
if &verbose
|
||||||
echohl WarningMSG
|
echohl WarningMSG
|
||||||
echo "nREPL: server has bug preventing session support"
|
echo "nREPL: server has bug preventing session support"
|
||||||
echohl None
|
echohl None
|
||||||
endif
|
endif
|
||||||
unlet! payload.session
|
unlet! msg.session
|
||||||
elseif !has_key(payload, 'session')
|
elseif !has_key(msg, 'session')
|
||||||
let payload.session = self.session
|
let msg.session = self.session
|
||||||
endif
|
endif
|
||||||
return payload
|
return msg
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:nrepl_call(payload, ...) dict abort
|
function! nrepl#fireplace_connection#callback(body, fn)
|
||||||
let payload = self.prepare(a:payload)
|
let response = {'body': a:body}
|
||||||
let response = filter(self.dispatch('call', nrepl#fireplace_connection#bencode(payload)), 'v:val.id == payload.id')
|
if has_key(a:body, 'session')
|
||||||
if a:0
|
let response.session = g:nrepl_fireplace_sessions[a:body.session]
|
||||||
call map(response, 'call(a:1, v:val)')
|
endif
|
||||||
|
call call(a:fn, [response])
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:nrepl_call(msg, ...) dict abort
|
||||||
|
let payload = nrepl#fireplace_connection#bencode(a:msg)
|
||||||
|
let terms = a:0 ? a:1 : ['done']
|
||||||
|
let sels = a:0 > 1 ? a:2 : {}
|
||||||
|
let response = self.dispatch('call', payload, terms, sels)
|
||||||
|
if a:0 > 2
|
||||||
|
return map(response, 'nrepl#fireplace_connection#callback(v:val, a:3)')
|
||||||
else
|
else
|
||||||
return response
|
return response
|
||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! s:nrepl_message(msg, ...) dict abort
|
||||||
|
let msg = self.prepare(a:msg)
|
||||||
|
let sel = {'id': msg.id}
|
||||||
|
return call(self.call, [msg, ['done'], sel] + a:000, self)
|
||||||
|
endfunction
|
||||||
|
|
||||||
let s:nrepl = {
|
let s:nrepl = {
|
||||||
\ 'close': s:function('s:nrepl_close'),
|
\ 'close': s:function('s:nrepl_close'),
|
||||||
\ 'command': s:function('s:nrepl_command'),
|
\ 'command': s:function('s:nrepl_command'),
|
||||||
\ 'dispatch': s:function('s:nrepl_dispatch'),
|
\ 'dispatch': s:function('s:nrepl_dispatch'),
|
||||||
\ 'prepare': s:function('s:nrepl_prepare'),
|
\ 'prepare': s:function('s:nrepl_prepare'),
|
||||||
\ 'call': s:function('s:nrepl_call'),
|
\ 'call': s:function('s:nrepl_call'),
|
||||||
|
\ 'message': s:function('s:nrepl_message'),
|
||||||
\ 'eval': s:function('s:nrepl_eval'),
|
\ 'eval': s:function('s:nrepl_eval'),
|
||||||
\ 'path': s:function('s:nrepl_path'),
|
\ 'path': s:function('s:nrepl_path'),
|
||||||
\ 'process': s:function('s:nrepl_process')}
|
\ 'process': s:function('s:nrepl_process')}
|
||||||
|
@ -140,9 +140,9 @@ function! s:repl.eval(expr, options) dict abort
|
|||||||
return result
|
return result
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:repl.call(...) dict abort
|
function! s:repl.message(...) dict abort
|
||||||
try
|
try
|
||||||
let result = call(self.connection.call, a:000, self.connection)
|
let result = call(self.connection.message, a:000, self.connection)
|
||||||
catch /^\w\+ Connection Error:/
|
catch /^\w\+ Connection Error:/
|
||||||
call filter(s:repl_paths, 'v:val isnot self')
|
call filter(s:repl_paths, 'v:val isnot self')
|
||||||
call filter(s:repls, 'v:val isnot self')
|
call filter(s:repls, 'v:val isnot self')
|
||||||
@ -330,7 +330,7 @@ function! s:oneoff.require(symbol) abort
|
|||||||
return ''
|
return ''
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:oneoff.call(symbol) abort
|
function! s:oneoff.message(symbol) abort
|
||||||
throw 'No live REPL connection'
|
throw 'No live REPL connection'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@ -385,7 +385,7 @@ function! fireplace#local_client(...) abort
|
|||||||
throw ':Connect to a REPL or install classpath.vim to evaluate code'
|
throw ':Connect to a REPL or install classpath.vim to evaluate code'
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! fireplace#call(payload, ...)
|
function! fireplace#message(payload, ...)
|
||||||
let client = s:client()
|
let client = s:client()
|
||||||
let payload = copy(a:payload)
|
let payload = copy(a:payload)
|
||||||
if !has_key(payload, 'ns')
|
if !has_key(payload, 'ns')
|
||||||
@ -400,7 +400,7 @@ function! fireplace#call(payload, ...)
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
return call(client.call, [payload] + a:000, client)
|
return call(client.message, [payload] + a:000, client)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! fireplace#findresource(resource, ...) abort
|
function! fireplace#findresource(resource, ...) abort
|
||||||
|
@ -95,12 +95,16 @@ class Connection:
|
|||||||
finally:
|
finally:
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
def call(self, payload):
|
def call(self, payload, terminators, selectors):
|
||||||
self.send(payload)
|
self.send(payload)
|
||||||
responses = []
|
responses = []
|
||||||
while True:
|
while True:
|
||||||
responses.append(self.receive())
|
response = self.receive()
|
||||||
if 'status' in responses[-1] and 'done' in responses[-1]['status']:
|
for key in selectors:
|
||||||
|
if response[key] != selectors[key]:
|
||||||
|
continue
|
||||||
|
responses.append(response)
|
||||||
|
if 'status' in response and set(terminators) & set(response['status']):
|
||||||
return responses
|
return responses
|
||||||
|
|
||||||
def dispatch(host, port, poll, keepalive, command, *args):
|
def dispatch(host, port, poll, keepalive, command, *args):
|
||||||
|
Loading…
Reference in New Issue
Block a user