美文网首页Other
[Other] Language Server Protocol

[Other] Language Server Protocol

作者: 何幻 | 来源:发表于2019-06-17 11:39 被阅读4次

LSP(Language Server Protocol)是由 redhat, microsoft, codenvy 联合推出的语言服务器协议
用于编辑器语言服务器之间的通信。

LSP is a win for both language tooling providers and code editor vendors!
LSP创造了编辑器和编程语言的一种双赢局面。

1. 复杂度

我们知道市面上有很多种不同的编辑器,VSCode,IntelliJ IDEA,Emacs,Vim,……
每一个编辑器也能支持多种不同的编程语言,Java,JavaScript,Python,Ruby,……

编辑器中有一些常见的功能,通常需要在每个编辑器中,针对每一种编程语言单独实现一遍,
例如,自动完成(auto complete),转到定义(go to definition),鼠标悬停展示文档(documentation on hover),……


这样的实现方式太繁琐了,上述功能,我们能不能让每个编辑器,对于不同的编程语言只实现一遍
这就是LSP给出的解决方案,编辑器只管基于LSP跟语言服务器通信就好了,

通过LSP,问题复杂度由原来的 m * n 转换为了 m + n
其中 m 为编程语言的数量,n 为编辑器的数量。

对于自动完成/转到定义/鼠标悬停展示文档,每个编辑器只用实现一遍,
每种编程语言也只用实现一遍。

2. 跨语言

语言服务器通常是由编程语言自身实现的,
Java语言服务器,和Node.js语言服务器,可能分别是由Java和Node.js编写的,

Language Servers are usually implemented in their native programming languages.

因此,基于LSP的编辑器,如果要同时TypeScript和PHP,
必须有办法同时跟TypeScript语言服务器,和PHP语言服务器通信。

此外,自动完成/转到定义/鼠标悬停展示文档,等等这些功能,比起编辑器而言,可能更加浪费资源,
例如,对文件进行检查时,语言服务器可能需要解析一个很长的文本,将其转换成AST(Abstract Syntax Tree),然后再执行静态检查。

Language features can be resource intensive.

所以最好的办法是,让语言服务器运行在单独的进程中,
编辑器和语言服务器之间,通过进程间通信(RPC)完成交互,这是一种C/S架构(client-server mode)。


上图为VSCode与语言服务器之间的通信过程,
其中,客户端(Language Client)是由VSCode插件实现的(使用TypeScript编写)。

如图对于TypeScript,VSCode通过LSP与TS语言服务器通信,
对于PHP,VSCode与PHP语言服务器通信。

3. 协议 & 规范

3.1 通信协议


编辑器与语言服务器之间,是基于JSON-RPC通信的。

JSON-RPC,是一个开源RPC协议,
规定了RPC请求,响应,以及请求错误的格式,

JSON-RPC is a stateless, light-weight remote procedure call (RPC) protocol.

3.2 语言服务器规范

LSP是一个协议,不是具体的实现,它规定了语言服务器应当实现的一些规范条件,
比如,编码格式,数据结构(Text Documents,Position,Range,Location,……),生命周期(Server lifetime),
以及服务器可支持哪些语言特性(Language Features),例如,completion,hover,definition,codelens等等。

具体的语言服务器,不必支持规范中提到的所有语言特性,
它支持的那部分特性集合,称为语言服务器的能力(Capabilities)。

A capability groups a set of language features.

4. 示例

下面我们来实际运行一下,示例来自Language Server Extension Guide
源码仓库位于lsp-sample

$ git clone https://github.com/microsoft/vscode-extension-samples.git
$ cd vscode-extension-samples/lsp-sample
$ npm i

使用VSCode打开,这个文件夹,


然后在 server/src/server.ts123 行打个断点,

在Debug面板选择Client + Server这个调试选项,然后启动调试,

VSCode会弹出一个新的窗口,这个窗口是用来调试VSCode插件用的,它是语言服务器的客户端,


我们在这个新窗口中新建一个文件,index.txt,然后保存,就会跳到断点位置,
(注意,后缀名必须是 .txt 才可以。)

本示例中,新建以及后续修改.txt文件,会触发语言服务器中的documents.onDidChangeContent事件,
语言服务器会对该文件进行校验validateTextDocument,返回诊断信息。

我们依次输入 AB,试一试,


会发现输入 B 之后,字符下面会出现一个绿色的曲线,这就是诊断信息。
鼠标移动到上面,会弹出一个悬浮框,

这正是validateTextDocument中实现的功能,


参考

LSP
github: language-server-protocol
VSCode: Language Server Extension Guide
Language Server Protocol
Implementations: Language Servers
JSON-RPC
LSP: specification
LSP: Capabilities

相关文章

网友评论

    本文标题:[Other] Language Server Protocol

    本文链接:https://www.haomeiwen.com/subject/jbjofctx.html