
Neovim 0.12 徹底レビュー - vim.pack と autocomplete で外部プラグインから卒業できるか
はじめに - 0.12は「ビルトイン回帰」のリリース
Neovim0.12.0は、GitHubReleases上では2026年3月29日17:16:57UTCに公開されています。日本時間では2026年3月30日2:16:57です。
公式ロードマップでは0.12の見出しをThe year of Nvim OOTBと置き、vim.pack、進捗メッセージ、LSPの追加能力、デフォルトステータスライン、プロンプトバッファ強化などを並べています。ここでいうOOTBは、追加プラグインを入れる前のNeovim本体だけで使える範囲を広げる方向性です。
この記事では、0.12を「外部プラグイン不要になった」と雑にまとめるのではなく、どこまで本体機能で置き換えられるのかを見ます。特に焦点は次の2つです。
vim.packでプラグイン管理をどこまで本体に寄せられるかvim.lsp.completion.enable()、'autocomplete'、inline completionで補完プラグインをどこまで減らせるか
結論を先に言うと、プレーンなNeovim構成なら0.12はかなり魅力的です。一方、LazyVimやlazy.nvimで育った構成をそのまま置き換えるには、まだ割り切りが必要です。
主要変更点サマリ
| 領域 | 0.12の変更 | 実用度 | 置き換え候補 |
|---|---|---|---|
| プラグイン管理 | vim.packを追加 | 小規模構成なら実用的 | 一部のpacker.nvim用途 |
| 補完 | 'autocomplete'とLSP補完を強化 | LSP中心なら実用的 | 軽いnvim-cmp構成 |
| inline completion | LSPtextDocument/inlineCompletionに対応 | サーバー依存 | Copilot系の一部操作 |
| LSP診断 | workspace diagnosticsやpull diagnosticsを拡張 | 大規模リポジトリで有用 | 診断表示の自作部分 |
| document colors | 色参照のハイライトを標準提供 | CSS/設定ファイルで有用 | 色表示系の軽量プラグイン |
| code lens | 再実装され、virtual lines表示に変更 | 対応サーバーなら有用 | 個別codelens設定 |
| 起動/実行性能 | vim.glob.to_lpeg()、i_CTRL-R、:packadd周りを改善 | 条件が合うと効く | 一部の最適化プラグイン |
| ステータスライン | 診断と進捗をデフォルト表示 | 最小構成なら十分 | 簡易statusline設定 |
vim.pack詳説
vim.packは、Neovim本体に入ったプラグインマネージャーです。公式ヘルプでは「外部プラグインのインストール、更新、削除」を行う機能と説明されています。ただし、同じヘルプ内でexperimentalとも明記されています。日常利用に耐える安定性を目指しているものの、lazy.nvimのような成熟した周辺機能をすべて持つわけではありません。
管理対象ディレクトリはstdpath('data')配下のsite/pack/core/optです。Gitを使ってプラグインを取得し、状態は$XDG_CONFIG_HOME/nvim/nvim-pack-lock.jsonに保存されます。公式ヘルプでは、このロックファイルを設定の一部としてバージョン管理する考え方も示されています。
最小設定例
init.luaに直接書くなら、まずはこのくらいから始められます。
vim.pack.add({
{ src = 'https://github.com/nvim-lua/plenary.nvim' },
{
src = 'https://github.com/echasnovski/mini.nvim',
name = 'mini.nvim',
version = 'main',
},
})
require('mini.files').setup()srcにはgit cloneで扱えるURIを指定します。nameを省略するとリポジトリ名がディレクトリ名になります。versionは未指定ならリポジトリのデフォルトブランチ、文字列ならブランチ/タグ/コミット、vim.version.range()ならsemverタグの範囲指定として扱われます。
更新はLua関数としてはvim.pack.update()で実行できます。更新前に確認バッファを出す挙動も用意されています。対話なしに進めたい場合はforceオプションを使う設計です。
lazy.nvim/packer.nvimとの機能比較
| 観点 | vim.pack | lazy.nvim | packer.nvim |
|---|---|---|---|
| 本体同梱 | はい | いいえ | いいえ |
| 設定方式 | vim.pack.add() | プラグイン仕様テーブル | useベースの仕様 |
| ロックファイル | nvim-pack-lock.json | lazy-lock.json | snapshot機能 |
| Git取得 | 対応 | partial clone対応 | 対応 |
| 遅延読み込み | 手動設計が中心 | イベント/コマンド/ft/キーで自動化 | イベント/コマンド/ftなど |
| UI | 更新確認バッファ中心 | 管理UI、更新確認、プロファイル | フローティングUIあり |
| 依存解決 | 明示順序の設計が必要 | 依存順序制御あり | 依存指定あり |
| プロファイル | 本体機能としては限定的 | あり | あり |
| 向いている構成 | 少数プラグイン、標準寄せ | 本格構成、LazyVim | 既存packer構成の維持 |
lazy.nvimのREADMEは、強力なUI、Luaモジュールの自動キャッシュ、イベント/コマンド/ファイルタイプ/キーマップでの遅延読み込み、依存順序、プロファイリング、ロックファイルを機能として挙げています。packer.nvimも、宣言的な仕様、依存関係、lazy-loading、コンパイル済みローダー、snapshotなどを持っています。
そのため、vim.packは「本体に入った最小中核」と見るのが自然です。lazy.nvimを丸ごと置き換えるというより、まずは小さな設定、検証用環境、最小構成のdotfilesで効いてきます。
LazyVimユーザーが乗り換える価値はあるか
LazyVimユーザーが、既存構成のプラグイン管理をvim.packへ全面移行する価値は、2026年5月時点では低めです。
理由は単純で、LazyVim自体がlazy.nvim上に構成されています。LazyVimのREADMEも、NeovimをIDEに近い状態へ変えること、lazy.nvimで簡単にカスタマイズできること、多数のプラグインが事前設定済みであることを特徴にしています。ここをvim.packへ差し替えると、LazyVimの前提から外れます。
ただし、次のような用途なら試す価値があります。
- LazyVimとは別に、素のNeovim検証用プロファイルを作る
- サーバー上で数個のプラグインだけを使う軽量設定を作る
- 自分のdotfilesから外部プラグインマネージャー依存を減らす
- プラグイン開発時に、本体機能だけで再現環境を作る
LazyVim本体を使い続けるなら、vim.packは今すぐの乗り換え先というより、Neovim本体の方向性を知るための観察対象です。
vim.packで詰まる典型ケース
vim.packはシンプルですが、シンプルさゆえに詰まりどころもあります。
| ケース | 原因 | 見直す場所 |
|---|---|---|
| インストールされない | Git実行ファイルが見つからない | git --version、PATH |
| 管理ディレクトリが見つからない | --cleanやXDG_DATA_HOME変更でpackpathが想定外 | :set packpath? |
| semver範囲指定が効かない | 対象リポジトリにv1.2.3形式のタグがない | タグ一覧、version指定 |
| 既存プラグインが古いまま | add()だけでは既存revisionの同期確認をしない | vim.pack.update() |
| 遅延読み込みが足りない | lazy.nvimのイベント指定に相当する高機能DSLはない | autocmdや手動packadd |
| 依存関係で壊れる | 依存順や読み込みタイミングを自分で設計する必要がある | add()の順序、require()位置 |
| ロックファイルを直したくなる | 公式ヘルプでは手編集しない前提 | 削除後の再生成、バージョン管理 |
特に、lazy.nvimのevent、cmd、ft、keysに慣れていると、vim.packはかなり素朴に感じます。そこを「不便」と見るか「標準APIとして十分」と見るかで評価が分かれます。
ネイティブautocomplete
0.12の補完は、nvim-cmpやblink.cmpを一気に不要にするというより、Neovim本体の補完レイヤーが実用域に近づいたリリースです。
vim.lsp.completion.enable()と'autocomplete'オプション
まず分けて考えたいのは、vim.lsp.completion.enable()と'autocomplete'は同じものではないという点です。
vim.lsp.completion.enable()は、指定したLSPクライアントとバッファに対して、LSP由来の補完候補をNeovimの組み込み補完へ流すためのAPIです。公式ヘルプでは、autotrigger=trueにするとサーバー定義のtriggerCharactersに基づいて自動補完が起動すると説明されています。すべてのキー入力で起動したい場合は、triggerCharactersを拡張するか、InsertCharPreからvim.lsp.completion.get()を呼ぶ案が示されています。
一方、'autocomplete'はエディタのオプションです。オンにすると、i_CTRL-Nに近い補完メニューが入力中に自動表示されます。遅延は'autocompletedelay'、タイムアウトは'autocompletetimeout'で調整できます。公式ヘルプ上のデフォルトは'autocomplete'がoff、'autocompletedelay'が0、'autocompletetimeout'が80です。
LSP中心の最小設定なら、まずは次の形で十分です。
vim.opt.completeopt:append({ 'menuone', 'noselect', 'popup' })
vim.api.nvim_create_autocmd('LspAttach', {
callback = function(ev)
local client = vim.lsp.get_client_by_id(ev.data.client_id)
if client and client:supports_method('textDocument/completion') then
vim.lsp.completion.enable(true, client.id, ev.buf, {
autotrigger = true,
})
end
end,
})この設定で、LSPサーバーが補完をサポートしていれば、組み込み補完の候補として扱えます。候補の確定はCTRL-Yです。nvim-cmpに慣れている場合、Enter確定やTab選択は自分でキーマップを考える必要があります。
inline completionの挙動
0.12ではLSPのtextDocument/inlineCompletionがサポートされています。公式ヘルプでは、通常の補完が単語や行の候補をメニューに出すのに対し、inline completionは複数行のテキスト、たとえばメソッド全体の候補をoverlay textとして表示する機能と説明されています。
有効化と受け入れは通常の補完とは別です。
vim.lsp.inline_completion.enable(true)
vim.keymap.set('i', '<Tab>', function()
if vim.lsp.inline_completion.get() then
return ''
end
return '<Tab>'
end, { expr = true, desc = 'Accept inline completion or fallback' })ここで重要なのは、inline completionはNeovimだけで完結しないことです。対応するLSPサーバーが必要です。公式ヘルプのquickstartではCopilot Language Serverの例が示されています。したがって「0.12にしたらAI補完が勝手に出る」ではありません。
nvim-cmp/blink.cmpユーザーの移行可否
LSP候補だけでよく、補完UIに強いこだわりがないなら、本体補完への移行は現実的です。特に小さなLua設定、サーバー上の編集、プラグインを極力減らしたい環境では試しやすいです。
一方、次の用途があるならnvim-cmpやblink.cmpを残す方が無難です。
- LSP、バッファ、パス、スニペット、絵文字ではなく記号候補など、複数sourceを細かく統合したい
- Enter、Tab、Shift-Tab、snippet jumpをひとまとめに制御したい
- 候補の並び順、フィルタリング、表示幅、ドキュメント表示を細かく作り込みたい
- LazyVimの既存補完UXを崩したくない
0.12のネイティブ補完は「軽い構成なら卒業できる」段階です。補完体験そのものをエディタの中心に置いている人には、まだ外部プラグインの価値が残ります。
LSP拡張の実用度
0.12のLSPは、目立つUI変更よりもプロトコル対応と標準挙動の底上げが効いています。
| 機能 | 公式で確認できる内容 | 実用上の見方 |
|---|---|---|
| workspace diagnostics | vim.lsp.buf.workspace_diagnostics()を追加 | プロジェクト全体診断をサーバーへ要求できる |
| document colors | document color highlightingはデフォルト有効 | CSS、Tailwind設定、テーマ設定で便利 |
| color presentation | vim.lsp.document_color.color_presentation()を提供 | 色表現の変換UIを作りやすい |
| code lens | textDocument/codeLensが再実装され、code lensesはvirtual lines表示 | テスト実行や参照数表示が見やすくなる可能性 |
| codeLens refresh | workspace/codeLens/refreshに対応 | サーバー側から再取得を促せる |
| diagnostic refresh | workspace/diagnostic/refreshに対応 | pull diagnostics系の更新と相性が良い |
| dynamic registration | textDocument/diagnosticのdynamic registration対応 | LspAttach後に能力が増えるケースを扱いやすい |
:checkhealth vim.lsp | 有効なLSP機能がどのバッファへ付いているか確認可能 | 移行時の最初の確認先になる |
個人的に効くと思うのは、workspace diagnosticsと:checkhealth vim.lspです。LSPが動いているかどうかは、以前からLspInfoやプラグイン側のUIで見ることが多かったところです。0.12では本体側の健康診断で、どの機能がどのバッファへ付いているかを追いやすくなっています。
dynamic registrationについては、自前のon_attachで「サーバーがこのメソッドを持っていたらキーマップを生やす」という実装をしている人ほど注意が必要です。公式ヘルプは、サーバーがdynamic registrationを行う場合、能力はLspAttach後に登録されることがあるため、client/registerCapabilityイベントを扱う選択肢を示しています。
パフォーマンス - LuaJIT2.1で15〜20%高速化をどう見るか
0.12.0のGitHubReleases本文では、ビルド情報としてLuaJIT 2.1.1774638290が示されています。
ただし、今回確認したNeovim公式リリース本文、0.12のnews.txt、ロードマップの範囲では、「LuaJIT2.1によりNeovim全体が15〜20%高速化した」という直接の記述は確認できませんでした。そのため、この記事ではその数値をNeovim公式の性能保証としては扱いません。
公式の0.12news.txtで確認できるパフォーマンス項目は、より具体的です。
vim.glob.to_lpeg()がLPegベース実装になり、複雑なpatternで約50%高速化i_CTRL-Rで名前付き/クリップボードレジスタをliteralに挿入し、10倍高速化- LSP
textDocument/semanticTokens/rangeで表示範囲だけのsemantic tokensを要求 :packaddがLua package pathキャッシュを無効化せず、インプレース更新するようになった
つまり、0.12の高速化は「LuaJIT2.1だから一律に速い」と見るより、特定の処理パスで改善が入ったと見る方が安全です。起動が重い設定では:packaddとvim.pack.add()の置き方、巨大ファイルではsemantic tokensやTreesitter、日常操作では補完やレジスタ貼り付けの挙動が体感に出やすいはずです。
既存設定の移行手順
いきなり既存のlazy.nvimやnvim-cmpを消すのではなく、切り分けながら進めるのがおすすめです。
1. Neovim0.12の状態を確認する
まずはバージョンとLSP状態を確認します。
:version
:checkhealth
:checkhealth vim.lsp:checkhealth vim.lspでは、LSPがどのバッファにattachしているか、どの機能が有効かを見ます。0.12ではこの確認が移行時の基準になります。
2. プラグイン管理だけを別プロファイルで試す
本命の~/.config/nvimを触る前に、別のNVIM_APPNAMEで検証すると戻しやすいです。
NVIM_APPNAME=nvim-012-pack nvimこの別プロファイルでvim.pack.add()を試し、プラグイン数が少ない構成なら運用できるか見ます。LazyVim本体を使っている場合、ここで本体設定とは分けて検証するのが安全です。
3. 補完はLSPだけで成立するかを見る
nvim-cmpやblink.cmpを外す前に、次を確認します。
- LSPサーバーが
textDocument/completionを返すか vim.lsp.completion.enable()で候補が出るかcompleteopt、CTRL-Y、Tab/Enterの操作が自分に合うか- snippet展開やパス補完を本当に使っているか
snippetやパス補完を多用しているなら、補完プラグインを残す判断で問題ありません。本体補完へ寄せる価値は、外部依存を減らしたいときに大きくなります。
4. mason/null-ls周辺を互換確認する
mason.nvimはLSPサーバーや周辺ツールのインストール管理、null-ls系は外部formatter/linterをLSP風に扱うための層です。vim.packはプラグイン取得を担当するだけなので、この2つの役割を直接置き換えるものではありません。
移行時は次の順で見ます。
| 確認対象 | 見るべき点 |
|---|---|
| mason | サーバー実体のパス、インストール済みserver、既存lspconfig設定 |
| LSP設定 | vim.lsp.config()または既存nvim-lspconfig経由の起動状況 |
| null-ls系 | formatter/linterの実行ファイル、対象filetype、保存時formatのautocmd |
| 診断 | vim.diagnostic.open_float()、location list、quickfixへの出方 |
| health | :checkhealth vim.lspと:checkhealthの警告 |
外部ツールを呼ぶ部分は、0.12本体だけで急に解決する領域ではありません。プラグイン管理と補完UIを軽くしても、formatter、linter、language serverの実体管理は別途残ります。
5. 削る順番を決める
移行の順番は、リスクが小さいところから進めます。
- 新規プロファイルで
vim.packを試す - LSP補完を別キーマップで試す
nvim-cmpまたはblink.cmpのsource利用状況を洗い出す- snippetやpath補完が不要なfiletypeから本体補完へ寄せる
- 最後に本命プロファイルへ反映する
特にLazyVimでは、補完、snippet、UI、diagnostics、formattingが複数プラグインで連動しています。1つだけ抜くと、想定外にキーマップや表示が崩れることがあります。
結論 - LazyVim/プレーンnvim/Vim移行検討中の3視点で評価
LazyVimユーザー
LazyVimユーザーは、0.12の新機能を「今すぐ全面移行」ではなく「本体側の進化として観察」するのがよさそうです。
vim.packは面白いですが、LazyVimの前提であるlazy.nvimのUI、遅延読み込み、依存解決、ロックファイル、既存のplugin specを捨ててまで移る理由はまだ強くありません。補完も、LazyVimのblink.cmpまたはnvim-cmp構成を使っているなら、snippetやsource統合まで含めてそのまま使う方が安定します。
ただし、NVIM_APPNAMEを分けて「素のNeovim0.12構成」を作る価値はあります。Neovim本体の未来を知るには、LazyVimの外に1つ小さな環境を持つのが一番分かりやすいです。
プレーンnvimユーザー
プレーンなNeovim設定を育てている人には、0.12はかなり刺さります。
プラグインが10個前後で、遅延読み込みも複雑ではなく、LSP補完中心なら、vim.packとネイティブ補完へ寄せる現実味があります。特に、設定ファイルを長期運用するなら「本体APIで済むものは本体へ寄せる」という設計は強いです。
ただし、依存関係が多い構成、プラグインの更新差分をUIで細かく見たい構成、プロファイルを見ながら起動速度を詰めたい構成では、lazy.nvimの方がまだ楽です。
Vim移行検討中の人
VimからNeovimへ移る理由として、0.12は分かりやすい節目になりました。
Lua設定、LSP、補完、inline completion、vim.pack、デフォルトステータスラインまで、本体側の機能だけで「まず使える」範囲が広がっています。最初から巨大なディストリビューションへ入るのが不安なら、0.12の標準機能を軸に小さく始める選択肢があります。
一方で、IDE的な体験をすぐ欲しいならLazyVimのような構成は今でも強いです。0.12は「外部プラグインから卒業するリリース」というより、「卒業できる領域を本体が少しずつ広げたリリース」と捉えるのが近いです。