Neovim 0.11アップデートの個人的に嬉しいことまとめ

Neovim 0.11がリリースされました。この記事ではその概要やアップデート手順、個人的なうれしいポイントを紹介します。「LSPの設定はビルトインだけに移行するべきか?」についても触れています。

アップデート手順

書くまでもないですが一応。

  • 一次情報に目を通す(次の項目でリンクをまとめました
  • 各パッケージマネージャーでアップデート
  • プラグインのアップデート

Neovim 0.11の概要

公式関係のリンクをまとめておきます。

Breaking Changesはどうよ?

一般ユーザー目線だと破壊的変更はほとんどありません。プラグイン開発者はご自身の目で確かめましょう(特にLSPやTreesitter系)。

Diagnosticのvirtual_text

1点だけ。Diagnosticのvirtual_textはデフォルトだと無効になったようです。

有効にする場合はvirtual_text = trueにしておきます。

vim.diagnostic.config({ virtual_text = true })

diagnosticはvirtual_linesjumpの設定も追加されています。

conceal_lines(プラグイン開発者向け)

vim.api.nvim_buf_set_extmarkやTreesitterのconceal_linesで「行全体を隠す」ようになりました。

0.10だとscmでset! conceal_lines ""のように書いても「行の文字が見えなくなるだけ」だったのでうれしいですね。

この変更は「BREAKING CHANGES」ではなく「NEW FEATURES」に書いてありますが、個人的にはうれしいBreakingです。

新機能

LSP周りが充実しました。

デフォルトキーマップの追加

デフォルトのキーマップが増えました。一部を紹介します。

まずはLSP関係。

モードキー内容
Normalgrnvim.lsp.buf.rename()
Normalgrrvim.lsp.buf.references()
Normalgrivim.lsp.buf.implementation()
NormalgO(オー)vim.lsp.buf.document_symbol()
Normalgravim.lsp.buf.code_action()
Insert<C-s>vim.lsp.buf.signature_help()

筆者はほとんどプラグイン経由でこれらの関数を呼んでいるのですが、キーマップはこのデフォルトのやつに合わせてみました。

あと面白そうなやつ。

モードキー内容
Normal[<Space>上に空行を追加
Normal]<Space>下に空行を追加

[<Space>]<Space>Ooと違ってノーマルモードのままかつカーソル位置は動きません

Lua関係

vim.fs.〇〇でのファイルやパス関連の操作、vim.text.indent()でインデントやdedent(インデントを削除するやつ)が追加されました。

また、gf同じリポジトリ内のモジュールにジャンプできるようになりました。
require("plugins.foo")みたいにdotfilesでファイル分割している人やプラグイン開発者にはうれしい機能です。

オプション関係

今までプラグイン毎にfloating windowのボーダーを設定しましたが、winborderオプションだけで設定できるようになりました。
ただプラグインによってはデフォルト設定してなくて残念な見た目になってしまうため、設定の際は要注意です。

Language Serverの設定APIが追加

今までLanguage Serverの設定周りはプラグインnvim-lspconfigを使っていました。0.11からはビルトインで設定できます。
もちろんnvim-lspconfigのままでも問題ありません。

vim.lsp.configの書き方

vim.lsp.config.<LSP名>にテーブルを書き、vim.lsp.enableで有効化します。

---@type vim.lsp.Config
vim.lsp.config.clangd = {
cmd = {
'clangd',
'--clang-tidy',
'--background-index',
'--offset-encoding=utf-8',
},
root_markers = { '.clangd', 'compile_commands.json' },
filetypes = { 'c', 'cpp' },
}
vim.lsp.enable({ 'clangd' }) -- これで有効化される

型はvim.lsp.Configです。

root_markersはルートとして扱いたいディレクトリにあるファイルを書きます。
TypeScriptだとpackage.jsonとか。

ファイルを分けたい場合

ファイルをLanguage Serverごとに分けたい場合、ランタイムパスのlsp/に置きます。
たとえばclangdなら.config/nvim/lsp/clangd.luaとか。

vim.lsp.config.<LSP名>に渡すテーブルを返すようにします。

.config/nvim/lsp/clangd.lua
---@type vim.lsp.Config
return {
cmd = {
'clangd',
'--clang-tidy',
'--background-index',
'--offset-encoding=utf-8',
},
root_markers = { '.clangd', 'compile_commands.json' },
filetypes = { 'c', 'cpp' },
}
共通の設定

共通の設定をする場合はvim.lsp.config("*", {foo=1})のように書きます。

次のコードはNeovimのヘルプvim.lsp.config()からの引用です。

vim.lsp.config('*', {
capabilities = {
textDocument = {
semanticTokens = {
multilineTokenSupport = true,
}
}
},
root_markers = { '.git' },
})

共通設定はいい感じに個別の設定とマージしてくれます。
詳しい例はCONFIG - Neovim docsを読んでください。

nvim-lspconfigからビルトインへ移行するべきか?

ビルトインだとcmd・ルートマーカーなどを全部自分で書く必要があります。とはいえ、各Language ServerのREADMEやプラグインnvim-lspconfigの実装を見ればすぐに設定できます。

ビルトインであれば、補完プラグインblink.cmpでわざわざcapabilitiesを自分で設定する必要もなくなります。

ただ、nvim-lspconfigだと:LspRestartのような便利なコマンドがあります。

というわけで筆者はまだしばらくnvim-lspconfigを使い続ける予定です。暇なときにLspRestartなどのコマンドをvim.lsp.config向けに実装できたら移行します。


以上、Neovim 0.11のアップデート備忘録でした。