Language Server Protocol
最近才注意到 Language Server Protocol (官方中文介紹)這東西,微軟為了 Visual Studio Code 所定的一個協定,專門用來輔助程式開發用的,像是 VSCode 的 IntelliSense 提供的自動補完就可以基於這個協定支援更多語言,這協定其實在 2016 就發表了,感覺我 lag 很久,不過其實我也好奇 VSCode 怎麼處理這問題一陣子了,最近在 TernJS 的 issue 裡面看到 LSP 這個詞,好奇之下才去看到底是什麼東西。
LSP 的設計理念是開發 Editor 的不可能每種程式語言都花時間心力去把它們的編輯輔助功能做起來(還不一定做的好),所以不如就把這塊拆出來,讓分析程式碼、提供輔助功能的部分(Language Server)拆出去給各自領域的人開發,然後透過一個公定的介面來做溝通,這個介面就是 Language Server Protocol 了。
LSP 是架構在 JSON-RPC 這個 protocol 上,只要你的 Editor 可以透過 JSON-RPC 發送請求並接收結果,就可以利用 LSP 來提供功能,現在支援 LSP 的編輯器也不少,不是只有 VSCode 有支援,其它還有 Eclipse、Vim、NeoVim、Sublime Text 3 都已經有方案可以支援了,在社群維護的網站 langserver.org 上有一份清單介紹各個 client 的支援狀況。
送到 Language Server 的指令,目前 Protocol 可以提供以下功能:
- Completion
- Hover Information
- Signature Help
- Goto Definition
- Goto Type Definition
- Goto Implementation
- Find References
- Action, fix code
- Code Lens, information for specific position
- Formatting
- Diagnostic, 像是 code lint
其它還有一些是檔案、工作區相關的操作指令,另外由於現在 Language Server 實做和 LSP 是分開的,也沒有限制一定要所有功能都有支援,所以有些 Language Server 可能是沒有支援特定功能的,目前可以找到兩份 Language Server 的列表,一份是 LSP 官網的,另一份則是 langserver.org 上的,社群維護的版本才有標示不同的 Language Server 對應支援的功能,不過說是社群維護,其實 langserver.org 是另外一間公司 Sourcegraph 在維護的,該公司做的東西和 LSP 相關性看起來還蠻大的,也提供了很多 Language Server。
然後我就很感興趣,VSCode 現在內建的 JavaScript 用的 Language Server 是哪一套呢?畢竟仔細一看,兩個列表裡面,都沒有列出內建由微軟維護的 JavaScript 的 Language Server,只有 Sourcegraph 的版本,不止 JavaScript 沒有,TypeScript 也沒,只有 TypeFox 的版本(TypeFox 也是做程式碼相關工具的公司,我有找到一些研討會演講介紹 LSP 的講者就是這間公司的人)。總之兩個語言都沒列這真是太不尋常了,實在引起了我的好奇心,後來到處尋找總算在 JavaScript in VS Code 這頁找到蛛絲馬跡,這頁內文第二句話就有個連結連去 JavaScript Language Service 在 GitHub 的介紹,位置是 TypeScript 專案下的 Wiki 頁面,也有找到 TypeScript 專案內的相關程式碼,實際上 VSCode 對於 JavaScript 和 TypeScript 的編輯輔助功能都是依靠這個 TypeScript Language Service 提供的,或是也可以叫它 tsserver,TypeScript 的大架構可以參考 Architectural Overview 這篇文章;由於 tsserver 比較早推出,所以用的不是 LSP 用的 JSON-RPC,而是 STDIO 然後傳輸 JSON 加上 header,指令也有些落差,不過其實整體而言沒差距很大,因為 VSCode 那些輔助功能幾乎都是從 Visual Studio 來的,TypeScript 的支援也早就都透過 tsserver 來實現了,事實上,Sourcegraph 的 TypeScript Language Service 就是個 tsserver 的 proxy,底層還是 tsserver,不過實際上要用的話應該是 TypeFox 的比較好;然後當然也有人提出來說 TypeScript 是不是應該直接提供 LSP 版本的開發工具支援,在 GitHub 上的 Issue 11274,不過目前看來是沒打算樣子,這點我也是蠻意外的,畢竟 LSP 和 TypeScript 同公司的,沒打算支援自家公司定的標準,也是十足的霸氣,也看的出來各開源專案自治度其實蠻高的。
補充:另外有個 debugger 用的 Debug Adapter Protocol