Emacsのlsp-requestがtimeoutする

新しいMacEmacsの設定を入れているときに,ほかはいつもどおり行ったのだが,goのlspだけがTimeoutするようになってしまった. 具体的には,

lsp-request: Timeout while waiting for response. Method: textDocument/definition.

というエラーが出る.

ちなみに使っているのは,

の組み合わせ.

ちなみに他のMacLinuxとは共通の設定を使っており,そちらは正常に動いてたので,このMacの設定がなにかおかしい.

どんな設定になってんの?

(use-package lsp-mode
  :custom
  (
   (lsp-inhibit-message t)
   (lsp-message-project-root-warning t)
   (create-lockfiles nil)
   )
  :bind
  (
   ("M-/" . lsp-find-references)
   )
  :hook
  (prog-major-mode . lsp-prog-major-mode-enable)
  )

(use-package go-mode
  :commands go-mode
  :config
  (setq indent-tabs-mode nil)
  (setq c-basic-offset 4)
  (setq tab-width 4)
  (setq gofmt-command "goimports")
  (define-key go-mode-map (kbd "C-c C-k") 'go-fill-struct)
  (setq lsp-prefer-flymake nil)
  (eval-after-load 'flycheck
    '(add-hook 'flycheck-mode-hook #'flycheck-golangci-lint-setup))
  :hook
  (go-mode . (lambda () (add-hook 'before-save-hook 'gofmt-before-save)))
  (go-mode . (lambda ()
               (hs-minor-mode 1)))
  (go-mode . (lambda ()
               (setq indent-tabs-mode t)))
  (go-mode . lsp)
  (go-mode . flycheck-mode)
  )

こんな感じ.

他のLSPは無事?

go以外のLSPはどうだろう,というわけで

を試してみたのだが,javascriptもrustのコードも問題なく解析されており,Timeoutも発生しない.つまりgoplsだけがおかしい.

そもそもgopls動いている?

emacsを起動後,goのファイルを開くとgoplsのプロセス自体は起動している.Emacs側にも

LSP :: Connected to [gopls:51617 status:starting].

というログは出てきており,このPIDでgoplsが立ち上がっているように見える.

ただこれが正常に動いているのかはわからない.

セキュリティ系のソフトにブロックされている可能性を考えて,それらを無効にしてみたり,goplsの利用ポートを調べてみたりしたけど,変化はなかった.

その他のログ

Emacsのバッファに,lspのログが出るようになっている.

  • *gopls:stderr*
  • *gopls

といったバッファなのだが,そこは何も出力されていなかった.

また,本来,

LSP :: Connected to [gopls:51617 status:starting].

のあとには,

LSP :: gopls:51617 initialized successfully

というログが出る必要があるのだが,これが出ていない.代わりに

Operation not permitted ~/.Trash

というエラーが出ている.ゴミ箱へのアクセス権がない?どういうことだ?なぜlspがゴミ箱のアクセス権を要求するのか?

ゴミ箱のアクセス権としてchmod +rとかchmod +xとかしても変化がない.これはおかしい.

というわけでsudo emacsしてみたところ,権限のエラーが消えた代わりに

There are 24512 files in folder ~/ so watching the repo may slow Emacs down.
Do you want to watch all files in ~/?

というようなメッセージが表示されるようになった.なぜかEmacsがホームディレクトリ以下のすべてのファイルをwatchしようとしているぞ.

原因

原因はlspのworkspaceだった.どこかのタイミングでホームディレクトリあたりに作ったgoファイルを開いてしまい,その際にworkspaceを聞かれてホームディレクトリをlspのworkspaceに追加してしまった

そして,自分のgoのソースコードはたいてい,GOPATH$HOMEとか$HOME/.dev とかにすることが多いので,ホームディレクトリ配下(~/src/github.com/h3poteto/kube-job)ということになってしまう. そのため,goのlspが起動した時点でホームディレクトリ配下のファイルを全スキャンしてlspに食わせようとしてくる.

このときに,前述の Operation not permitted ~/.Trashというエラーが出るのであった.

というわけで,解決策としては M-x lsp-workspace-folders-removeして,ホームディレクトリをworkspaceから削除すれば良い. これだけで無事goplsは初期化に成功するようになり,lspのTimeoutも発生しなくなった.