Neovim 0.12の新機能 外せるプラグインと外せないもの
Neovim 0.12の変更点は:help newsにすべて載っています。ただ、あの一覧を上から読んでも自分の設定から何を削れるかは見えてきません。項目が機能の種類で並んでいて、プラグインとの対応で並んでいないからです。この記事は0.12の追加を「どのプラグインを外せるか」という一本の軸で並べ直したものです。個々の機能の詳しい使い方は担当の記事に渡します。
検証環境:Homebrewで入れたNVIM v0.12.4(macOS)。表の「そのまま呼べるか」の欄は、素のnvim --cleanを起動してexists(':Undotree')のような形で実際に問い合わせた値です。0.13で入る予定の変更はこの記事の対象外にしています。
目次(9項目)
置き換えの表
先に全体を出します。左が0.11までプラグインで足していたもの、右が0.12の標準機能です。いちばん右の欄が実際の手間で、ここに差があります。
| やりたいこと | 0.12の標準機能 | 要る手間 |
|---|---|---|
| プラグインの導入と更新 | vim.pack | init.luaに並べるだけ |
| 打ちながら候補を出す | autocomplete | :set autocomplete |
| 言語サーバの起動 | vim.lsp.enable() | 設定ファイルを1枚置く |
| undo履歴を目で見る | :Undotree | :packaddが要る |
| ディレクトリ同士の比較 | :DiffTool | :packaddが要る |
| quickfixの絞り込み | :Cfilter | :packaddが要る |
| 連続する重複行を消す | :uniq | 無し |
プラグイン管理が本体に入った
0.12でいちばん大きいのはvim.packです。プラグインマネージャそのものを入れるためのブートストラップが消え、init.luaにURLを並べるだけになりました。
vim.pack.add({
'https://github.com/nvim-lua/plenary.nvim',
})
ヘルプによると、vim.pack.add()は指定されたプラグインがディスクに無ければその場でcloneし、あれば何もせずに:packaddまで進みます。導入と読み込みが1つの呼び出しにまとまっているので、初回起動と2回目以降で書き分ける必要がありません。バージョンの固定や更新の流れは標準プラグイン管理vim.packの記事に書きました。
lazy.nvimから移るときに引っかかるのは遅延読み込みです。vim.pack.add()にはeventやftのような遅延の指定が無く、読み込みを遅らせたいときはloadに関数を渡して自分で:packaddのタイミングを決めます。プラグインを10本も20本も抱えている設定では、ここが移行の手間の中心になります。
補完のポップアップが1行で出る
0.12ではautocompleteというオプションが増えました。これを立てるだけで、打っている途中に候補のポップアップが出ます。手元の0.12.4で--clean起動から次の設定だけを入れて確かめました。
:set autocomplete complete=.^5 completeopt=popup,menu
const useまで打った時点でuserNameShortとuserNameLongが下に並びます。プラグインは1つも入れていません。候補の出どころはcompleteオプションで、.^5は「今のバッファから最大5件」という意味です。LSPの候補を混ぜたいときはvim.lsp.completion.enable()を併用します。
もっとも、nvim-cmpやblink.cmpを完全に置き換えられるかというと、そこは用途によります。ソースごとの見た目の作り込みやスニペットの展開まで含めると足りない部分が残ります。どこまでを標準で賄えるかは標準自動補完の記事で切り分けました。手で呼び出すCtrl-n系の補完は0.12より前から使えるので、標準入力補完の使い方も合わせて読むと候補の出どころが掴めます。
言語サーバは設定ファイル1枚で動く
LSPまわりは0.11から段階的に整理が進み、0.12ではvim.lsp.enable()が必要に応じてクライアントを起動・停止し、対象外のバッファからは切り離すところまで面倒を見るようになりました。lsp/ディレクトリに設定を1枚置いて名前を渡すだけです。手順は標準LSP設定の記事にまとめてあります。
nvim-lspconfigが不要になったかというと、少し違います。あのリポジトリの値打ちは起動のコードではなく、言語サーバごとの起動コマンドとルート判定を集めたカタログのほうにあります。0.12以降もlsp/の中身を写す先として参照することになります。
同梱されているのに、そのままでは呼べないもの
ここが0.12でいちばん引っかかりやすいところです。:help newsの「PLUGINS」には:Undotreeと:DiffToolが新機能として並んでいますが、素のNeovimを起動して打っても存在しません。これらはpack/dist/optに置かれた任意読み込みのパッケージで、:packaddを通してはじめて登録されるからです。
実際に数えました。nvim --cleanで起動し、exists()の戻り値を:packaddの前後で比べています。0は「無い」、2は「そのコマンドがある」という意味です。
| パッケージ | コマンド | packadd前 | packadd後 |
|---|---|---|---|
| nvim.undotree | :Undotree | 0 | 2 |
| nvim.difftool | :DiffTool | 0 | 2 |
| nvim.tohtml | :TOhtml | 0 | 2 |
| cfilter | :Cfilter | 0 | 2 |
| termdebug | :Termdebug | 0 | 2 |
| netrw | :Explore | 2 | 2 |
同じpack/dist/optに入っているのに、netrwだけは最初から呼べます。runtime/plugin/netrwPlugin.vimという小さな受付役が常に読まれていて、そこから本体を呼びに行くためです。matchitも同じ形で、%には最初から<Plug>(MatchitNormalForward)が割り当たっていました。つまり「optに入っている」ことと「使えない」ことは同じではありません。
気をつけたいのが:TOhtmlです。これは0.11まで既定で読み込まれていたものが、0.12で任意読み込みへ移されました。:help newsでも新機能ではなく破壊的変更の側に書かれています。バッファをHTMLに書き出す手順をスクリプトに組み込んでいた場合、0.12に上げた瞬間に「そんなコマンドは無い」で止まります。
毎回打つのが面倒なら、init.luaに1行足しておけば起動時に登録されます。
vim.cmd.packadd('nvim.undotree')
ただ、既定で読み込まれない理由は起動時間なので、使う日にだけ打つほうが素直です。:Undotreeと:DiffToolで何ができるかは標準の:Undotreeと:DiffToolの記事にあります。どのスクリプトが読み込まれているかを確かめたいときは:scriptnamesの使い方が早いです。
一覧では埋もれる小さな追加
見出しが付かないぶん見落としやすい追加もあります。手元の0.12.4で存在を確かめたものを並べます。
:uniq:隣り合った重複行を消します。:sort uと違って並べ替えないので、順序を保ったまま連続分だけ落とせます。:sortと重複行の記事と使い分けます:iput::putと同じですが、貼り付けた行のインデントを現在行に合わせます。インデントを増減する操作を後から当てる手間が減ります:retab -indentonly:行頭の空白だけを変換します。文字列の中のタブまで潰してしまう事故を避けられます。挙動の違いは:retabとexpandtabの記事に書きました- grtとgrx:既定のキーマップに型定義へのジャンプとcodelensの実行が加わりました
shadaの既定から/tmp/と/private/が外れました。:oldfilesの一覧が一時ファイルで埋まらなくなります- ZRと
:restart:設定を読み直すために抜けて入り直す手順が要らなくなります。詳しくは:restartとZRの記事にあります
まだ外せないもの
削れないほうも正直に書きます。ファジーファインダーは標準に入っていません。matchfuzzy()の中身がfzy相当の実装に入れ替わって精度は上がりましたが、あれは関数であって画面ではないので、telescope.nvimやfzf-luaの代わりにはなりません。プラグイン無しでファイルを開く手段としては:findでファイル名から探す方法が現実的な線です。
ツリー表示のファイラも0.12の時点では標準の外です。既定の一覧は依然としてnetrwで、0.13でdirに替わる予定になっています。この移り変わりは標準ファイラがnetrwからdirへ変わる記事とファイラープラグインの比較を見てください。Git連携も同じで、差分の記号を行番号の横に出すたぐいは今もプラグインの領分です。
0.12に上げた日、まず:Undotreeを打って「無い」と言われました。ニュースに新機能として書いてあるものが打って存在しないので、しばらくビルドの問題を疑っていました。pack/dist/optを覗いてやっと納得したのですが、この形の追加はこれからも増えるはずなので、以降は新機能を試す前にexists()で聞くようにしています。逆にいちばん拍子抜けしたのがautocompleteで、:set autocompleteと打った瞬間にポップアップが出たときは、これまで補完のために書いてきた設定は何だったのかという気持ちになりました。
まとめ
Neovim 0.12の追加をプラグインとの対応で並べ直すと、外せるものはvim.packによるプラグイン管理、autocompleteによる入力補完、vim.lsp.enable()による言語サーバの起動、それに:Undotreeと:DiffToolと:Cfilterです。ただし後半の3つはpack/dist/optにあるので、:packaddを通すまで存在しません。実際にexists()で数えると、:packaddの前は0で後は2になります。同じ場所にあるnetrwとmatchitが最初から使えるのは、常に読まれる受付役のスクリプトが別にあるためです。0.11まで既定で読まれていた:TOhtmlが任意読み込みへ移った点だけは、上げた瞬間に手順が止まるので先に確かめておくと安全です。ファジーファインダーとツリー表示のファイラ、Git連携は0.12の標準では代わりが無く、引き続きプラグインが要ります。