Vimアドベントカレンダー12/9の記事です。
昨日の記事は以下の2本でした。
- NI57721さんによる「長文丸暗記用のVimプラグインを作った話」
- yasunori0418さんによる「ヘルプから始めるddu」
gfはいいぞ
gf
コマンド、便利ですよね。
ファイル名前の上でgf
と入力すると、そのファイルをバッファに開いてくれます。
この上位互換にgF
もあり、file.txt:30
みたくファイル名に行番号が付いている場合に該当業を開いてくれます。
なので、以下のようにgf
をgF
にしてしまうのは定番といえます。
nnoremap gf gF
いきなり脱線しましたが、:help gf
を見ると、netrwプラグインを入れてればURIも開けるよとのこと。何それ便利。
If the name is a hypertext link, that looks like “type://machine/path”, you need the |netrw| plugin.
netrwはいらないけど、URLくらいは開きたいので、実装してみました。
マッピングを使う
たぶん、王道です。
カーソル下のURLを見つけて、任意のプログラムで開きます。
これまた :help gf
を読んで気付いたのですが、<cfile>
という文字列は、カーソル下にあるファイル名に相当するそうです。
従ってexpand('<cfile>')
すると、実際のファイル名(URL)に展開されます。
あとは'<cfile>'
がURLかどうか判定して動作を切り替えればOK。
-- Lua (Neovim向け)
vim.keymap.set("n", "gf", function()
local cfile = vim.fn.expand("<cfile>")
if cfile:match("^https?://") then
-- Neovim <= 0.9.x なら vim.fn.system("xdg-open " .. cfile)
vim.ui.open(cfile)
else
vim.cmd("normal! gF")
end
end)
" Vim script (ChatGPTに翻訳させたものを手直し)
function! OpenFileOrURL()
let cfile = expand("<cfile>")
if match(cfile, '^https\?://') >= 0
call system('xdg-open ' . cfile)
else
normal! gF
endif
endfunction
nnoremap <silent> gf :call OpenFileOrURL()<CR>
自動コマンドを使う
あるいはこんなものも面白いかもしれません。
特に設定してない状態でURLにカーソルを合わせえてgf
すると、URLをファイル名とした空のバッファが開きます。
これを逆手にとって、BufReadCmd
イベントで発火する自動コマンドを登録します。
バッファの開閉という副作用がデメリットですが、:e https://example.com
などでブラウザが開くようになるのは便利かも?
やることとしては以下の通り。
Luaスクリプトを用意してますが、Vim scriptが必要な人はChatGPTなりなんなりに問い合わせてください。
- ファイル名前が
https://
またはhttp://
で始まることを条件とする - 任意のコマンド(ブラウザ)でファイルを開く
- 空のバッファがゴミになるので、直前のバッファを開きなおし(
e #
)、ゴミバッファを消す- 直前のバッファを開きなおして、ゴミバッファを非表示にしておくのがポイントで、これにより、バッファを消したせいでウィンドウが閉じるのをふせげます。
vim.api.nvim_create_autocmd("BufReadCmd", {
desc = "Open browser with gf",
pattern = { "https://*", "http://*" },
group = vim.api.nvim_create_augroup("open-browser"),
callback = function(ctx)
if vim.ui.open then
-- Neovim nightlyを使っている場合
vim.ui.open(ctx.match)
else
vim.fn.system({"xdg-open", cfile})
end
vim.cmd([[e # | bdelete #]])
end,
})
ENJOY!
<cfile>
を知らず、最初に思いついたのが自動コマンドでした。ヘルプ読むのって面白いですね!