世界を動かす技術を、日本語で。

Neovim パック

2025年9月4日原文(neovim.io)

概要

Neovimの パッケージ管理プラグイン管理 の仕組みについて解説。 Vimパッケージディレクトリ構造や 自動・手動ロード の違いを整理。 パッケージ作成手順や 依存関係の管理方法 を紹介。 新しい 内蔵プラグインマネージャ(vim.pack) の使い方も説明。 各手順や推奨配置を 箇条書き でまとめて理解しやすく構成。

NeovimでのVimパッケージ拡張

  • Vimパッケージ は複数プラグインをまとめて管理するディレクトリ構成
  • アーカイブ展開Gitリポジトリ として管理・更新が容易
  • 依存関係を持つ複数プラグイン のまとめ管理が可能
  • 自動ロード(start)手動ロード(opt) の2種類の配置
    • start: pack/*/start/* 配下で自動ロード
    • opt: pack/*/opt/* 配下で :packadd で手動ロード
  • runtime-search-path ではstartディレクトリが自動的に検索対象
    • ただし 'runtimepath' には明示的に含まれず ":set rtp" で確認不可
    • nvim_list_runtime_paths()nvim_get_runtime_file()で確認

パッケージの追加・自動ロード手順

  • 例: ~/.local/share/nvim/site/pack/foo/start/foobar/ にプラグイン展開
  • ディレクトリ名(foo)は任意
  • Nvim起動時にpackpath内のstartディレクトリを自動スキャン・ロード
  • foobarプラグインがfiletypeを設定した場合、該当syntaxファイルも自動検索
  • opt配下のプラグインは自動ロードされない(手動で:packaddが必要)
  • プラグインの自動ロード無効時は:packloadallで明示的ロードが可能
  • afterディレクトリが存在する場合、'runtimepath'の末尾に追加され後からロード

単体プラグインの自動ロード

  • パッケージ構造がなくても、pack/foo/start/foobar/を作成し展開で同様に動作

オプションプラグインの手動ロード

  • :packaddコマンドでopt配下のプラグインを手動ロード
    • 例: :packadd foodebug
    • 設定ファイル内で:packadd! foodebugと書くと--noplugin時はロードしない
  • opt配下のみのパッケージも作成可能、必要時のみロード

配置の推奨

  • colorschemeはstart/optどちらでも可、推奨はopt配下
  • filetypeプラグインはstart配下推奨
  • afterディレクトリは通常不要だが利用自体は可能

Vimパッケージの作成

  • 複数プラグインをまとめて配布したい場合にパッケージ作成
  • 構成例:
    • start/foobar/plugin/foo.vim(常時ロードされるコマンド定義)
    • start/foobar/autoload/foo.vim(コマンド利用時に自動ロード)
    • start/foobar/doc/foo.txt, tags(ヘルプファイル)
    • opt/fooextra/plugin/extra.vim(オプションプラグイン)
    • opt/fooextra/autoload/extra.vim, doc/extra.txt, tags
  • 配布方法はアーカイブまたはリポジトリ(GitHub推奨)
  • 利用者はgit clonepackディレクトリに配置
  • オプションプラグインのロード例: :packadd! fooextra
  • ヘルプタグ生成には:helptagsコマンドを利用

プラグイン間の依存関係管理

  • 共通機能はautoloadディレクトリに配置
  • 例:
    • pack/foo/start/one/plugin/one.vim(foolib#getit()呼び出し)
    • pack/foo/start/lib/autoload/foolib.vim(共通関数定義)
  • startパッケージ内でautoloadファイルも自動検索対象

内蔵プラグインマネージャ vim.pack

  • vim.pack はNeovim組み込みのプラグイン管理機能(開発中)
  • $XDG_DATA_HOME/nvim/site/pack/core/opt専用ディレクトリで管理
  • Git必須 (バージョン2.36以上)、プラグインはGitリポジトリで管理
  • プラグイン名=サブディレクトリ名(指定可能)
  • セマンティックバージョニング(v1.2.3など)タグを利用

基本的な使い方

  • init.luavim.pack.add()を記述
    • 例:
      • 'https://github.com/user/plugin1'(デフォルトブランチでインストール)
      • { src = 'https://github.com/user/plugin3', version = vim.version.range('1.0') }(バージョン指定)
      • { src = 'https://github.com/user/generic-name', name = 'plugin2' }(任意の名前指定)
  • Neovim再起動で未インストールプラグインが自動インストール
  • vim.pack.update()で全プラグインを最新化
    • アップデート内容を確認後、:writeで確定、:quitで破棄
  • バージョン変更やフリーズ(更新停止)はinit.luaでversion指定を編集
  • vim.pack.del()でプラグイン削除

イベントフック

  • PackChangedPre(状態変更前)、PackChanged(変更後)のイベント
  • kind(install/update/delete)、spec(仕様)、path(パス)などの情報付与

仕様フィールド

  • src:Git URI
  • name:プラグイン名(デフォルトはリポジトリ名)
  • version:ブランチ・タグ・コミットハッシュまたはvim.version.range出力
  • data:任意データ

補足

  • インストールは並列処理、全完了後に次の処理へ
  • ディスク上の状態が指定バージョンと異なる場合は明示的にアップデートが必要

参考:

  • 詳細は:help packagesや公式ドキュメント参照
  • vim.packは今後仕様変更の可能性あり、利用時は注意

Hackerたちの意見

3年ごとに新しい(Neo)Vimパッケージマネージャに移行しなきゃいけない気がする。これまでの流れは、pathogen -> Vundle -> vim-plug -> lazy.nvimって感じかな。これが最後のVIMパッケージマネージャであってほしいな。

Plugはまだまだ使えると思う。でも、これが言語に組み込まれてるから、たくさんのユーザーにとってはエンドゲームにふさわしいものになるんじゃないかなって期待してる。試してみたけど、特に問題なく使えたよ。lazyが提供するような派手なことはやってないけどね。

lazy.nvimはかなり成功してるみたいだね。でも、他にもいろんなプラグインがサポートされてるし、抽象的には統一感があったらいいなと思う。でも、lazy.nvimのように速くて信頼できるものが手に入るかどうか、ちょっと信じるのが難しいな。まあ、可能性はあるけどね!

新しいパッケージマネージャは今のところかなり遅いよ。lazy vimでnvimを読み込むのに200msかかるのに対して、Packだと1秒かかる感じ。

幸運なことに、これは組み込みの公式なやつだから、最も広くサポートされる可能性が高いね。(でも、機能が豊富とは限らないかも)

俺はほんとにただgitとvimを使ってるだけだよ。

nixvimを使い始めたんだけど、vim-plugあたりで諦めた気がする。複数のマシンやOSで安定して動く設定を維持するのが悪夢だったからね。

2017年にpathogenをやめて、~/.vim/pack/*/start/にgitサブモジュールを使うようにしたけど、今でもそのままだよ。

みんながlazy.vimに移行してる中、私はvim-plugを使い続けてる。週末にlazy.vimに移行しようかなって考えてたけど、このニュースを聞いて、プラグインマネージャーが出るまで待った方が良さそうだな。

自分の(プライベートな)dotfilesのgit履歴を見てみたら、2011年にpathogen、2013年にvundle、2017年にvim-plugを使い始めて、それ以来動かしてない。Plugはまだまだ役に立ってるし、2021年にneovimに移行した後も問題なし。落ち着いたら新しい組み込みパッケージマネージャーに移るかも。

Nixでは、NixOSやMacOS、Linuxのnix管理のhome-managerでも、覚えてる限り同じだよ: neovim = { enable = true; vimAlias = true; vimdiffAlias = true; defaultEditor = true; plugins = [ pkgs.vimPlugins.fugitive pkgs.vimPlugins.fzf-vim pkgs.vimPlugins.vim-gh-line pkgs.vimPlugins.vim-gutentags pkgs.vimPlugins.nvim-lspconfig pkgs.pkgs-unstable.vimPlugins.vim-go pkgs.pkgs-unstable.vimPlugins.zig-vim ]; extraConfig = builtins.readFile ./vimrc; extraLuaConfig = builtins.readFile (pkgs.replaceVars ./dev.lua { inherit (pkgs) ripgrep; }).outPath; }

これがその元の問題だよ: https://github.com/neovim/neovim/issues/20893 どうやら、これはNeovimプロジェクトの長年の目標だったみたいだけど、理由はあまり説明されてないんだよね。既存のプラグインが素晴らしい仕事をしてたところに、無駄が増えたように感じるけど、どうやらそう思わない人もいるみたい。

Hacker Newsで議論の続きを見る