Gopls: Emacs の使用

gopls のインストール

Emacs で gopls を使用するには、まず gopls 実行可能ファイル をインストールし、結果として生成されるバイナリ ($(go env GOBIN) または $(go env GOPATH)/bin) を含むディレクトリが PATH に含まれていることを確認する必要があります。

Emacs LSP クライアントの選択

Emacs で gopls を使用するには、Emacs LSP クライアントパッケージを選択してインストールする必要があります。2つの人気のあるクライアントパッケージは、LSP ModeEglot です。

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 モジュールのための project の設定

Eglot は、新しく開かれたバッファの LSP ワークスペースを識別するために、組み込みの project パッケージを使用します。project パッケージは、GOPATH または Go モジュールについてネイティブには認識していません。幸いにも、カスタムフックを与えることで、最も近い親の 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)

Eglot の最新バージョンにアップグレードするには、M-x eglot-upgrade-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 がプロジェクトフォルダを要求したとき、モジュールを使用している場合はモジュールのルートフォルダ(つまり、「go.mod」があるディレクトリ)を選択する必要があります。GOPATH を使用している場合は、$GOPATH をフォルダとして選択してください。
  • Emacs は、環境 (PATH、GOPATH など) が適切に設定されている必要があります。M-x getenv <RET> PATH <RET> を実行して、Emacs で PATH が設定されているかどうかを確認できます。設定されていない場合は、ターミナルから Emacs を起動する、[このパッケージ][exec-path-from-shell] を使用する、またはシェル設定を .bashrc から .profile に移動してログアウトおよび再ログインを試すことができます。
  • LSP クライアントモードは1つだけインストールされていることを確認してください。(例えば、lsp-mode を使用している場合、eglot も有効になっていないことを確認してください。)
  • *lsp-log* バッファでエラーを探すか、M-x eglot-events-buffer を実行してください。
  • Gophers slack#emacs チャンネルで助けを求めてください。

このドキュメントのソースファイルは、golang.org/x/tools/gopls/doc の下にあります。