All Articles

NeovimでLSPを使う

C++の開発環境を Neovim で実現しようとしていろいろ調べていたところ、Neovim に Language Server Protocol(LSP)を導入したという記事をいくつか見つけたのでやってみた。

LSP の説明はこの記事読むとして、概略してコードの補完や参照などがエディタの種類にかかわらずアクセスすることで利用可能になるサーバーという認識で良いのかな。
これまでもdeopleteと言語ごとにプラグインを導入することで補完をすることはできていたんだけど、LSP 使うと大分高速にできる、さらにリンターとしても利用できるみたいなので乗り換えてみようと思った次第です。

LanguageClient-neovim

まず Neovim で LSP を利用するために、LanguageClient-neovimをインストールします。
私は dein.vim でプラグイン管理しているので、

[[plugins]]
repo = 'autozimu/LanguageClient-neovim'
rev = 'next'
build = 'bash install.sh'

dein.tomlに書き込んで Neovim を起動させインストールします。
LanguageClient-neovim 以外にも LSP のプラグインはvim-lspとかあるみたいなんだけど、LanguageClient-neovim はdeopleteで使える!と見たので、よく意味はわかってないんですがこちらを選択しました。
そして言語ごとのサーバーをインストールし、LanguageClient-neovim で参照することで LSP を利用します。
利用できるサーバーの一覧はこちらのページに載っています。

C/C++

C/C++用のサーバーはclangd,cquery,cclsがあるみたいで、clangdだけが機能的に他のものに劣っているようなことが先程の一覧ページに書いてあります。
なので最初はcqueryを導入しようと思ってたんですが、なんかうまく動かなかったので結局clangd使うことにしました。
clangdはもともとclangとかllvmをインストールしていたので、私の環境では何も追加でインストールせず使えました。
設定は、

[[plugins]]
repo = 'autozimu/LanguageClient-neovim'
rev = 'next'
build = 'bash install.sh'
hook_add = '''
    set hidden
    let g:LanguageClient_autoStart = 1
    let g:LanguageClient_serverCommands = {
        \ 'c': ['clangd'],
        \ 'cpp': ['clangd'],
\ }
'''

と書けば(とりあえずは)動きます。
動いているかの確認は、適当な C/C++ファイルを開いてコード打って補完候補が出てくるかどうかでできます。
ただ、私の環境だとそもそも LSP が立ち上がっていなかったり、立ち上がっていてもclangdを呼び出してくれないなどトラブルが頻発しました。
設定をdein.tomlの上の方に書いたら直ったんで今は動いてますが、どうして起動しなかったりしたのかは結局よくわからないです。

追記

これhook_sourceじゃなくてhook_addって書く必要があったぽい、そのせいだったかもしれない。

設定中のlet g:LanguageClient_autoStart = 1は LSP を自動起動するというものです。起動していなくても、手動で:LanguageClientStartとコマンドに打つことで起動することができます。

Python

どうせなので Python 用の LSP も導入します。
2 つあるようですが、GitHub のスター数的にPython Language Serverを導入すればいいでしょう。
インストールはpip install python-language-serverで行います。
そしてREADME.mdに書かれてあるとおり、いくつかのプラグインをオプションとして用いることが可能なようです。
私はこの中からリンターであるpycodestyle(以前までpep8と呼ばれていたもの)とコードを保存時にフォーマットしてくれるyapfを導入しました。
導入には、

$ pip install 'python-language-server[pycodestyle]'
$ pip install 'python-language-server[yapf]'

などとすれば良いようです。
そして LanguageClient-neovim の設定に、

    let g:LanguageClient_serverCommands = {
        \ 'python': ['pyls'],
\ }

を追記すれば動きます。
おそらくこれでリンターも動くはずなので(まだ確認していないのですが)、alepylintとかを動かしていたのですが、これらを削除しました。
こんな感じです。まだキーコンフィグ全く設定していないので、そのうち追記するかと思います。

Reference