LSP-language-server-protocol规范学习

豆皮粉儿们,又见面了,今天这一期,由字节跳动数据平台的“虫二”,给大家讲一讲LSP-language-server-protocol。

https://microsoft.github.io/language-server-protocol/
vscode LSP文档(可中文阅读): https://docs.microsoft.com/zh-cn/visualstudio/extensibility/language-server-protocol?view=vs-2019

yuge最近在学习WebIDE的实现机制,需要实现类似IDE的智能提示、语法检查和解析、悬停文档等交互体验;由于没法直接嵌入进来VSCode,于是想学习相关方面的实现,目标是利用Monaco和LSP实现一个IDE。

LSP(Language Server Protocol) 语言服务协议,该协议定义了在编辑器或IDE与语言服务器之间使用的协议,该语言服务器提供了例如自动补全,转到定义,查找所有引用等的功能;语言服务器索引格式的目标是支持在开发工具中进行丰富的代码导航或者一个无需本地源码副本的WebUI。

分以下几个方面

  • 什么是LSP
  • LSP如何工作
  • IDE 和语言服务器如何交互
  • LSP的功能
  • LSP的提供者和使用者的库(SDK)

LSP概述

什么是LSP

每个开发IDE,都要为语言实现类如自动补全,转动定义,悬停在单词上提供文档的功能,传统上,需要个IDE根据自己的API实现上述工作,即使是相同的功能,也要根据不同IDE实现一遍重复的功能,代码却不同。例如,Eclipse CDT 插件(在 Eclipse IDE 中支持 C/C++)是用 Java 编写的,因为 Eclipse IDE 本身是用 Java 编写的。按照此方法,这意味着在 Visual Studio 代码的 TypeScript 中实现 C/C++ 域模型,在 Visual Studio 的 C# 中实现单独的域模型。

如果开发工具可以重用现有的特定于语言的库,则创建特定于语言的域模型也容易得多。但是,这些库通常在编程语言本身中实现(例如,好的 C/C++域模型在 C/C++中实现)。将 C/C++ 库集成到用 TypeScript 编写的编辑器中,在技术上是可能的,但很难做到。

一个语言服务器旨在提供某个语言的智能化,并通过支持进程间通信的协议与开发工具进行通信。

LSP设计的目标是使该语言服务器和开发工具进行标准化的通信,这个语言服务可以在多个开发工具中重复使用,从而以最小的改动支持多种语言。语言服务器后端可以用PHP,Python或Java编写,LSP可以轻松地将其集成到各种工具中,该协议提供通用抽象级别的协议,以便工具可以提供丰富的语言服务,从而无需完全理解特定于底层域模型的细微差别。

LSP对于语言提供商和工具的提供商都是双赢!

LSP如何工作

语言服务器会作为单独的进程运行,同时开发工具使用基于JSON-RPC的语言协议与服务器进行通信。

以下是一个开发工具和语言服务器在运行编辑期间的通信示例:

https://www.npmjs.com/package/vscode-languageclient
[2] 语言服务器npm模块: https://www.npmjs.com/package/vscode-languageserver