-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
181 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
如果想入门 LSP,查官方文档是必不可少的:microsoft.github.io | ||
|
||
但是语言服务非常重交互,只靠文字描述是很单薄的,初学者只看干巴巴的接口定义肯定会头晕,不知道这些接口都能干什么。不过也不怪 LSP 官方,毕竟只负责设计协议,具体的实现还得靠客户端(各大代码编辑器)。 | ||
|
||
这时候就推荐 VS Code 的这篇文档了,列出了插件 API 和 LSP 的对应关系,毕竟和 LSP 一样都是微软家的,很多概念和术语都相通:code.visualstudio.com | ||
|
||
文档里详细列出了 VS Code 支持的语言特性,并且都配上了动图和聊胜于无的文字说明。要说为什么是聊胜于无,还是因为交互太重了,各个功能需要多写 demo 去体验,意会。 | ||
|
||
从学习和方便调试的角度,可以尝试先用 VS Code API 实现一些功能,翻翻 API 的文档,然后再换成 LSP 实现,两者的文档交叉比对,能更好的体会“设计”和“实现”的差异,更好的理解 LSP。 | ||
|
||
--- | ||
|
||
在 VS Code 中的语言服务插件,指的是能给一种语言提供高亮、补全、诊断,悬浮提示,查看定义等等功能的插件。 | ||
|
||
实现这些功能有两种方式。 | ||
一种是在插件进程内,调用 vscode 这个 npm 包的 API。插件是一个 node 进程,也是 Electron 进程(具体是主进程,还是渲染进程,还不确定)的子进程。 | ||
另一种是再新开一个进程,作为语言服务器,和插件(客户端)通过 LSP(Language Server Protocol) 通信。 | ||
|
||
是的,这些功能都是插件作者一行一行的代码写出来的。在开发插件之前,我完全没有料到在编辑器里 console 后输一个点,要经历这么复杂的代码后,才会弹出 log,warn 和 error。 | ||
|
||
两种方案有什么区别? | ||
vscode API。文档全面,教程详细。可以快速实现小功能。适合快速实现轻量化语言服务,例如 json,markdown 甚至 css 这种非编程语言。或者快速验证想法。 | ||
缺点是只能使用 js(ts) 实现,而且业务功能和插件底层在一个进程会导致性能问题,不适合计算密集型的功能。提供语言服务和编译器的区别之一就是需要处理用户输入,要求写完代码后能快速更新语法树,然后基于语法树提供语言服务。例如给一个 1000 行的 js 代码生成 AST,然后提供语义高亮。这时候插件更新慢了,插件和 vs code 的通信就会慢,提供语言服务的速度也会慢。 | ||
|
||
语言服务器。实现语言没有限制。与 vs code 解耦,只要是实现了 LSP 的客户端都可以通信,服务更多的编辑器。并且可以起多个进程(多个实例),一起给客户端服务,解放客户端进程的算力,客户端只需要转发其他进程算出来的数据给 vs code 即可。 | ||
缺点是 LSP 有一定上手门槛,需要额外处理进程通信,架构复杂后,调试和开发都没那么轻便了。如果你还是用 node,微软官方提供了 vscode-languageserver 这个 npm 包,但是我都用它写完语义高亮、悬浮提示这些功能了,还是不知道这个包应该怎么用。比起 vs code API,它的文档太少了,示例代码也很少,相关讨论也很少,最要命的是 ChatGPT 也不太懂这个包怎么用,看来是能训练的资料确实太少了… | ||
|
||
文档缺失倒逼我去翻 GitHub,推荐一下 Volar.js 的源码,用 node 实现,实现的功能都很丰富,我就是抄它的配置,才做出语义高亮的… | ||
|
||
--- | ||
|
||
插件进程主要的功能应该是和 VS Code 主体通信。就像 Electron 主进程一样,应该避免执行很重的任务。VS Code 通知插件,现在需要一个自动补全的列表,虽然插件可以返回一个 promise 异步处理,但如果等太久,VS Code 就不要这个结果了(不提供补全)。这也是 VS Code 的用户交互指南之一,插件不能影响 UI 响应速度 | ||
|
||
--- | ||
|
||
插件本体、语言服务器、代码编辑器这三者分别是什么关系? | ||
插件本体就是个转发层,代码编辑器是真正发请求的,语言服务器是真正处理请求的。 | ||
他们在三个进程,分别是 VS Code 的 extension host 进程、VS Code 的渲染进程、语言服务器进程。后两者通过 LSP 通信,前两者通过 Electron IPC 通信(TODO: 存疑)。 | ||
|
||
--- | ||
|
||
拿自动补全举例,在 console 后输入一个点,这时候语法结构是不完整的,有错的,怎么根据不完整的语法结构和当前光标的位置,推断出当前上下文适用哪些补全,是很难的。 | ||
现在理解尤雨溪为什么资助 Volar 作者全职开发这个插件了,它就是 DX 的基础之一,没有这种插件,开发者写 .vue 文件就和白纸写代码一样,是完全写不了的 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.