什么是LSP语言服务器协议?

过去,许多代码编辑器都是为特定语言构建的,为了提供丰富而智能的代码编辑功能,编辑器和语言工具之间的紧密集成必不可少。

另一方面,虽然有(现在仍然有)更多通用编辑器,但它们在更高级的语言特定功能(如代码完成、“转到定义”等)方面功能不足(例如,使用正则表达式进行代码突出显示)。

随着代码编辑器和编程语言的不断增长,这成为了经典的M*N复杂性问题。

但随后微软推出了语言服务器协议(LSP)作为上述问题的解决方案,它优雅地将这种M*N复杂性转变为更易于管理的M+N情况。

LSP 最初是由VS Code 的需求驱动的:

  • LSP 将语言服务器与代码编辑器(语言客户端)分开。通过使语言服务器成为专用于语言理解的独立进程,LSP 使任何编辑器都可以使用标准语言服务器。这意味着所有编辑器都可以使用单个标准语言服务器。
  • 这种互操作性是通过一组定义的标准消息和程序实现的,这些消息和程序控制着语言服务器和编辑器之间的通信。LSP 定义了开发工具和语言服务器之间使用 JSON-RPC 发送的消息的格式。

语言服务器功能
每个语言服务器的功能列表可能有所不同,但通常它们提供以下功能:

  • 自动完成
  • 转到定义/声明
  • 查找参考资料
  • 代码格式
  • 诊断
  • 文档
  • ETC。
例如
  • 这里您可以看到gopls (Go 语言服务器)提供的编辑器功能列表。
  • 这里您可以看到可用功能的完整 LSP 规范。

LSP 如何工作?
语言服务器协议建立在JSON-RPC之上。它具体使用 JSON RPC 2.0。您可以将 JSON-RPC 视为使用 JSON 进行数据编码的远程过程调用协议。

简而言之,它的工作原理如下。首先,编辑器与语言服务器建立连接,然后随着开发人员输入代码,编辑器将增量更改发送到语言服务器。然后它发回以下见解:代码完成建议、诊断。

让我们看一个自动完成的真实示例。此案例中来自语言客户端(编辑器)的请求将是:


  “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

结论
多亏了语言服务器协议,各种编程语言和编码环境都能普遍使用高级编码功能。 了解代码编辑器的工作原理是件好事,因此了解这项被广泛使用的技术(LSP)也大有益处。 LSP 对语言提供商和工具供应商来说都是双赢之举!