A Day In The Life

とあるプログラマの備忘録

go-mode + lps-modeを使ってEmacsのGolang開発環境を整える

以前の記事 go-mode + eglotを使ってEmacsのGolang開発環境を整える - A Day In The Life で eglot を使った Go の開発環境構築方法を紹介しましたが、今回は lsp-mode を使って環境を構築してみたいと思います。前回と同じく Go の Language Server は gopls を使います。

動作確認バージョン

Emacsは25以上、Golangは1.11以上なら問題なく動作するはずです。

gopls のインストール

Go の Language Server は3種類あります(bingo 最近は開発を中止したみたいです)。

前回同様 gopls をインストールします。

$ go get -u golang.org/x/tools/cmd/gopls 

goimportsのインストール

こちらも前回同様、Go の import を整理してくれるコマンドもついでにインストールしておきます。

$ go get golang.org/x/tools/cmd/goimports

init.el の設定

入力補完は company-mode を使います。あと GOPATH や GOROOT など環境変数設定のために exec-path-from-shell を使います。

;; パッケージ管理サーバ
(require 'package)
(add-to-list 'package-archives '("melpa" . "http://melpa.org/packages/") t)
(add-to-list 'package-archives '("marmalade" . "http://marmalade-repo.org/packages/"))
(package-initialize)
;; パッケージ情報の更新
(package-refresh-contents)

;; インストールするパッケージのリスト
(defvar my/favorite-packages
  '(
    use-package
    exec-path-from-shell
    ))
;; my/favorite-packagesからインストールしていないパッケージをインストール
(dolist (package my/favorite-packages)
  (unless (package-installed-p package)
    (package-install package)))

;; シェルに設定されている環境変数を引き継ぐ
(exec-path-from-shell-initialize)

;; lsp-mode
;; プロジェクトルートで M-x lsp-workspace-folder-add を実行すること
(use-package lsp-mode
  :ensure t ;自動インストール
  :custom ((lsp-inhibit-message t)
         (lsp-message-project-root-warning t)
         (create-lockfiles nil))
  :hook
  (prog-major-mode . lsp-prog-major-mode-enable)
  :config
  (setq lsp-response-timeout 5))
(add-hook 'hack-local-variables-hook
          (lambda () (when (derived-mode-p 'go-mode) (lsp))))

;; company-lsp integrates company mode completion with lsp-mode.
;; completion-at-point also works out of the box but doesn't support snippets.
(use-package company-lsp
  :ensure t
  :commands company-lsp)

;; Company mode is a standard completion package that works well with lsp-mode.
(use-package company
  :ensure t
  :config
  (global-company-mode)
  ;; Optionally enable completion-as-you-type behavior.
  (setq company-idle-delay 0)
  (setq company-minimum-prefix-length 1)
  (setq completion-ignore-case t)
  (setq company-dabbrev-downcase nil)
  (setq company-selection-wrap-around t))

;; go-mode
(use-package go-mode
  :ensure t
  :commands go-mode
  :config
  (setq gofmt-command "goimports")
  (add-hook 'before-save-hook 'gofmt-before-save))

emacs-lispのコードはこちらに置いてます。

プロジェクトルートが見つからない時の対策

Monorepo 構成で Go プロジェクトが複数存在する場合に lsp-mode がプロジェクトルートが判別できずローカルのパッケージの補完ができないことがあります。その場合は Emacs を起動後、以下のコマンドで追加します。

M-x lsp-workspace-folder-add

関連記事

参考