Vimにcoc.nvimを入れたら便利すぎて感動したっていう話


ぼくはパソコンは実家にしか無く、開発系は全てAndroidのTermuxで済ませなくてはなりません。
(Termuxを使えば結構色々なLinux系のコマンド、ソフトを使えるのでたいへん助かってます)
よって、ぼくの開発環境は"ポケットIDE"。そう、(neo)Vimです。

こういうわけで、開発毎に、それぞれの言語の補完プラグイン、Linter(これはうまく動かなかったのだが)を入れ、またファイラを入れ、がんばっていた訳です。

プロローグ

数年前、ネットをVimについてググりサーフィンしていると、"LSP"という単語が目に入りました。"Language Server Protocol"。どうやら、コーディング補助系について規格化したものであるようなのです。
(参考:https://langserver.org/)

Vimに対応させるプラグインも出てきたと聞いて、すぐ飛びついた訳ですが、当時、ぼくは英語力も拙く、READMEさえも読めずにうまく設定すらもできないで諦めてしまいました。

受験を経て、ある程度英語力もついたことだし、または、LSP界隈も活発になっているかも?と期待して、調べてみると、実装も複数なされていて、どうやら聞き覚えのないものも出てきているようです。その一つがcoc.nvimでした。

coc.nvimの導入

Vim(8.0.1453以上) || Neovim(0.3.1以上)が必要です。

まず、Node.jsとyarnを入れましょう。

install.sh
apt install nodejs
npm install -g yarn

あとはcoc.nvim自体をいつものパッケージマネージャなどの方法で加えるだけです。

vim-plugを導入済みの場合

ぼくはvim-plugなので、以下をinit.vim(vimrc)に書き加えます。

init.vim
Plug 'neoclide/coc.nvim', {'branch': 'release'}

そして :PlugInstall をノーマルモードでEnter。
インストール時に色々足りないって注意されたのですが、その都度指摘してくれ、選択すれば自動でそれらをインストールしてくれました。

これで終わりです。このページも参照してみてください。

各種設定など

:help coc-nvim.txtでヘルプが見れます。

coc.nvimの設定ファイルはコマンド:CocConfigで開くことができます。ただ、デフォルトでも使いにくいわけではないです。

また、coc.nvimのExtension、というものがあり、機能追加・拡張ができます。各言語のlanguageserverもあります。
coc.nvimの拡張専用のパッケージマネージャがあり、それでExtensionを管理してくれます。

試しにtypescript/javascriptのサーバーであるcoc-tsserverを入れてみます。コマンドモードで以下をEnter:

cocinst.vim
:CocInstall coc-tsserver

また、設定すれば、Extensionにないサーバーも使えます。

(2021/01/03追記:現在はC言語のcocエクステンションも存在するようですが、エクステンションにないLSPサーバーの設定方法の例示として以下を残しておきます)

例えば、C系のサーバーのclangdだと、coc.nvimの設定ファイルに、

coc-settings.json
{
  "languageserver": {
    "clangd": {
      "command": "clangd",
      "filetypes": ["c", "cpp", "objc", "objcpp"]
    }
  }
}

このように書けば使えるようになります。
ここに、各種言語について設定方法などをまとめて下さっているので参照してみてください。

coc.nvimの機能

coc.nvimで対応が実装されている各機能を調べてみました。

AutoCompletion

デフォルトでリアルタイムの補完が効きました。

また、何もサーバーなどを登録せずとも、Vimでデフォルトで使える補完の、ファイル、バッファ、aroundの補完候補は一覧で出てきます。

Diagnostics

エラー、警告、インフォメーションが表示されます。その場所にカーソルを合わせるとメッセージが見れます。

画面左端のアイコンの背景色・文字色の設定をするには、init.vim(vimrc)に、例えば以下のようにして書き加えます。

init.vim
highlight CocErrorSign ctermfg=15 ctermbg=196
highlight CocWarningSign ctermfg=0 ctermbg=172

15、196、0、172が色です。このサイトの"Xterm Number"を参照してみてください。

CocList

多機能セレクタと呼ばれるものです。かなり便利です。CtrlPに類似しています。
デフォルトでもextentionのトグル、diagnosticsのリスト表示とジャンプ、symbolの検索まで色々できます。
さらに、拡張coc-listsを入れると、ファイル検索、grep検索、buffer移動など、もう何でもできます…
何でも突っ込んだ感じになる機能ですが、あいまい検索ができるので割とスムーズに操作できます。

Vimプラグイン(cocの拡張ではない)の coc-fzf(リンク)を入れると候補の検索にFZFを使うようになり、軽快な動作になります。
詳しくは こちら で別に扱っているので興味があれば御覧ください。

Hover

ヒント(ホバー)を読むことができます。
2019/06/25の時点では、NeoVimのnightlyビルドではfloating windowが使えるようですが、これはそれにも対応しています。
残念ながら、Termux版はstableのみなのでpreview windowにヒントが表示されています。

【2019年9月27日追記】
Termux版のNeoVimでfloating windowが有効になったようです。

References

参照先を一覧にして見ることができます。

Definition

定義にジャンプします。

別ファイルに定義が書いてある場合、別ファイルのバッファを開き、ジャンプしてくれます。

Rename

変数名などを一括リネームします

Format

ソースコードを綺麗に整えます。

機能の呼び出し方

多数の機能がある!と言うことは調べてみて割とすぐにわかったのですが、呼び出し方がちょっと引っかかったのでメモしておきます。

機能 呼び出し方
AutoCompletion insertモードで既に有効
Diagnostics 画面左端にマーク表示されている
CocList内にリスト有
CocList :CocListコマンドで呼び出し
Hover :call CocAction('doHover')で呼び出し
References <Plug>(coc-references)で呼び出し
Definition <Plug>(coc-definition)で呼び出し
Rename <Plug>(coc-rename)で呼び出し
Format <Plug>(coc-format)で呼び出し

これらをそれぞれショートカット設定などして呼び出す感じかな。
少しバラバラに思えるのですが、多分本当はもっと奥深く体系だった構成なのでしょう。
coc.txtをもっと読み解かなくては……。

init.vim(vimrc)の例

自分のinit.vimからcoc.nvim周りのものを抜粋・コメントしました。
もしよかったら参考にどぞ。

init.vim
call plug#begin('~/.vim/vim-plug')
  Plug 'itchyny/lightline.vim'
  Plug 'neoclide/coc.nvim', {'branch': 'release'}
call plug#end()

"LightLineにcoc.nvimのステータスを載せます
let g:lightline = {
  \'active': {
    \'right': [
      \['coc']
    \]
  \},
  \'component_function': {
    \'coc': 'coc#status'
  \}
\}

"Diagnosticsの、左横のアイコンの色設定
highlight CocErrorSign ctermfg=15 ctermbg=196
highlight CocWarningSign ctermfg=0 ctermbg=172

"以下ショートカット

"ノーマルモードで
"スペース2回でCocList
nmap <silent> <space><space> :<C-u>CocList<cr>
"スペースhでHover
nmap <silent> <space>h :<C-u>call CocAction('doHover')<cr>
"スペースdfでDefinition
nmap <silent> <space>df <Plug>(coc-definition)
"スペースrfでReferences
nmap <silent> <space>rf <Plug>(coc-references)
"スペースrnでRename
nmap <silent> <space>rn <Plug>(coc-rename)
"スペースfmtでFormat
nmap <silent> <space>fmt <Plug>(coc-format)

まとめや追伸

使ってみた感じですが、Androidスマホでもヌルヌルでサクサク動いて快適です。
これでまたvimが真のideに近づいていけます。
嬉しい限りですね。

この先、新たな発見等をしたら追記していこうと思います。