vital.vim の import と関数呼び出しを簡略化してみた

さて、vital.vim をローカルで遊ぶ場合に一般的には下記のような使い方になると思います。

let s:V = vital#of("vital")

let s:DataList = s:V.import("Data.List")
let s:Prelude  = s:V.import("Prelude")


echo s:DataList.char_range("a", "z")
echo s:DataList.flatten([[1,2,3],[4,5,6]])
echo s:DataList.foldr("v:val + v:memo", 0, range(10))
echo s:Prelude.is_float(3.14)
echo s:Prelude.is_float(42)


まぁこんな感じですね。
しかし、上記のコードの場合、

  • :source する度に vital#of と import が呼ばれてしまう
  • s:DataList. のような prefix が邪魔


というような問題があります。
前者の場合は特に quickrun.vim を使用する場合に問題になってきます。
quickrun.vim で vital.import を呼び出すと :scriptnames が出力されてしまう。


後者は、

let s:DL = s:V.import("Data.List")

echo s:DL.char_range("a", "z")

のように短くする方法もありますが、やはり鬱陶しいです。


※後者は import に s: などを渡して解決出来るらしいです。

V.import('Data.List', s:)
echo s:char_range("a", "z")

みたいな書き方が出来るみたい(あとから知った。


と、いうことで import の仕組みをラップして使い勝手をよくしてみました。

[ソース]

function! g:vital_import(target, libname, ...)
    let plugin_name = get(a:, "1", "vital")
    if !has_key(a:target, plugin_name)
        let a:target[plugin_name] = vital#of(plugin_name)
    endif
    let vital = a:target[plugin_name]
    let libname = substitute(a:libname, '\.', '_', "g")
    if !has_key(a:target, libname)
        let a:target[libname] = vital.import(a:libname)
        call extend(a:target, a:target[libname])
    endif
endfunction


" s: に各モジュールの機能を展開する
call g:vital_import(s:, "Data.List")
call g:vital_import(s:, "Data.String")
call g:vital_import(s:, "Prelude")


" s: から直接関数を呼び出す
echo s:char_range("a", "z")
echo s:flatten([[1,2,3],[4,5,6]])

" 明示的にモジュールを指定して呼び出す
" . は使えないので _ で代用
echo s:Data_List.flatten([[1,2,3],[4,5,6]])

echo s:foldr("v:val + v:memo", 0, range(10))
echo s:is_float(3.14)
echo s:is_float(42)
echo s:chop("まみまみ")


" 明示的にエイリアスを付ける場合
let s:F = get(s:, "F", {})
call g:vital_import(s:F, "Functor")

" s:F に展開される
echo s:F.call("add", [[1,2], 3])

[出力]

['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
[1, 2, 3, 4, 5, 6]
[1, 2, 3, 4, 5, 6]
45
1
0
まみま
[1, 2, 3]


まず、vital#of と import をラップして、1度の呼び出しで import 出来るようにしてみました。
1度 import したモジュールは2回目以降は呼び出されません。


次に各モジュールの関数ですが、そのまま s: に展開するようにしてみました。
これで、s:{モジュールの関数名} というような呼び出しを行うことができます。
個人的にはこれでかなり vital.vim の使い勝手がよくなったんじゃないかと思います。
vital#of や import は s: じゃなくて、g: に展開してもいいかなぁ。

[注意]

今回の処理では各モジュールで同名の関数がある場合を全く考慮していません。
同名の関数があった場合は最初に import したモジュールが優先されます。
同名の関数で問題になった場合は、g:vital_import に渡す辞書を適当に変更して見て下さい。