在过去,许多代码编辑器都是专门为特定语言设计的,为了提供丰富和智能的代码编辑,编辑器和语言工具之间必须紧密结合。另一方面,还存在一些(直到现在仍然存在)更通用的编辑器,但在实现如代码补全、“转到定义”等更高级的语言特定功能时却显得力不从心。(例如,通常使用正则表达式来实现代码高亮)。
随着代码编辑器和编程语言种类的增多,这成了一种经典的 M*N 复杂度问题。
但是随后微软引入了语言服务器协议(LSP),以解决上述问题,优雅地将这种*MN的复杂度简化为更易管理的M+N**情况。
LSP 最初是为了满足 VS Code 的需求而开发的
- LSP 将语言服务器与客户端编辑器分离。通过让语言服务器成为专门负责语言理解的独立进程,LSP 使得任何编辑器都可以使用标准语言服务器。这意味着一个标准语言服务器可以被所有编辑器使用。
- 这种互操作性是通过一组定义的标准消息和通信协议实现的,这些协议规范了语言服务器和编辑器之间通信的消息格式。LSP 定义了通过 JSON-RPC 发送的消息格式,用于开发工具和语言服务器之间的通信。
每种语言的服务器提供的功能可能有所不同,但通常它们包括以下功能:
- 自动完成
- 跳转到定义或声明
- 查找引用
- 代码格式化
- 代码诊断
- 文档生成
- 等
例如,这里可以看到gopls(Go语言服务器)提供的编辑器功能。
在这里你可以找到完整的LSP规范:点这里[here](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#languageFeatures)\。
LSP是怎么工作的?语言服务器协议(Language Server Protocol,简称LSP)建立在JSON-RPC之上。它具体使用的是JSON-RPC 2.0版本。可以把它想象成一种使用JSON进行数据编码的RPC协议。
简而言之,流程如下。首先,编辑器与语言服务器建立连接,然后当开发者输入代码时,编辑器会将代码的增量更改发送给语言服务器。语言服务器则返回如代码提示和错误检查等信息。
让我们来看一个真正的自动补全的例子。在这种情况下,来自语言客户端(编辑器)的请求如下:
{
"jsonrpc": "2.0",
"id": 1,
"method": "textDocument/completion",
"params": {
"textDocument": {
"uri": "file:///home/alex/code/test/main.go"
},
"position": {
"line": 35,
"character": 21
}
}
}
正如你看到的,它发送了当前光标所在的位臵以及缓冲文件的信息。我们来分解一下这个。
- ID:客户端设置此字段来唯一标识请求。请求处理完成后,会返回一个带有相同请求ID的响应,这样客户端就能知道哪个响应对应哪个请求。
- Method:一个包含要调用的方法名称的字符串。
- Params:这些参数可以是一个数组或对象。
语言服务可以访问此文件,对其进行分析,并给出建议:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"isIncomplete": false,
"items": [
{
"label": "Println",
"kind": 3,
"insertText": "Println(${1:format}, ${2:a ...interface{}})$0",
"insertTextFormat": 2,
"detail": "func Println(a ...interface{}) (n int, err error)",
"documentation": "Println 格式化并打印..."
},
// ... 更多条目
]
}
}
Go语言的服务器
最受欢迎的Go语言服务器是gopls。它被许多编辑器使用,例如像Visual Studio Code Go扩展这样的编辑器。之前,Sourcegraph团队也开发了一个流行的Go语言服务器go-langserver,但是这个项目现在不再积极维护。
很多编辑器会在主机机器上没有安装 gopls 语言服务器程序时自动安装,但你也可以手动安装:
下面是一个手动安装的示例命令:
# 手动安装命令示例
go install golang.org/x/tools/gopls@latest
在 Go 语言中,你可以使用 go install
命令来安装 gopls 工具的最新版本。 安装最新版本的 gopls 工具。gopls 是一个用于 Go 语言的代码补全和诊断工具。
gopls 还提供了一个实验性 CLI 接口:
gopls references 是一个命令行工具的输出 ./main.go:35:8
结尾
得益于语言服务器协议,高级编码功能现在可以在各种编程语言和开发环境中广泛使用。
知道你的代码编辑器是如何工作的很好,因此了解广泛使用的称为 LSP 的技术是有益的。
LSP(语言服务提供商)对语言服务提供商和工具开发商来说都是大好事!
资源(注:gopls是Go语言的服务器,用于支持语言服务器协议。)
共同学习,写下你的评论
评论加载中...
作者其他优质文章