Gopls:在 Emacs 中使用
安裝 gopls
要在 Emacs 中使用 gopls
,您必須首先 安裝 gopls
可執行檔案,並確保包含生成二進位制檔案的目錄(即 $(go env GOBIN)
或 $(go env GOPATH)/bin
)已新增到您的 PATH
中。
選擇 Emacs LSP 客戶端
要在 Emacs 中使用 gopls
,您需要選擇並安裝一個 Emacs LSP 客戶端包。兩個流行的客戶端包是 LSP Mode 和 Eglot。
LSP Mode 採用“開箱即用”的方法,集成了許多功能,並且 lsp-mode
本身提供了許多額外的行為。
Eglot 採用最小侵入式的方法,專注於與其他成熟的包進行順暢整合。它提供了一些自己的 eglot-
命令,但預設情況下不提供額外的鍵繫結。
選擇好要使用的客戶端後,請按照軟體包說明進行安裝:參見 Eglot 1-2-3 或 LSP Mode 安裝。
通用配置
Eglot 和 LSP Mode 都可以與 Emacs 生態系統中流行的包整合
- 內建的
xref
包提供交叉引用。 - 內建的 Flymake 包提供即時診斷疊加。
- Company 模式顯示程式碼補全候選(比內建的
completion-at-point
提供更豐富的 UI)。
Eglot 使用內建的 ElDoc 迷你模式提供文件,而 LSP Mode 預設使用其自己的 lsp-ui
模式提供文件。
Eglot 預設使用 [project
] 包定位專案根目錄。在 LSP Mode 中,可以透過 lsp-auto-guess-root
設定來配置此行為。
配置 LSP Mode
在 .emacs
中載入 LSP Mode
(require 'lsp-mode)
(add-hook 'go-mode-hook #'lsp-deferred)
;; Set up before-save hooks to format buffer and add/delete imports.
;; Make sure you don't have other gofmt/goimports hooks enabled.
(defun lsp-go-install-save-hooks ()
(add-hook 'before-save-hook #'lsp-format-buffer t t)
(add-hook 'before-save-hook #'lsp-organize-imports t t))
(add-hook 'go-mode-hook #'lsp-go-install-save-hooks)
透過 LSP Mode 配置 gopls
有關可用的 gopls 設定資訊,請參見 設定。
穩定的 gopls 設定在 lsp-mode
中有相應的配置變數。例如,(setq lsp-gopls-use-placeholders nil)
將停用補全片段中的佔位符。有關可用變數列表,請參見 lsp-go
。
可以透過 lsp-register-custom-settings
配置實驗性設定
(lsp-register-custom-settings
'(("gopls.completeUnimported" t t)
("gopls.staticcheck" t t)))
請注意,更改設定後,您必須使用例如 M-x lsp-restart-workspace
來重新啟動 gopls。
配置 Eglot
在 .emacs
中為 Go modules 配置 project
Eglot 使用內建的 project
包來識別新開啟的緩衝區的 LSP 工作區。project
包本身不瞭解 GOPATH
或 Go modules。幸運的是,您可以為其提供一個自定義鉤子,告訴它查詢最近的父級 go.mod
檔案(即 Go 模組的根目錄)作為專案根目錄。
(require 'project)
(defun project-find-go-module (dir)
(when-let ((root (locate-dominating-file dir "go.mod")))
(cons 'go-module root)))
(cl-defmethod project-root ((project (head go-module)))
(cdr project))
(add-hook 'project-find-functions #'project-find-go-module)
在 .emacs
中載入 Eglot
;; Optional: load other packages before eglot to enable eglot integrations.
(require 'company)
(require 'yasnippet)
(require 'go-mode)
(require 'eglot)
(add-hook 'go-mode-hook 'eglot-ensure)
;; Optional: install eglot-format-buffer as a save hook.
;; The depth of -10 places this before eglot's willSave notification,
;; so that notification reports the actual contents that will be saved.
(defun eglot-format-buffer-before-save ()
(add-hook 'before-save-hook #'eglot-format-buffer -10 t))
(add-hook 'go-mode-hook #'eglot-format-buffer-before-save)
使用 M-x eglot-upgrade-eglot
升級到最新版本的 Eglot。
透過 Eglot 配置 gopls
有關可用的 gopls 設定資訊,請參見 設定。
LSP 伺服器設定由 eglot-workspace-configuration
變數控制,該變數可以在 .emacs
中全域性設定,也可以在專案根目錄的 .dir-locals.el
檔案中設定。
.emacs
:
(setq-default eglot-workspace-configuration
'((:gopls .
((staticcheck . t)
(matcher . "CaseSensitive")))))
.dir-locals.el
:
((nil (eglot-workspace-configuration . ((gopls . ((staticcheck . t)
(matcher . "CaseSensitive")))))))
使用 Eglot 組織匯入
gopls
將 goimports
的匯入組織功能作為 LSP 程式碼操作提供,您可以透過執行 M-x eglot-code-actions
(或繫結到 eglot-code-actions
函式但您選擇的任意鍵)並在提示時選擇 Organize Imports
來按需呼叫它。
要在儲存前自動組織匯入,請新增一個鉤子
(add-hook 'before-save-hook
(lambda ()
(call-interactively 'eglot-code-action-organize-imports))
nil t)
故障排除
常見錯誤
- 當 Emacs 提示您輸入專案資料夾時,如果您正在使用 modules,則必須選擇模組的根資料夾(即包含“go.mod”的目錄)。如果您使用 GOPATH,請將您的 $GOPATH 選為您的資料夾。
- Emacs 必須正確設定您的環境(PATH、GOPATH 等)。您可以執行
M-x getenv <RET> PATH <RET>
來檢視您的 PATH 是否在 Emacs 中設定。如果未設定,您可以嘗試從終端啟動 Emacs,使用 [此包][exec-path-from-shell],或將您的 shell 配置從.bashrc
移動到.profile
並登出後重新登入。 - 確保只安裝了一個 LSP 客戶端模式。(例如,如果使用
lsp-mode
,請確保您沒有同時啟用eglot
。) - 檢視
*lsp-log*
緩衝區中的錯誤,或執行M-x eglot-events-buffer
。 - 在 Gophers slack 的
#emacs
頻道尋求幫助。Gophers slack。
本文件的原始碼可以在 golang.org/x/tools/gopls/doc 下找到。