- 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