美文网首页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