この記事は Vim 駅伝の 2025/5/16 の記事です。前回は kawarimidoll さんによる「mini.nvimの新モジュールmini.keymapで決めろマルチステップコンボ」でした。
作ったもの
まずはこの動画を貼っておきます。表題を見て機能が想像できた人はこれ見りゃ十分でしょう。今すぐレポジトリーのページへ飛んでください。
Runtime ファイルを開いているならそれを開きますし、それ以外のファイルなら設定している関数にフォールバックします。デフォルト値は Snacks.gitbrowse() です。
Neovim の Runtime ファイルを読む
分かる人にはこれだけで十分なのですが、なぜこんなものが必要なのか、以下で説明しています。
Neovim には多くの機能がありますが、最近の機能は C では無く Lua で書かれることも多くなっています。Neovim ユーザーは設定のために Lua を必ず読めますから、機能の詳細を確認したいと思ったらまずソースを読むはずです(よね?)。
このようなソースは「Runtime ファイル」と呼ばれ、インストールされている場所は $VIMRUNTIME
という環境変数にセットされています。Neovim の中なら :echo $VIMRUNTIME
で見れますし、シェルから確認するならこのようになります。
~ ❯❯❯ nvim --clean --headless +'echo $VIMRUNTIME' +q
/opt/homebrew/Cellar/neovim/HEAD-40b64e9/share/nvim/runtime
あるいは、nvim -V1 --version
でも表示されます。
~ ❯❯❯ nvim -V1 --version
NVIM v0.12.0-dev-5607+g40b64e9100-Homebrew
Build type: Release
LuaJIT 2.1.1744318430
system vimrc file: "$VIM/sysinit.vim"
fall-back for $VIM: "/opt/homebrew/Cellar/neovim/HEAD-40b64e9/share/nvim"
Run :checkhealth for more info
実際にこの配下のファイルを表示するとなると $VIMRUNTIME
の値がシェルでも欲しくなります。ですが、これを手に入れるのには上記のような操作を行わないと難しいです。もし単にその配下のファイルを開きたいだけなら、+{command}
を使うといいでしょう。
# LSP 機能のソースを開く
nvim +'e $VIMRUNTIME/lua/vim/lsp.lua'
あるいは、nvim-telescope/telescope.nvim などのファジーファインダーを使う手もありますね。例えば :Telescope find_files cwd=$VIMRUNTIME
すると以下のように表示されます。
読んでいる所を GitHub で開きたい
一人で読むだけならこれでいいのです。しかし、例えば勉強会などで「この部分のソースが~」と説明しながら参加者に披露しようとすると困ってしまいます。「$VIMRUNTIME/lua/vim/lsp.lua
の 543 行目を見てください」と口頭で案内するのは無理がありますし、そもそも使っている Neovim のバージョンによってファイル名や行数が変わってしまいます。
ここで GitHub を使います。例えば、↓以下のような URL を使うと、「特定のコミット、特定のパス、特定の行」を指定してソースを開くことができます。
https://github.com/neovim/neovim/blob/40b64e91007e364fd7c7eaab64ce7c8cf0150aec/runtime/lua/vim/lsp.lua#L543-L543
このようなリンクを作成するために、Snacks.gitbrowse() のようなプラグインを使うことができます。これを使うと、特定のキーを押すだけで上記のようなリンクがブラウザで開きます。はい。これでオシマイ!
……なんですが、これが使えるのは「Git レポジトリーの中のファイルのみ」なんです。Neovim の Runtime ファイルを開こうとしたら簡単な方法が無いんですね1。
で、プラグインを作りました
そこで作りましたのが、再掲になりますが↓これです。
以下のようなフローで動作します。
-
:lua require("rtbrowse").browse()
する。 - 現在開いているのが Runtime ファイルでなければ、
fallback
オプションの関数(デフォルトでは Snacks.gitbrowse())で開いて完了。 - Neovim のバージョン、あるいはコンパイルしたコミットを調べる。
- ビジュアルモードで選択中ならその行を、そうでなければ現在行をブラウザで開く。
キーマップを自前でやりたい人は、
-- 以下、lazy.nvim を使っているものとして書きます。
{ "delphinus/rtbrowse.nvim" }
だけでいいですし、lazy.nvim で一緒に設定するなら
{
"delphinus/rtbrowse.nvim",
keys = {
{
"<Leader>gB",
function require("rtbrowse.nvim").browse() end,
mode = { "n", "x", "o" },
},
},
}
で良いでしょう2。これ以上書くことは特に無い(後は :h rtbrowse.txt
してください)のですが、一点実装に苦労した部分があったので載せておきます。
現在使っている Neovim のリビジョンを知る
実装するに当たり、結構困ったのがこれです。いや、リリース版をインストールしているなら簡単なんですよね。
vim.version()
を見る
lua print(vim.version())
" 0.11.1 などと表示される
これで終わりなんですが、Neovim を自前でコンパイルすると表示がこのように変わります。
lua print(vim.version())
" 0.12.0-dev+Homebrew
これは Homebrew でインストールした場合ですが、手ずから make した場合も同様でしょう。このようなバージョン文字列では GitHub の狙ったコミットを表示させることができません。
:version
を見る
:version
を使うのはどうでしょう。
NVIM v0.12.0-dev-5607+g40b64e9100-Homebrew
Build type: Release
LuaJIT 2.1.1744318430
Run ":verbose version" for more info
g40b64e9100
という所にコミットハッシュのようなものがありますね。これを使えば良さそうなのですが、明らかに桁数が足りません。もうひと手間必要です。
完全なコミットハッシュを知る
このためにも、再び GitHub の機能を使います。この用途には GitHub API の “Get a commit” を使います。
~ ❯❯❯ curl -H 'Accept: application/vnd.github.sha' https://api.github.com/repos/neovim/neovim/commits/40b64e9100
40b64e91007e364fd7c7eaab64ce7c8cf0150aec
このように、https://api.github.com/repos/neovim/neovim/commits/
の後に短いハッシュを付けると、完全な形のハッシュを返してくれるようです。これを使って GitHub の URL を作ることができます。
なお、今回の実装では GitHub API のアクセストークンを指定していません。そのため、Rate Limit に達してしまい curl
コマンドが失敗してしまう人も居ると思います。その場合は gh
コマンド を利用するオプションも提供していますのでそちらを使ってください(:h rtbrowse-configuration-get_commit
)。
まとめ
Neovim の Runtime ファイルを開いた状態から、そのファイルを GitHub で開くプラグインを作った話を書きました。勉強会なんかでやるソースリーディングのお供に是非お使いください。
-
実際にやるとしたら、neovim/neovim レポジトリーをローカルにクローンし、開きたいコミットをチェックアウトし、該当のファイルを開いて
Snacks.gitbrowse()
を呼ぶ、という手順になります。 ↩ -
この場合は
keys
オプションによりプラグイン自体が遅延読み込みされますからオススメです。また、このプラグインを設定する際にopts = {}
は不要です。 ↩