[英]Use asyncio with neovim remote plugins
I want to write a vim plugin that listens to Server-sent events .我想写一个 vim 插件来监听服务器发送的事件。 Since I am most fluent with python3 and use neovim, I figured it would be a good idea to use the neovim remote plugin API .
由于我最熟悉 python3 并使用 neovim,我认为使用neovim 远程插件 API是一个好主意。
Obviously, listening for messages from the network must not be blocking, so asyncio must be involved somehow.显然,监听来自网络的消息不能是阻塞的,因此必须以某种方式涉及 asyncio。 But I was not able to figure out how to combine the two.
但我无法弄清楚如何将两者结合起来。 Somewhere I would have to run an event loop.
我必须在某个地方运行事件循环。 However, pynvim already runs its own event loop, so I probably should hook into that.
但是,pynvim 已经运行了自己的事件循环,所以我可能应该加入它。
@pynvim.plugin
class MyPlugin:
def __init__(self, nvim):
self.nvim = nvim
@pynvim.command('Connect', nargs='1')
async def connect(self, args):
url = base_url + args[0]
async with sse_client.EventSource(url) as event_source:
for raw in event_source:
try:
msg = json.loads(raw)
except json.JSONDecodeError:
continue
do_something(msg)
This example doesn't work.这个例子不起作用。 The
Connect
command is not available in neovim (it was before I made it async). Connect
命令在 neovim 中不可用(在我使它异步之前)。
Not sure if this is the best answer, but this is what I have found to work:不确定这是否是最好的答案,但这是我发现的工作:
asyncio
seems to keep a reference to the current loop, so asyncio.ensure_future()
can be used to schedule async code. asyncio
似乎保留了对当前循环的引用,因此asyncio.ensure_future()
可用于调度异步代码。 However, that async code will crash if it tries to access vim internals.但是,如果该异步代码尝试访问 vim 内部,它将崩溃。 In order to do that, you need to call yet another callback with
nvim.async_call()
.为此,您需要使用
nvim.async_call()
调用另一个回调。
@pynvim.plugin
class MyPlugin:
def __init__(self, nvim):
self.nvim = nvim
async def _connect(self, url):
async with sse_client.EventSource(url) as event_source:
for raw in event_source:
try:
msg = json.loads(raw)
except json.JSONDecodeError:
continue
self.nvim.async_call(do_something, msg)
@pynvim.command('Connect', nargs='1')
def connect(self, args):
url = base_url + args[0]
asyncio.ensure_future(self._connect(url))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.