简体   繁体   English

将 asyncio 与 neovim 远程插件一起使用

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM