VSCode 建議你啟用 gopls,它到底是個什么東東?

碼小辮專注更多編程視頻和電子書

天天在用錢
要談 gopls,得先聊聊 LSP。
LSP 是什么
LSP,全稱 Language Server Protocol,即語言服務(wù)器協(xié)議,這是微軟創(chuàng)建的一個協(xié)議(目前已有 Codenvy,Red Hat 和 Sourcegraph 等公司一起支持它的發(fā)展)。定義了在編輯器或 IDE 中與語言服務(wù)器之間使用的協(xié)議,該語言服務(wù)器提供諸如自動完成,轉(zhuǎn)到定義,查找所有引用等語言功能。語言服務(wù)器索引格式(LSIF,其發(fā)音類似于“ else if”)的目標是支持開發(fā)工具或 Web UI 中的富代碼導(dǎo)航,而不需要源代碼的本地副本。
目前該協(xié)議得到了編輯器和語言社區(qū)的廣泛支持。
LSP 的官方網(wǎng)站:https://microsoft.github.io/language-server-protocol/,GitHub 地址:https://github.com/Microsoft/language-server-protocol。目前最新版本(2020-09-06):3.15。
LSP 解決了什么問題
為編程語言添加諸如自動完成、轉(zhuǎn)到定義或鼠標懸停出現(xiàn)文檔之類的功能需要付出大量的努力。傳統(tǒng)上,這項工作必須為每個開發(fā)工具重復(fù)進行,因為每個工具為實現(xiàn)相同的特性提供不同的 api。
語言服務(wù)器(Language Server)旨在提供特定語言的智能功能,并通過支持進程間通訊協(xié)議與開發(fā)工具進行通信。
語言服務(wù)器協(xié)議(LSP)背后的思想是為這些服務(wù)器和開發(fā)工具的通信方式提供標準化協(xié)議支持。通過這種方式,可以在多個開發(fā)工具中重用單個 Language Server,而這些工具反過來可以用最少的工作支持多種語言。
例如,之前需要為 VSCode 構(gòu)建 Go 插件、為 Sublime Text 構(gòu)建 Go 插件、為 Vim 構(gòu)建 Go 插件、為 Sourcegraph 構(gòu)建 Go 插件,很多重復(fù)的工作?,F(xiàn)在,對于每種語言,LSP 允許語言社區(qū)將精力集中在一個高性能語言服務(wù)器上,這個服務(wù)器可以提供代碼完成,懸停文檔提示、跳轉(zhuǎn)到定義、查找引用等功能,而編輯器和客戶端社區(qū)可以專注于構(gòu)建一個單一的、高性能的、直觀的和慣用的擴展,這個擴展可以與任何語言服務(wù)器通信,即時提供深入的語言支持。
LSP 是語言提供商和工具供應(yīng)商的雙贏!
LSP 的工作原理
語言服務(wù)器(Language Server)作為單獨的進程運行,開發(fā)工具在 LSP 基礎(chǔ)上通過 JSON-RPC 與服務(wù)器通信。下面是一個開發(fā)工具和語言服務(wù)器在進行編輯時如何通信的例子:

圖片來自 LSP 官網(wǎng),演示了協(xié)議如何在文檔引用(uri)和文檔位置級別與語言服務(wù)器通信。這些數(shù)據(jù)類型與編程語言無關(guān),適用于所有編程語言。
用戶在開發(fā)工具中打開一個文件(稱為文檔):開發(fā)工具通知語言服務(wù)器文檔已打開(textDocument/didOpen)。從現(xiàn)在開始,關(guān)于文檔內(nèi)容的真實信息不再存儲在文件系統(tǒng)中,而是由開發(fā)工具保存在內(nèi)存中?,F(xiàn)在必須在開發(fā)工具和語言服務(wù)器之間同步內(nèi)容。
用戶進行編輯:該開發(fā)工具通知服務(wù)器文檔更改(textDocument/didChange),并由語言服務(wù)器更新文檔的語言表示形式。在這種情況下,語言服務(wù)器會分析這些信息,并將檢測到的錯誤和警告通知開發(fā)工具(textDocument/publishDiagnostics)。
在打開的文檔中,用戶就一個符號(symbol)執(zhí)行 Go to Definition:該開發(fā)工具發(fā)送一個帶有兩個參數(shù)的 “textdocument/Definition” 請求:(1)文檔 URI 和(2)發(fā)出 “Go to Definition” 請求的文本位置,發(fā)送到服務(wù)器。服務(wù)器的響應(yīng)包含文檔 URI 和該符號在該文檔中的定義位置。
**用戶關(guān)閉文檔(文件) **:開發(fā)工具發(fā)出 “textDocument/didClose” 的通知,告知語言服務(wù)器文檔現(xiàn)在不在內(nèi)存中了。文件系統(tǒng)上的當(dāng)前內(nèi)容現(xiàn)在是最新的。
看一個具體的 “textDocument/definition” 示例,以 Go 語言為例,請求如下:
對此請求的響應(yīng):
如果你想要開發(fā)一個 Language Server,可以看官方的協(xié)議規(guī)范。
gopls 是什么
經(jīng)過上面對 LSP 的介紹,你應(yīng)該猜到 gopls(讀音:go please) 是什么了吧?!沒錯,gopls 是 LSP 的一個語言端(Server)實現(xiàn),是針對 Go 語言的 LSP 實現(xiàn)。
在 LSP 官網(wǎng)列出了相關(guān)的實現(xiàn),包括三個部分。
1、Language Servers:列出各個語言的 LSP 實現(xiàn)
其中 Go 語言的實現(xiàn)有兩個:(Sourcegraph 的不再維護,因為集中維護一個會更好)

在另一個由 Sourcegraph 維護的網(wǎng)站 https://langserver.org/ 中,不但列出了實現(xiàn) LSP 的語言,而且給出了它們對協(xié)議的實現(xiàn)完整性。

也就是說 gopls 是 Go 官方維護的、對 LSP 的實現(xiàn),即一個 Go 語言的官方 Language Server。
2、LSP Clients:列出支持 LSP 的開發(fā)工具
包括 VSCode、Sublime Text、Atom、Emacs、Vim 和 Eclipse 等很多開發(fā)工具。在上文提到的兩個網(wǎng)站都有列出。
3、SDKs for LSP:為了方便開發(fā)
為了方便開發(fā),還有一些 LSP 的 SDK 可以使用。具體可以查看:https://microsoft.github.io/language-server-protocol/implementors/sdks/。
進一步了解 gopls
首先說明下,目前 gopls 還不是穩(wěn)定版本,處于 alpha 狀態(tài),所以 VSCode 默認沒有啟用它。項目地址:https://github.com/golang/tools/tree/master/gopls。
目前 gopls 支持的特性包括:
Autocompletion
Jump to definition
Signature help
Hover
Document symbols
References
Rename
目前已知存在如下的問題:
Editing multiple modules in one editor window: #32394[1]
Type checking does not work in cgo packages: #35721[2]
Does not work with build tags: #29202[3]
Find references and rename only work in a single package: #32877[4]
當(dāng)前 gopls 的工作重點是確保穩(wěn)定性(期待發(fā)布 1.0 版本),之前一直受詬罵的是資源占用,目前已經(jīng)好太多了。
有如下編輯器支持 gopls,你可以根據(jù)自己喜愛的編輯器查看相應(yīng)的安裝、配置說明。
VSCode[5]
Vim / Neovim Vim/Neovim[6]
Emacs[7]
Acme[8]
Sublime Text[9]
Atom[10]
玩轉(zhuǎn) VSCode 的文章會詳細介紹在 VSCode 中使用 gopls。同時,后續(xù)在 VSCode 開發(fā)其他語言項目時,也會介紹相應(yīng)語言的 LSP。
參考資料
[1]
#32394: https://github.com/golang/go/issues/32394
[2]
#35721: https://github.com/golang/go/issues/35721
[3]#29202: https://github.com/golang/go/issues/29202
[4]#32877: https://github.com/golang/go/issues/32877
[5]VSCode: https://github.com/golang/tools/blob/master/gopls/doc/vscode.md
[6]Vim / Neovim Vim/Neovim: https://github.com/golang/tools/blob/master/gopls/doc/vim.md
[7]Emacs: https://github.com/golang/tools/blob/master/gopls/doc/emacs.md
[8]Acme: https://github.com/golang/tools/blob/master/gopls/doc/acme.md
[9]Sublime Text: https://github.com/golang/tools/blob/master/gopls/doc/subl.md
[10]Atom: https://github.com/golang/tools/blob/master/gopls/doc/atom.md
-END-

???小貼士
隱藏菜單:返回上一級?回復(fù)?“?內(nèi)推?"關(guān)鍵詞,獲取騰訊、阿里、百度、字節(jié)跳動等大廠的內(nèi)推機會!
