coc.nvim は VimのLSPプラグインの一つで、コード補完や定義ジャンプを提供したり、ドキュメントを良い感じに出してくれる。cocはプラグインであるにも関わらず、それ自体が拡張機能(エクステンション)を持っており、使いたい言語の拡張を入れるだけで細かい設定が要らないのが大きな特徴である。あとFloating Windowの表示がきれい。
ただ、個人的にLSPプラグインはリント・コードフォーマットの組み合わせ方が難しいと思っている。なぜなら、cocはいずれの機能も提供するものの、特定のフォーマッタをピンポイントで入れるというのがなかなか難しいからである。拡張が設定を用意していない限り、カスタマイズが難しい。
なので自分は、LSPには基本的な補完機能とリントを、aleにコードフォーマットを任せている。こうすることで、cocの快適な機能を享受しつつも、aleで非同期に(カーソル動作をブロックせずに)コードフォーマットも行えている。
本題になるが、今、自分はGoのLSPである gopls を使っており、これは coc-go が提供するが、残念がら golint を使うことはできない。リントをcocに任せている以上、golintもLSPとして連携されなければならない、という問題がある。
こう言うときに使えるのが diagnostic-languageserver である。これは、任意のコマンドをLSP化してくれるもので、coc向けには coc-diagnostic が提供されている。これを活用することで、例えば JSのeslintやdockerfileのhadolintなんかもLSPとして組み込むことができる(!)
以下、導入方法を順に説明すると、
coc-diagnosticをインストールする。
:CocInstall coc-diagnostic
でも良いし、 Vim Plugで管理しているのであれば
Plug 'iamcco/coc-diagnostic', {'do': 'yarn install --frozen-lockfile && yarn build'}
と書くこともできる。
golintをインストールする。
地味に気づかなかったりるけど、入っていないと当然動かない。
go get github.com/golang/lint
coc-settings.json
に下記を設定する{ ... "languageserver": { "dls": { "command": "diagnostic-languageserver", "args": ["--stdio"], "filetypes": [ "go" ], "initializationOptions": { "linters": { "golint": { "command": "golint", "rootPatterns": [], "isStdout": true, "isStderr": false, "debounce": 100, "args": ["%filepath"], "offsetLine": 0, "offsetColumn": 0, "sourceName": "golint", "formatLines": 1, "formatPattern": [ "^[^:]+:(\\d+):(\\d+):\\s(.*)$", { "line": 1, "column": 2, "message": [3] } ] } }, "formatters": {}, "filetypes": { "go": "golint" }, "formatFiletypes": {} } } } }
そうするとこんな感じで coc経由できちんとgolintの出力が見れると思います。 golintは出力にlevelがないので、すべてerrorとして表示されるのが少し気になるけど。
こんな感じで意外と楽に任意のリンタが追加できます。他のリンタについてもWikiに設定例がたくさん紹介されているので、参考まで。
以上です。