LSP探索
是什么
官方定义:https://microsoft.github.io/language-server-protocol/overviews/lsp/overview/
为编程语言实现自动补全、定义跳转或在鼠标悬停时显示文档等功能的支持是一项重大工作。传统上,这项工作必须为每个开发工具重复进行,因为每个工具提供的实现相同功能的API都不同。
LSP的理念就是通过一种协议,与开发工具交流,实现功能。通过中间层,来做到一个语言服务器服务多个开发工具。
怎么用
意识就是开发工具会捕捉一个个事件点,与语言服务器进行交互,比如这里的:打开文档,编辑文档,用户执行定义跳转,关闭文档等。
可以具体看一下定义跳转
的交互
请求:
{
"jsonrpc": "2.0",
"id" : 1,
"method": "textDocument/definition",
"params": {
"textDocument": {
"uri": "file:///p%3A/mseng/VSCode/Playgrounds/cpp/use.cpp"
},
"position": {
"line": 3,
"character": 12
}
}
}
响应:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"uri": "file:///p%3A/mseng/VSCode/Playgrounds/cpp/provide.cpp",
"range": {
"start": {
"line": 0,
"character": 4
},
"end": {
"line": 0,
"character": 11
}
}
}
}
具体参数信息可看:官方文档
并非所有语言服务器都支持协议中定义的所有功能,所以需要在初始化时通过Capabilities
,来告诉开发工具,我能做啥。
自己实现
编译审查
完整代码:gist
def check_syntax file
# 检查语法
RubyVM::InstructionSequence.compile_file(file)
nil
rescue SyntaxError => e
e # only return syntax errors
rescue Exception
nil # ignore anything else
end
# 获取异常信息
line_number = error.message[/(?<=:)\d+/].to_i
# 找到具体行
line = File.readlines(file)[line_number - 1]
# 返回信息
result = {
:uri => doc[:uri],
:diagnostics => [
{
"range" => {
"start" => { "character" => 0, "line" => line_number - 1 },
"end" => { "character" => line.bytesize, "line" => line_number - 1 },
},
# 具体返回的信息
"message" => error.message.lines.first,
# 标识符,表示错误、警告、信息或提示。
"severity" => 1
},
],
}
# 写回流中
writer.write(method: "textDocument/publishDiagnostics", params: result)
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 玲辰书斋!