ref#cache()の使い方

  • 2
    Like
  • 0
    Comment
More than 1 year has passed since last update.

最近vim-refのsourceを作ってて、ref#cache()の使い方がわからなかったのでまとめる。

ref#cache()は基本的にListをキャッシュすることを想定している。
これは恐らく、取得したテキスト(ドキュメント)の内容を行分割したものがそのままキャッシュされることを前提としているから。

ref#cache()は渡す引数によって動作にバリエーションがある。
わかってしまうと、使いやすいインタフェイス。

ref#cache({source-name})

{source-name}のキャッシュに対するkeys()みたいなもの。
キャッシュ済の{name}のリストを取得する。

" => []
echo ref#cache('hoge')
call ref#cache('hoge', 'fuga', [])
" => ['fuga']
echo ref#cache('hoge')

ref#cache({source-name}, {name})

{source-name}のキャッシュから{name}をキーにListを取得する。
{name}というキーが存在しない場合、0が返る ([]のほうが統一感ある気がするけど) 。

" => 0
echo ref#cache('hoge', 'fuga')
call ref#cache('hoge', 'fuga', [])
" => []
echo ref#cache('hoge', 'fuga')

ref#cache({source-name}, {name}, {gather})

ref#cache({source-name}, {name})と基本的には同じだが、キャッシュが存在しない場合には{gather}を評価し、その結果をキャッシュして返す。
{gather}には、以下いずれかを指定可能。

  1. Listを返すFuncref

    引数に{name}を取る。
    キャッシュが存在しない場合のみ実行される。

    function! s:piyo(name)
        return [a:name]
    endfunction
    
    " => ['fuga']
    echo ref#cache('hoge', 'fuga', function('s:piyo'))
    
  2. eval()で評価可能な文字列

    a:nameに{name}が入る。
    呼び出し元のスコープでeval()される訳ではないため、スコープに注意する必要がある。
    キャッシュが存在しない場合のみeval()される。

    " => ['fuga']
    echo ref#cache('hoge', 'fuga', '[a:name]')
    
  3. call()という辞書関数を持つ辞書

    引数に{name}を取る。
    キャッシュが存在しない場合のみ実行される。

    let s:piyo= {}
    function! s:piyo.call(name)
        return [a:name]
    endfunction
    
    " => ['fuga']
    echo ref#cache('hoge', 'fuga', s:piyo)
    
  4. List

    キャッシュが存在しない場合のみ利用される。

    " => ['fuga']
    echo ref#cache('hoge', 'fuga', ['fuga'])
    

ref#cache({source-name}, {name}, {gather}, {update})

基本的にはref#cache({source-name}, {name}, {gather})と同じだが、{update}に0以外が与えられたときには、常にキャッシュの更新を行う。
大体以下と同じ意味。

call ref#rmcache('hoge', 'fuga')
echo ref#cache('hoge', 'fuga', [])