Vim で使える LSP クライアント各種を使った感想

この記事は [Vim Advent Calendar 2019](https://qiita.com/advent-calendar/2019/vim) 向けに書かれていたのですが、やめました。
なんか、個人的な感想を羅列する記事になってしまい、微妙だったため。。。

# はじめに
たくさん記事が出ているので皆さんご存知かもしれませんが、
最近の Vim は [LanguageServer Protocol](https://microsoft.github.io/language-server-protocol/) の台頭によって IDE ライクな機能が多数使えるようになってきています。

- Go To Definition
- （賢い）Completion
- （ファイルを跨がった）Rename
- Hover documentation
- Signature Help
- Formatting
- Refactor

などなどです。

それもこれも Microsoft さんが LSP 仕様を策定し、
言語開発者達が Language Server を用意し、
Vim もどんどん進化を続けているからに他ならないなと思います。


# この記事について
自分は LSP 向けのプラグインを多数試してきました。
そしてついには自作するに至りました。（どんだけ進捗を犠牲にしているのか…）
そういうわけで、この記事では多数あるプラグインを使ってみた感想を書いていこうと思います。

# プラグイン達
今回取り上げるのは下記のプラグインたちです。

- coc.nvim
- vim-lsp
- vim-lsc
- LanguageClient-neovim
- neovim built-in lsp

では一つ一つ使ってみた感想を書いていきます。

## coc.nvim
#### 特徴
- TypeScript で書かれている（使うには node のインストールが必要）
- All-in-one（自動補完機能、スニペット機能、ファイル検索などがくっついてくる）
- プロトコル対応が最も進んでいて機能が豊富（利用者は特に意識せず便利に使える）
- セットアップが非常に簡単
- コミュニティはとても強い（使っている人がとても多い）
- 1 ファイルタイプに対して、複数言語サーバに対応

#### 感想
とにかく熱量を感じるプロダクト。機能もとても多い。
ただ、go を書きたいだけなのに node を要求されたり、そこは好き好き。
導入も簡単で機能も豊富なので「LSP プラグイン何がおすすめ？」と言われればこれを一番におすすめする。
coc.nvim は LSP に対応しているが「coc.nvim が提供する API にサーバの機能を接続する」という形で実現されている。
つまり、LSP に対応していないツール（例えば eslint など）も、coc.nvim の API につなげれば使えるようになる。（実際、coc-eslint が存在する）

（ちなみに 逆の発想で「ツールを LSP のプロトコルに合わせて利用する」というプロダクトも存在する、efm-langserver や diagnostic-languageserver など）

なぜ使っていないのか？というと、

- 良くも悪くも All-in-one である
    - 自動補完機能だけ別のプラグインにしたいなーといったことはできない
    - まあ、自動補完くらいかな？問題になるのは

とかが理由。正直 coc.nvim 使えばいいのに...と自分でも思う。


## vim-lsp
#### 特徴
- Pure Vim script で書かれている
- 他プラグインとの連携手段が豊富（自動補完は deoplete.nvim、スニペットは ultisnips など）
- LSP の機能に比較的多く対応している
- コミュニティは強い（日本語圏だと vim-jp slack で気軽に質問できる）
- 1 ファイルタイプに対して、複数言語サーバに対応

#### 感想
一番お世話になった期間が長いプラグイン。
界隈のプラグインの中では活発に開発が進んでいる方だと思う。
ソースコードがわかりやすく、なにか問題が見つかった時に自力で直しやすい。
最近は動作もかなり安定している。
vimrc のポータビリティも大事だし機能の豊富さも大事って人はこれがおすすめ。

便利に使うには自動補完機能の入ったプラグインなどがあったほうがいいが、それは自力で設定する必要がある。そこまで難しくはない。

## vim-lsc
#### 特徴
- Pure Vim script で書かれている
- 自動補完機能を内蔵している（coc.nvim 以外では珍しい！）
- LSP の機能はそこまで対応していない（よく使うものは流石に対応している）
- 動作が安定している（ほとんどバグったことがない）
- ファイルタイプにつき、言語サーバは一つまで

#### 感想
当時、vim-lsp に個人的にクリティカルな不具合があって vim-lsc を使っていた。今は複数言語サーバに対応していて欲しいので vim-lsp に戻っている。
（現状は vim-lsp の動作はかなり安定してるのでご心配なく）
とりあえず動作が安定しているというのが強い。
coc.nvim 以外では珍しくビルトインで自動補完に対応している。
あまりプラグインを入れたくないんだよなって人は、Pure Vim script でポータブルだし、入れるだけで便利になるのでいいかもしれない。


## LanguageClient-neovim
#### 特徴
- Rust で大部分がかかれている
- LSP の機能に比較的多く対応している
- デフォルトで有名なプラグインと連携してくれる（珍しい。他のプラグインは極力依存を切り離す方向で考えられている）
- ファイルタイプにつき、言語サーバは一つまで

#### 感想
はじめて利用した LSP プラグインはこれだった気がする。
デフォルトで denite.nvim や deoplete.nvim や fzf.vim に対応している。
すでにそれらのプラグインを利用している人はこれを入れると簡単に統合できていいかもしれない。

## neovim built-in lsp
#### 特徴
- 大部分が Lua で書かれている
- エディタレベルで行差分を検出して言語サーバに送るのでおそらく一番軽い（多分）
- コミュニティは最強クラス（neovim built-in なので...）
- UI がイケてる（代わりに、実装されている機能はまだ少なめ）
- neovim でしか利用できない

#### 感想
エラー箇所をハイライトしたり、エラー文言を表示したりする UI にこだわりを感じる。
動きもかなりサクサクしていて、仕組み的に大きなファイルを開いても遅くなりにくいはず。
neovim しか使わないし、今後に期待！という人はこれがいいかもしれない。


# まとめ
まとめてみると、それぞれのプラグインに方針の違いや強みがあるなあと思った。

自作のプラグインはいろいろ使ってみて、ここがいいなと思った点を各種取り入れるように頑張ってみてはいます。まだ安定してないのですが…。

他にも、LSP のスニペット機能を実現するプラグインも書いていてこっちはもうすでにちゃんと動いてるので興味があったら使ってみてください。

このスニペット向けのプラグインは、上述したプラグインと合わせて使うこともできます。

- https://github.com/hrsh7th/vim-vsnip
- https://github.com/hrsh7th/vim-vsnip-integ

最後の最後に宣伝になってしまった…。