Vimのランタイムパスを確認する(runtimepath)
プラグインを手動でディレクトリに配置したのに読み込まれません。原因を探るには、まずVimがどこを見に行っているのか、その検索先一覧を知る必要があります。
目次(8項目)
runtimepathを確認する
:set runtimepath?
:set rtp? " 省略形
設定ファイルやプラグインを読み込む対象ディレクトリの一覧が、指定された並び順で表示されます。この並び順どおりに検索・読み込みが行われるため、同名のファイルが複数の場所にある場合は先に見つかったほうが優先されます。
ただし:set rtp?はカンマ区切りの1行で返ってくるので、項目が増えると画面の右端で折り返して読めなくなります。とくにNeovimの既定はターミナルの1行にまず収まりません。1項目ずつ縦に並べたいときは、カンマで割ってから改行でつなぎ直します。
:echo join(split(&rtp, ","), "\n")
:echo split(&rtp, ",") " リストのまま見る
リストで受け取れると、len(split(&rtp, ","))で項目数を数えたり、index(split(&rtp, ","), $VIMRUNTIME)でVim本体のランタイムが何番目にあるかを調べたりできます。パスを1行ずつ縦に並べておくと、綴りを間違えて足した余計な1行もすぐ目に入ります。
もうひとつ勘違いしやすいのが、各ディレクトリの直下がまるごと読まれるわけではないという点です。探されるのは決まった名前のサブディレクトリだけで、そこに合わない場所へファイルを置くと、runtimepathに入っていても永久に読まれません。
| サブディレクトリ | 読まれるタイミング |
|---|---|
plugin/ | 起動時にすべて |
ftplugin/ | ファイルタイプが決まったとき |
syntax/ | 構文ハイライトが必要になったとき |
indent/ | インデント設定が必要になったとき |
colors/ | :colorschemeを打ったとき |
autoload/ | 中の関数が最初に呼ばれたとき |
doc/ | :helpの検索対象 |
pack/ | 起動時と:packadd |
ディレクトリを追加する
set runtimepath+=~/my-vim-plugin
手動でプラグインを配置した場所や、自作のスクリプトを置いたディレクトリを検索対象に加えたいときは、このように追記します。プラグインマネージャを使っている場合は通常自動的に設定されるため、意識する場面は限られます。
足す位置は2通りあります。+=が末尾、^=が先頭です。set rtp=A,Bの状態から試したところ、set rtp+=ZでA,B,Z、set rtp^=ZでZ,A,Bになりました。
set runtimepath+=~/my-vim-plugin " 末尾に足す
set runtimepath^=~/my-vim-plugin " 先頭に足す
どちらを使うかは、そのファイルが「勝ちたい」のか「負けたい」のかで決まります。colors/のように最初に見つかった1本だけを使う検索では先頭が勝ちます。手元で同名のcolors/dup.vimをAとBに置き、set rtp=./A,./Bとしてから:runtime colors/dup.vimを打つとAの側が読まれ、全部読む:runtime! colors/dup.vimではあとから読まれたBの値が残りました。ftplugin/は後者の全部読む型なので、上書きしたいなら末尾側に置くことになります。
既定値に+=で足した場合、その項目は~/.vim/afterよりさらに後ろに並びます。順番だけ見ると「いちばん最後に読まれる」ように思えますが、起動時のプラグイン読み込みはafterで終わる項目を別扱いにするため、実測では~/.vim/after/plugin/より先に読まれました。
NeovimのLuaからはvim.optのメソッドで足します。vim.opt.rtp:prepend()が^=、vim.opt.rtp:append()が+=に対応し、実際にprependしたパスは先頭、appendしたパスは~/.config/nvim/afterよりさらに後ろに入りました。読むだけなら文字列をそのまま返すvim.o.runtimepathで足ります。
vim.opt.rtp:prepend(vim.fn.stdpath("data") .. "/site/mine") -- 先頭に足す
print(vim.o.runtimepath) -- 文字列で確認
読み込みの確認は:scriptnamesとセットで
runtimepathはあくまで「検索先の候補」であって、実際に読み込まれたかどうかまでは分かりません。設定を追加したのに反映されない場合は、:scriptnamesで実際に読み込まれたファイルの一覧も確認し、両方をあわせて切り分けると確実です。
| コマンド | 確認できること |
|---|---|
:set rtp? | 検索対象ディレクトリの一覧(あくまで候補) |
:scriptnames | 実際に読み込まれたファイルの一覧(結果) |
runtimepathに含まれているのに読み込まれていないなら、ファイル名や配置場所の規約(plugin/ディレクトリ配下かどうかなど)を疑います。
起動時の読み込みは3段階に分かれています(:help load-plugins)。まずafterで終わらない各項目からplugin/**/*.vimが読まれ、次にpackpathのpack/*/start/にあるパッケージがruntimepathへ足されたうえで読まれ、最後にafterで終わる項目のplugin/が読まれます。
この3段階があるせいで、並び順と:scriptnamesの番号は素直に対応しません。手元で~/.vim/pack/mine/start/aaaを作り、vim -u NORCで起動して数えると、そのディレクトリはruntimepathの2番目に入っているのに、読み込みは全18本のうち17番目でした。本数は起動の仕方で変わり、素のvimではsystem vimrcやdefaults.vimが加わって増えます。$VIMRUNTIMEに入っている標準プラグイン15本より後です。
1: ~/.vim/plugin/x.vim
2: /usr/share/vim/vim91/plugin/colorresp.vim
"(中略)標準プラグインが15本
16: /usr/share/vim/vim91/plugin/zipPlugin.vim
17: ~/.vim/pack/mine/start/aaa/plugin/x.vim
18: ~/.vim/after/plugin/x.vim
Neovimなら、書いたパスが実在するかまで機械に確かめさせられます。:lua print(#vim.api.nvim_list_runtime_paths())は実際に存在するディレクトリだけを数える関数で、既定の状態で打つと手元では4を返しました。並んでいる大半は「置いてもよい場所」として用意されているだけで、ディスク上にはまだありません。足したはずのパスでこの数が増えないなら、綴りかチルダの展開を間違えています。
設定ファイル自体の場所も含まれる
runtimepathには、プラグイン用ディレクトリだけでなくvimrc/init.lua本体の置き場所も含まれています。設定ファイルの読み込み優先順位を意識したいときや、複数の設定ファイルを使い分ける環境を作りたいときにも、この一覧が判断材料になります。
Vim 9.1では先頭の項目が「vimrcをどこで見つけたか」で入れ替わります。~/.vimrcがあるときの先頭は~/.vimですが、~/.vimrcも~/.vim/vimrcも無く$XDG_CONFIG_HOME/vim/vimrcだけを置いた環境で起動すると、先頭が$XDG_CONFIG_HOME/vimに変わりました。両方置いた状態では~/.vimrcのほうが勝ちます。
Neovimはこの答えをvim.fn.stdpath()が持っています。stdpath("config")が~/.config/nvimでこれが並びの先頭、stdpath("data")が~/.local/share/nvimで、プラグインが入るのはその下のsiteのほうです。設定と自動で入れたプラグインが別の木に分かれるのがVimとの違いで、Windows版Neovimの設定ファイルの配置場所のように環境ごとの置き場所を追うときも、まずこの2つを見分けることになります。
Windows/Linux/Macでのデフォルトの違い
デフォルトのruntimepathにはOSごとに異なるパスが含まれています。トラブルシューティングで他の人の設定と見比べる際は、OSの違いによるパスの差を前提に読むと混乱が少なくなります。
Vimの既定値は:help 'runtimepath'にOSごとに列挙されています。Unix系が$HOME/.vim、MS-Windowsが$HOME/vimfilesで、先頭のドットの有無が違います。続く$VIM/vimfilesと$VIMRUNTIME、末尾にafterが2つという骨格は共通なので、他人の設定を読むときは最初と最後だけ読み替えれば話が通じます。
macOS 26.4.1のVim 9.1(patch 1-1752)で実際に出た既定値が次の6項目です。$VIMRUNTIMEは/usr/share/vim/vim91で3番目にあります。4番目のnetrwは、標準プラグインのnetrwPlugin.vimが起動時に:packadd netrwを打った結果で、-u NONEで起動すると消えて5項目になりました。
~/.vim
/usr/share/vim/vimfiles
/usr/share/vim/vim91
/usr/share/vim/vim91/pack/dist/opt/netrw
/usr/share/vim/vimfiles/after
~/.vim/after
同じマシンのNVIM v0.12.4は18項目でした。/etc/xdg/nvimやHomebrewが置く/opt/homebrew/etc/xdg/nvimまで並ぶぶん長くなっています。目に付くのは構造の対称性で、後半7項目が前半7項目をそのまま逆順にした鏡写しになっており、~/.config/nvimが先頭、~/.config/nvim/afterが末尾に来ます。$VIMRUNTIMEは8番目です。
~/.config/nvim
/opt/homebrew/etc/xdg/nvim
/etc/xdg/nvim
~/.local/share/nvim/site
/opt/homebrew/share/nvim/site
/usr/local/share/nvim/site
/usr/share/nvim/site
/opt/homebrew/Cellar/neovim/0.12.4/share/nvim/runtime
"(中略)netrw / matchit / lib/nvim の3項目
/usr/share/nvim/site/after
/usr/local/share/nvim/site/after
/opt/homebrew/share/nvim/site/after
~/.local/share/nvim/site/after
/etc/xdg/nvim/after
/opt/homebrew/etc/xdg/nvim/after
~/.config/nvim/after
runtimepathへ足しても、そのディレクトリのplugin/は自動では読まれません。実測でも足した直後は何も起きず、:runtime! plugin/*.vimを打って初めて読み込まれました。試した設定を本番にするときは、Vimを起動し直して確かめます。
自作のスクリプトを~/tools/hello.vimに置いてset rtp+=~/toolsと書き、まったく動かずに30分溶かしたことがあります。:set rtp?には~/toolsがはっきり出ているのに何も起きないので、チルダの展開を疑い、ファイル名を疑い、最後は自分のVimのビルドを疑いました。plugin/という階層をひとつ挟んでいなかっただけだと分かったときは、脱力より先に「これ、何も教えてくれないんだな」という気持ちのほうが強かったです。
packpathとパッケージの関係
Neovimではruntimepathに加えてpackpathというオプションもプラグイン検索に関わります。ネイティブのパッケージ機能(:help packages)はVim 8以降とNeovimの両方にありますが、多くのプラグインマネージャが内部でこの仕組みを使うため、直接意識する場面はそれほど多くありません。
packpathはruntimepathとは別のリストで、pack/以下のパッケージを探す場所だけを持ちます。手元ではVim 9.1が5項目、NVIM v0.12.4が16項目でした。Vim側の既定は、runtimepathからnetrwのpackエントリを抜いたものと一致しています。
置き場所は2つあり、扱いがはっきり違います。pack/<好きな名前>/start/に入れたものは起動時に読まれ、そのディレクトリ自体がruntimepathへ挿し込まれます。pack/<好きな名前>/opt/のほうは:packaddを打つまで何も起きません。
~/.vim/pack/mine/start/aaa/plugin/x.vim " 起動時に読まれる
~/.vim/pack/mine/opt/bbb/plugin/x.vim " :packadd bbb まで読まれない
この配置で:packadd bbbを打つと~/.vim/pack/mine/opt/bbbがruntimepathの2番目、つまり~/.vimの直後に入り、その場でplugin/x.vimが読まれました。起動を重くしたくないものをopt/に置き、必要になった場面だけ足す使い分けができます。
Neovim 0.12が持つ標準プラグイン管理vim.packも、この仕組みの上に乗っています。同梱のランタイムlua/vim/pack.luaを読むと、インストール先はstdpath("data")の下のsite/pack/core/optで、読み込みは:packaddでした。プラグインマネージャが裏で何をしているのか分からなくなったら、packpathの下を素直にlsしてみるのが早道です。
まとめ
runtimepathはVimがファイルを探しに行く場所のリストです。プラグインや設定が読み込まれないトラブルの切り分けでは、まずここを確認するのが基本になります。
この記事の数値はmacOS 26.4.1上のVim 9.1(patch 1-1752)とNVIM v0.12.4で実際に打って確かめたものです。既定値はビルドオプションとパッケージの入れ方で変わるので、項目数や並びは自分の環境で取り直してください。Windows上での動作と、プラグインマネージャを入れた状態での並びは確認していません。
:set と :set all の違いを押さえておけば、runtimepath以外のオプションも同じ手つきで見比べられます。