unite.vim の候補を動的にソートする

この記事は Vim Advent Calendar 2012 287日目の記事になります。


さて、unite.vim の候補は以下のようにして動的にソートする事が出来ます。

" :help unite#mappings#set_current_filters()
" 参照
nnoremap <buffer><expr> S      unite#mappings#set_current_filters(
      \ empty(unite#mappings#get_current_filters()) ? ['sorter_reverse'] : [])


これで S を押せば候補が逆順にソートされます。
しかし、unite.vim にはいくつか sorter が用意されており、vimfiler.vim のように候補を選択してソートを行いたい事が稀によくあります。
(vimfiler.vim は S を押すと unite.vim が起動し、ソートの種類を選択してソートを行うことができる。


と、いうことで unite.vim でも同じように動的にソートするような unite-source を書いてみました。

[ソース]

function! s:sort(sorters)
    call unite#mappings#set_current_filters(a:sorters)
    execute "normal \<Plug>(unite_redraw)"
endfunction


let s:source = {
\   "name" : "sort",
\   "action_table" : {
\       "set_current_filters" : {
\           "is_selectable" : 0,
\           "is_quit" : 0,
\       },
\   },
\   "default_action" : "set_current_filters",
\}

function! s:source.action_table.set_current_filters.func(candidate)
    execute "normal \<Plug>(unite_exit)"
    call s:sort(a:candidate.action__sorters)
endfunction


function! s:source.gather_candidates(...)
    let sorters = filter(values(map(unite#variables#filters(), "v:val.name")), 'v:val =~ "^sorter"')
    return map(copy(sorters), '{
\       "word" : v:val,
\       "action__sorters"     : [v:val],
\   }')
\   + map(copy(sorters), '{
\       "word" : "reverse " . v:val,
\       "action__sorters"     : [v:val, "sorter_reverse"],
\   }')
endfunction

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


function! s:start_sort()
    let context = {}
    let context.input = ''
    let context.auto_preview = 0
    let context.unite__is_vimfiler = 0
    let context.default_action = 'default'
    call unite#start_temporary([["sort", ""]], context)
endfunction


augroup my-unite
    autocmd!
    autocmd FileType unite nnoremap <buffer><silent> S :call <SID>start_sort()<CR>
augroup END


こんな感じ。
ぶっちゃけかなり無理やりやっているんですけども…。
unite.vim のバッファで S を押すと unite-sort が起動し、選択したソートで起動した unite の候補をソートします。
ちょっと並び順を変更したい場合に便利かと思います。
ちなみに需要があれば本体に組み込まれるとか組み込まれないとか。