- Published on
Neovim Vala Lsp Integration Tips
- Authors

- Name
- ttyS3
The Issue
如果不是用到了一个叫 peek 的录屏软件,我可能没听过这个叫 vala 的语言,GNOME 搞出来的东西。
老灯日常用的 geary 邮件客户端和 peek 都是这个语言编写的。
老灯发现neovim 官方的 vala lang server 配置无法适用于 peek 这个项目。已经提交了 PR ( https://github.com/neovim/nvim-lspconfig/pull/789 ), 不过这个合并效率真是低,都两周了,还没动静,没给close 也没给merge.
neovim 官方的 vala lang server 配置甚至无法用于正常浏览 vala-language-server 的源码。
git clone https://github.com/benwaffle/vala-language-server
cd vala-language-server
nvim
然后我们在 neovim 中打开 src/server.vala,然后 neovim lsp 会在src目录下找到一个“假”的meson.build文件 (真正的 meson.build 文件在项目根目录下),根据 vala lang server 的逻辑,它会在这个“project root"(假的) 下面执行 meson build, 很明显这个命令会失败,因为这个不是真正的 meson.build 文件,而只是一个被根目录下的 meson.build 文件 包含进来的 include 文件 (姑且这么说吧,你 get 到意思就行)。然后 vala lang server 就报错了(实际上它输出的是 meson 的 stderr 错误信息):
ERROR: First statement must be a call to project
The Solution
根据 meson 的报错信息,我们知道,meson.build 文件的第一行有效指令一定是 a call to project.
这里老灯用的有效指令,其实主要是指排除comment. a call to project 即调用 project()
在官方没合并老灯的 PR 前,只能手动在配置那里hack了:
-- https://github.com/neovim/nvim-lspconfig/blob/master/CONFIG.md#vala_ls
local meson_matcher = function (path)
local pattern = "meson.build"
local f = vim.fn.glob(util.path.join(path, pattern))
if f == '' then
return nil
end
for line in io.lines(f) do
-- skip meson comments
if not line:match('^%s*#.*') then
local str = line:gsub('%s+', '')
if str ~= '' then
if str:match('^project%(') then
return path
else
break
end
end
end
end
end
lsp.vala_ls.setup({
on_attach = mix_attach,
capabilities = lsp_status.capabilities,
cmd = {'vala-language-server'},
root_dir = function (fname)
local root = util.search_ancestors(fname, meson_matcher)
return root or util.find_git_ancestor(fname)
end,
})
ps: 关于上面配置里的 mix_attach 和 lsp_status 请参考老灯之前写的《Neovim C Cpp Lsp Integration Tips》
这里主要是告诉 neovim lsp, 要怎么确定这个 project root, 所谓的 project root, neovim lsp config 的逻辑是,
先找到项目的 meson.build 文件, 该文件所在目录,即project root,否则,就尝试找 git 仓库.
这里我们简单地给查找 meson.build 文件的方法 hack 了一下,跳过评论并且去除行两端的空格后,我们简单地判断此行是否以project(开头,即可过滤掉那些假的 meson.build 文件
其实 neovim lsp config 这个判断方法也只是针对大部分情况。但是老灯觉得,对于大部分情况已经 OK 了,毕竟,作为一个公共配置,它无法兼顾所有情况。
根据 GNOME 官方说明:meson 是 Vala 主要的构建系统。
Meson - a front end to the Ninja build system with Vala support (The main build system for Vala)
因此,只判断meson.build 文件,对于大部分 Vala 项目来说应该是 OK 的
Refs
https://github.com/benwaffle/vala-language-server
https://wiki.gnome.org/Projects/Vala/Tools
https://mesonbuild.com/Syntax.html#comments