新しいMacにEmacsの設定を入れているときに,ほかはいつもどおり行ったのだが,goのlspだけがTimeoutするようになってしまった. 具体的には,
lsp-request: Timeout while waiting for response. Method: textDocument/definition.
というエラーが出る.
ちなみに使っているのは,
の組み合わせ.
ちなみに他のMacやLinuxとは共通の設定を使っており,そちらは正常に動いてたので,この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も発生しなくなった.