codic-vim に手を加えない unite-codic 書いてみた

[追記]

codic-vim に関数が追加されて unite-codic.vim が出来ました。


初 unite-source

[関連]


codic-vim とは何なのか!というのは kaoriya さんの記事を読んでみるとよいのですが、それを fork して unite-source を付属させたものを rhysd さんが公開されました。
これ、なんで unite-source だけではなくて fork しているのだろうと思ったら vim-codic 側の関数が公開されておらず、そのあたりも対応する必要があったようです。
ただ、この場合だと vim-codic が更新された場合に追従するのがちょっと手間なので vim-codic 側に手を入れないような unite-codic を書いてみました。
※ただし、動作させるためには scall.vim が必要になります。

[unite.vim]

let s:source = {
\   "name" : "codic",
\   "kind" : "word",
\   "default_action" : "insert",
\   "max_candidates" : 100,
\   "hooks" : {}
\}


function! s:source.hooks.on_init(args, context)
    if exists("s:Codic_GetDictAuto")
        return
    endif
    silent! echo codic#command("")
    let s:Codic_GetDictAuto = scall#search("autoload/codic:GetDictAuto")
endfunction


function! s:Find(dict, word, size)
  let items = []
  for [ k, v ] in items(a:dict)
    let score = stridx(k, a:word)
    if score >= 0
      call add(items, { 'score': score, 'key': k, 'item': v })
    end
  endfor
  call sort(items, 's:Compare')
  return map(items[0 : a:size - 1], 'v:val["item"]')
endfunction


function! s:Compare(i1, i2)
  let cmp = a:i1['score'] - a:i2['score']
  if cmp != 0
    return cmp
  endif
  return len(a:i1['key']) - len(a:i2['key'])
endfunction


function! s:get_dict(word, size)
    if empty(a:word)
        return []
    endif
    let dict = s:Codic_GetDictAuto(a:word)
    if empty(dict)
        return []
    endif
    let result = s:Find(dict, a:word, a:size)
    return result
endfunction


function! s:source.change_candidates(args, context)
    let word = matchstr(a:context.input, '^\S\+')
    if word == ''
        return []
    endif

"     let items = s:get_dict(word, self.max_candidates)
    let items = s:get_dict(word, get(a:args, 0, 100))
    let top_items = items
    let candidates = []
    for top_item in top_items
        call add(candidates, {
\           "word" : top_item.label,
\           'abbr' : '['. top_item.label . ']',
\       })
        for value in top_item.values
            call add(candidates, {
            \ 'word' : printf('  %s %s %s', top_item.label, value.word, value.desc),
            \ 'abbr' : printf('  %s %s', value.word, value.desc),
            \ 'action__text' : value.word,
            \ })
        endfor
    endfor
    return candidates
endfunction

call unite#define_source(s:source)
unlet s:source


scall.vim を使用して codic-vim 内のスクリプトローカル関数を呼んでいます。
実装は rhysd さんのコードを流用しているだけなので動作は変わらないと思います。