Skip to content

Commit b467cef

Browse files
committed
session: Enable sending async rpc calls to nvim
1 parent 55a581f commit b467cef

File tree

5 files changed

+49
-4
lines changed

5 files changed

+49
-4
lines changed

neovim/api/common.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,11 +224,11 @@ def next_message(self):
224224
if msg:
225225
return walk(self._in, msg, self, msg[1], msg[0])
226226

227-
def request(self, name, *args):
227+
def request(self, name, *args, **kwargs):
228228
"""Wrapper for Session.request."""
229229
args = walk(self._out, args, self, name, 'out-request')
230-
return walk(self._in, self._session.request(name, *args), self, name,
231-
'out-request')
230+
return walk(self._in, self._session.request(name, *args, **kwargs),
231+
self, name, 'out-request')
232232

233233
def run(self, request_cb, notification_cb, setup_cb=None):
234234
"""Wrapper for Session.run."""

neovim/msgpack_rpc/async_session.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,15 @@ def request(self, method, args, response_cb):
4444
self._msgpack_stream.send([0, request_id, method, args])
4545
self._pending_requests[request_id] = response_cb
4646

47+
def notify(self, method, args):
48+
"""Send a msgpack-rpc notification to Nvim.
49+
50+
A msgpack-rpc with method `method` and argument `args` is sent to
51+
Nvim. This will have the same effect as a request, but no response
52+
will be recieved
53+
"""
54+
self._msgpack_stream.send([2, method, args])
55+
4756
def run(self, request_cb, notification_cb):
4857
"""Run the event loop to receive requests and notifications from Nvim.
4958

neovim/msgpack_rpc/session.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def next_message(self):
5454
if self._pending_messages:
5555
return self._pending_messages.popleft()
5656

57-
def request(self, method, *args):
57+
def request(self, method, *args, **kwargs):
5858
"""Send a msgpack-rpc request and block until as response is received.
5959
6060
If the event loop is running, this method must have been called by a
@@ -67,7 +67,16 @@ def request(self, method, *args):
6767
- Send the request
6868
- Run the loop until the response is available
6969
- Put requests/notifications received while waiting into a queue
70+
71+
If the `async` flag is present and True, a asynchronous notification is
72+
sent instead. This will never block, and the return value or error is
73+
ignored.
7074
"""
75+
async = kwargs.get('async', False)
76+
if async:
77+
self._async_session.notify(method, args)
78+
return
79+
7180
if self._is_running:
7281
v = self._yielding_request(method, args)
7382
else:

test/test_client_rpc.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,19 @@ def request_cb(name, args):
3535

3636
vim.session.run(request_cb, None, setup_cb)
3737

38+
@with_setup(setup=cleanup)
39+
def test_async_call():
40+
41+
def request_cb(name, args):
42+
vim.vars['result'] = 17
43+
vim.session.stop()
44+
45+
cmd = 'call rpcrequest(%d, "test-event")' % vim.channel_id
46+
# this would have dead-locked if not async
47+
vim.session.request('vim_command', cmd, async=True)
48+
vim.session.run(request_cb, None, None)
49+
eq(vim.vars['result'], 17)
50+
3851

3952
@with_setup(setup=cleanup)
4053
def test_recursion():

test/test_events.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,20 @@ def test_receiving_events():
1616
eq(event[1], 'py!')
1717
eq(event[2], [vim.current.buffer.number])
1818

19+
@with_setup(setup=cleanup)
20+
def test_sending_notify():
21+
# notify after notify
22+
vim.session.request('vim_command', "let g:test = 3", async=True)
23+
cmd = 'call rpcnotify(%d, "test-event", g:test)' % vim.channel_id
24+
vim.session.request('vim_command', cmd, async=True)
25+
event = vim.session.next_message()
26+
eq(event[1], 'test-event')
27+
eq(event[2], [3])
28+
29+
# request after notify
30+
vim.session.request('vim_command', "let g:data = 'xyz'", async=True)
31+
eq(vim.eval('g:data'), 'xyz')
32+
1933

2034
@with_setup(setup=cleanup)
2135
def test_broadcast():

0 commit comments

Comments
 (0)