Vim LSP 配置

用了好几年的 YouCompleteMe,体验还是不错的,最爽的一点是能基于 Token 补全在当前 buffer 中作补全,任何语言用 Vim 就有一个“基本可用”的体验,即使写 git commit message 的时候也很好用。

但是最近玩一些神奇的东西,YouCompleteMe 如果没有支持这种语言的话,就没办法做到一个比较好的体验了。

对于一种语言,YouCompleteMe 都要去实现这种语言的支持,才能起作用。每增加一种语言,YouCompleteMe 都要增加一种工作量。不光 YouCompleteMe,像 Emacs,VS Code,都要去实现每一个语言的自动补全。这就形成了很大的浪费:每一种编辑器要去自己实现每一种语言。如果有人写了一个新的语言想要其他编辑器支持,需要一个一个实现编辑器的补全工具。

这就形成了一种交叉关系,假如有三个语言,三个编辑器存在,就需要9个补全的实现。

所以 VS Code 就提出了 “Language Server” (简称 LSP)这种先进的概念。这是一种 Client-Server 架构,每个语言实现自己的 Language Server,每个编辑器去实现自己对接 Language Server 的前端。这样一个语言只需要实现一次,就可以支持所有的编辑器。上面那种情况,只要有3个语言的补全实现+3个编辑器自己的 Language Server 实现就可以了。

其实 YouCompleteMe 也支持 LSP 的,但是配置上看起来资料比较少,像是不是支持的特别好,所以我索性放弃 YCM 了,转向了 vim-lsp

配置 vim-lsp

这里以 Python 为例,介绍一下配置方法。

首先需要安装 Python 的 Language Server。推荐使用 pipx 安装。

然后修改 .vimrc 的配置修改,以下是一个最小化配置:

安装的插件需要4个,下面分别介绍一下这四个是干什么用的。

async.vim

因为补全是支持 Vim 和 Neovim 的,async.vim 封装了两个 Vim Async 相关的接口。

asyncomplete.vim

利用 async.vim 做的补全,相当于一个补全引擎。(到这里是和 lsp 还没有什么事儿,配置的都是补全插件。)

这个补全只是负责补全引擎,具体的补全还是要交给依赖此引擎的实现。比如我们想要对路径进行自动补全,需要先安装这个插件,再安装基于此插件实现的路径补全插件,最后对补全引擎注册这个插件,才能使用。安装路径补全插件和注册的配置如下。

还有很多挺有意思的补全,比如这个 tmux-completion,是基于 tmux 的窗口 buffer 来补全,在 vim 中抄写 tmux 里面的 git hash,URL 啥的挺有帮助。但是我没找到禁用它的方法,导致它会一直弹出来,太烦人了,就没用。

vim-lsp

是一个与 LSP 交互的插件,类似于一个 Vim 的 SDK。

asyncomplete-lsp

将 lsp 中的内容交给 asyncomplete 做补全。

 

后面的两个配置,一个是设置用 Tab 触发补全(判断补全窗口有没有打开,有打开的话就将tab键映射为补全选择键。

然后注册 Python 的 LSP。每一个 LSP 都需要注册。

效果如下:

配置好这些插件之后,再配置其他语言的 LSP 就简单多了。分成两步:

  1. 安装该语言的 LSP,这里有一个列表
  2. 在 Vim 中注册该 LSP;

以 Bash 为例,我们首先按照仓库的介绍,安装该语言的 LSP:

然后在 .vimrc 中用以下配置注册:

换成其他语言的话,只要将 cmd 换成 LSP 的启动命令,然后通过 whitelist 或者 blacklist 设置生效的文件类型就好了。

 

Snip 的支持

Language Server 支持补全一段代码模板,比如写 Elixir 的时候自动补全 defmodule 。但是 vim-lsp 本身是不支持的,snip 在 vim-lsp 中会补全成这个样子:

将这个片段正确的显示在 vim 中,并且支持跳转,需要通过插件来解析 Language Server 返回的片段。

这里又涉及到 N 多插件。首先你需要一个代码片段引擎,负责在 Vim 中生成片段,在片段中需要填写的字段中进行来回跳转,补全。之前在博客中介绍过 Ultisnips ,这里就以它为例。

除了 SirVer/ultisnips 本身,还要安装两个插件来将 LSP 中的 snip 补全到 vim 中来。总共需要安装的插件如下:

然后有一个小坑需要注意,Snip 必须确认选中才能展开,也就是菜单中将焦点移动到这个 Snip 上去之后,需要按 Ctrl + y 来展开。

但是这个快捷键可以更改,比如我换成了 Ctrl + o

 

Vim LSP 配置”已经有8条评论

  1. 前段时间也去了解过各种代码不全
    被人安利了一个叫 tabNine的东西
    这家伙不全的思路和其他插件完全不一样,
    他是用ml来预测,完全没有啥语法树啥的
    所以速度出奇的快,推荐可以试试

    另外催更捕蛇者说

    • Cool 我也听说过这个,补全上用大量代码做训练,效果应该不错。

      但是语法树应该会更准确,LSP 还能提供跳转到定义,跳转到声明,引用列表,冲命令变量等功能。功能列表

      用机器学习的话相当于补全工具并不知道你写的语法,甚至不知道你在写啥语言,只是基于数据帮你生成代码。我觉得实用价值不大。

      PS 捕蛇者说第10期录完了,laike9m在剪辑。

  2. 这个vim-lsp不稳定啊,对于python来说
    ,比如我输入import ,有时候会补全这个,而有时候会卡死,后边的库名,则经常出现没有出现补全提示的情况,我现在是jedi-vim/ale/gtags来实现自动补全/改名/跳转到定义/查找引用的。或许是因为我用的是win10?

    • 用了一段时间发现确实会有些问题,没有出现补全是因为异步吧。卡死的情况应该是 asyncomplete 的问题,我补全js的时候遇到过。

  3. coc-nvim 还是很推荐的,确实如其作者大大所说,给人以vscode一般的体验,并且非常的快,且插件化,国人精品。
    让我最惊喜的是支持跨文件的重构(需要LSP支持),
    另外衍生的插件已经取代了我很多老的插件了,

    内置的CocList 提供一些模糊查找路径,大纲,符号表等 取代了 fzf等同类插件;
    coc-explorer 取代了 NERDTree,defx;
    coc-pairs 取代了 autopairs;
    coc-smartf 取代了 vim-easymotion;
    coc-highlight 取代了 vim-cursorline,并提供了颜色板功能(不知道怎么描述,就是可以像ide一样在描述颜色的地方弹出调色窗口
    coc-java/ccls/python/rls 取代了那堆各有缺点的补全插件,
    coc-pyright 提供 python 静态类型检查,
    ……
    配置也没那么复杂,引入新的配置文件 全局/局部coc-settings.json,就像vscode那样,安装coc-json后提供完整的设置模糊补全,
    而这些插件只需要在ex中 :CocInstall 插件名 即可
    你甚至可以安装 coc-marketplace 搜索安装更多插件
    好用到哭

    最后感谢你在捕蛇者说中的分享和开源的 iredis,对初学redis很有帮助

Leave a comment

电子邮件地址不会被公开。 必填项已用*标注