Vim で Web ページを :source する

この記事は Vim Advent Calendar 2012 213日目の記事になります。
最近、3日に1回 Vim Advent の記事を書いているような気がする。


参加者はまだまだ募集中です。
2回目の記事を書きたい人も募集しているので書きたい人はこのブログのコメントか @osyo_memo まで連絡下さい。


さて、今回は gist などに書かれている内容を Vim で直接 :source するようなスクリプトを書いてみたいと思います。

[注意]

最初に書いておくと今回書いたコードと同等の機能が既に netrw で実装されていたりします(ただし、手元の環境だとなぜか動作しませんでしたが…。
気になる方はそっちも調べてみるといいと思います。

[ページの内容を取得する]

とりあえず、今回は curl を使ってページの内容を取得します。
他には webapi.vim 等を使ってもいいと思います。

$ curl https://gist.github.com/osyo-manga/5805362/raw/da3c5b5882e8469bd8c4e1c46ba2afbdbff29059/test.vim
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   106    0   106    0     0     69      0 --:--:--  0:00:01 --:--:--    95
echom "hello, world"

function! s:func(a, b)
    return a:a + a:b
endfunction
echom "3 + 2 = " . s:func(3, 2)


また、今回はページの内容をそのまま :source するので対象となるページはプレーンなテキスト形式である必要があります。(git や gist だと raw とか)。

[Vim で :source する]

curl でページの内容を temp ファイルに書きだして、それを :source します。

function! s:source_web_file(url)
    let temp = tempname()
    call system(printf("curl %s -o %s", a:url, temp))
    source `=temp`
    call delete(temp)
endfunction

command! -nargs=* WebSource call s:source_web_file(<q-args>)


:WebSource https://gist.github.com/osyo-manga/5805362/raw/da3c5b5882e8469bd8c4e1c46ba2afbdbff29059/test.vim
" => hello, world
" 3 + 2 = 5


これで URL からページの内容を読み込むことが出来ました。

[:source 時に処理を hook する]

autocmd SourceCmd で任意の :source 時の処理を定義する事が出来るのでそれを使用します。

function! s:source_web_file(url)
    let temp = tempname()
    call system(printf("curl %s -o %s", a:url, temp))
    source `=temp`
    call delete(temp)
endfunction

command! -nargs=* WebSource call s:source_web_file(<q-args>)


" netrw と競合するので無効にしておく
augroup Network
    autocmd!
augroup END

augroup web-source
    autocmd!
    " set noshellslash だと / が \\ になっている為、置換
    autocmd SourceCmd https://* execute "WebSource" substitute(expand("<afile>"), '\\', '/', 'g')
    autocmd SourceCmd http://* execute "WebSource" substitute(expand("<afile>"), '\\', '/', 'g')
augroup END


これで専用のコマンドを使用しないで、直接 :source に URL を渡して読み込む事が出来ます。

:source https://gist.github.com/osyo-manga/5805362/raw/da3c5b5882e8469bd8c4e1c46ba2afbdbff29059/test.vim
" => hello, world
" 3 + 2 = 5


と、いうような感じで Web から直接 :source を行うことが出来ました。
今回は gist の raw を対象としていたんですが、対象が raw でなかった場合、raw のリンクを探して、それを :source するような実装を行うと更に便利になると思います。
あと起動時間はかかるけど、ローカルじゃなくて Web 上に vimrc を置いておいてそれを起動時に読み込んでくるってのも面白いかもしれない。