在vim中,我可以执行vim --servername foovim --servername foo --remote-silent bar.txt从多个终端窗口(通过tmux或其他方式)在vim的一个实例中打开文件。 NeoVim如何实现相同的目的?

#1 楼

据我所知,vim具有此功能,因为GUI vim(gvim)使用图形X服务器。我知道非GUI Vim也可以使用--servername参数,但仅当X11正在运行时并且可以通过访问它来使用。另一方面,neovim没有图形支持。因此,我认为--servername选项不起作用(除非以其他方式完全重写了该选项),因为我发现奇怪的是控制台程序仅出于该目的访问X11服务器。 >

评论


起初我以为这个答案是错误的,因为不带X的IPC不仅可能,而且非常普遍(例如套接字)。但是:help x11-clientserver似乎确认了这一点:“客户端和服务器之间的通信通过X服务器。[..]可以访问X11显示(| xterm-clipboard |)的非GUI Vim也可以起作用。作为命令服务器,如果显式给出了服务器名称” ...

–马丁·图尔诺伊(Martin Tournoij)
15年11月14日在23:03

#2 楼

Neovim remote是用于控制Neovim进程的python脚本。它具有vim样式--servername和--remote选项。这就是我现在用于多终端工作环境的方式。

评论


值得一提的是,此插件不适用于Windows平台。

– jdhao
19 Mar 26 '19 at 12:08

#3 楼

如前所述,所有客户端服务器功能已在Neovim中删除。这是因为它们使用X11共享内存,并且Neovim删除了对X11的支持。

但是,如果我在Neovim中使用:help --servername,我最终会在文档中找到serverstart()函数:

serverstart([{address}])                                serverstart()
                Opens a named pipe or TCP socket at {address} for clients to
                connect to and returns {address}. If no address is given, it
                is equivalent to:
                        :call serverstart(tempname())
                $NVIM_LISTEN_ADDRESS is set to {address} if not already set.
                                                        --servername
                The Vim command-line option --servername can be imitated:
                        nvim --cmd "let g:server_addr = serverstart('foo')"


这将在/tmp/中制作一个插座;请参阅:echo v:servername了解路径。使用更具确定性的地址可能更有用(例如serverstart('/tmp/nvim-remote');尽管您可能希望将其包装在函数中,因为如果已经存在,它不会像Vim的--serverstart一样附加数字)。

您可以使用RPC API发送命令。据我所知,仅Neovim(meh)无法将命令发送至此。您需要安装一个API客户端。例如,使用参考Python API客户端(这也是Neovim远程使用的客户端):

import neovim
nvim = neovim.attach('socket', path='/tmp/nvim-remote')
try:
    nvim.command(':e foo')
finally:
    nvim.quit()


您可以使用echo ... >> /tmp/nvim-remove shell命令发送相同的字节,但是RPC API使用了一些不平凡的非文本协议(“ MessagePack RPC”),因此,弄清楚要发送的确切字节对于本篇文章来说太费力了;-) Neovim的RPC API的完整详细信息。


NB Neovim中仍然存在:help rpc以及许多其他帮助项(例如:help remote.txt等),但是这些都不起作用。似乎谁删除了此功能的人都做得很草率。

评论


这是一个很好的答案。它使我能够编写自己的,简单的,与Windows兼容的neovim-remote版本,以便在:terminal中运行。有了这些信息,这非常容易。

–大卫
19-10-18在15:37



@David可以分享吗?

– TamaMcGlinn
20 Mar 25 '20在8:53

python程序nvr巧妙地解决了这个问题(可在Windows和Linux上运行):github / mhinz / neovim-remote

– TamaMcGlinn
20 Mar 25 '10:00



@TamaMcGlinn这是我的小脚本:gist.github.com/dhazel/4858340f66e18cb7e12cd2ec8f8ca8d7。感谢您提供有关nvr的提示。自从我看了已经有好几年了。

–大卫
20-3-26在23:07



#4 楼

对于Windows,我提出以下解决方案:

在您的ginit.vim文件中添加以下行:

silent execute "!echo " . v:servername . " > servername.txt"


备注:ginit.vim将在%LocalAppData%\nvim中找到或创建文件(例如:在Windows 10上为John Doo:C:\Users\JDoo\AppData\Local\nvim

使用以下批处理文件启动nvim-qt:

 @setlocal
@pushd %~dp0
@if not exist servername.txt goto nvimqt
@%~dp0\nvim.py %*
@if [%errorlevel%]==[0] goto :end

@:nvimqt
@%~dp0\bin\nvim-qt.exe %*
@del %~dp0\servername.txt

:end
@popd
 


,它利用以下Python脚本:

 import os
import sys
import neovim


def main():
    servername_path = "servername.txt"

    if not os.path.isfile(servername_path):
        return 1

    with open(servername_path, mode="rt") as f:
        line = f.readline()
        servername = line.strip("\r\n ")

    try:
        nvim = neovim.attach("socket", path=servername)
    except Exception:
        print("Neovim not found")
        os.remove(servername_path)
        return 1

    if len(sys.argv) <= 1:
        return

    path = sys.argv[1]
    nvim.command(':e %s' % path)

    nvim.close()


if __name__ == "__main__":
    ret = main()
    sys.exit(ret)