unite-messages をつくってみる

この記事は Vim Advent Calendar 2012 334日目の記事になります。
明日以降の担当者がまだ決まっていないので誰か書きたい方がいれば @osyo_memo までご連絡下さい。
ちなみに Vim Advent Calendar 2013 は明日あたりから募集する予定です。


上記の記事に触発されて unite.vim だとどこまで出来るのかいろいろと試してみました。

[:messages を unite.vim で出力]

:messages を unite.vim へと出力する場合は unite-output を使用するのが楽だと思います。

" :messages の出力結果を unite.vim へ出力する
:Unite output:messages


これは次のように aliases を設定しておくと呼び出しが楽になります。

let g:unite_source_alias_aliases = {
\   'messages' : {
\       'source': 'output',
\       'args': 'message',
\   },
\}
" :Unite output:messages
:Unite messages

[候補を逆順に表示する]

LeafCage さんの記事でも書かれていましたが、いちいち一番下の出力結果まで移動するのは手間です。
そこで『回避方法その1』という事で出力結果を逆順にしてみます。
これには unite-filters が利用できます。

" 逆順に sort する
call unite#custom#source('messages', 'sorters', 'sorter_reverse')


これで一番最後に出力された :messages が一番上に移動します。

[unite.vim の起動後に一番下にカーソルを移動させる]

『回避方法その2』
unite.vim の起動時に -log オプションを追加する事がカーソルを一番下に移動させる事ができます。

:Unite messages -log


sorter_reverse の設定とは咬み合わないので、このオプションを使用する場合は sorter_reverse を設定しないほうがよいでしょう。

[:messages の内容を削除する]

Vim では :messages の内容を削除することはできません。
しかし、次のように空の文字列を出力する事で擬似的に :messages で表示されないようにすることはできます。

" 履歴をすべて空の文字列で埋める
for n in range(200) | echom "" | endfor

" コマンドを定義したり
command! MessageClear for n in range(200) | echom "" | endfor


これは :messages を使用する場合には有効なのですが、unite.vim へ出力する場合には空の行が挿入されるので有効ではありません。



そこで次のように『候補が空白であれば削除する』という unite-filters を定義してみました。

" 空白行を取り除く converter を定義する
let s:filters = {
\   "name" : "converter_remove_empty_word",
\}

function! s:filters.filter(candidates, context)
    return filter(deepcopy(a:candidates), '!empty(v:val.word)')
endfunction

call unite#define_filter(s:filters)
unlet s:filters


" messages の converters を設定する
call unite#custom#source('messages', 'converters', "converter_remove_empty_word")


これで空白行は表示されません。

[開く位置を変更する]

:messages の場合は一番下の位置で開かれるので unite.vim でも一番下の位置で開くように設定してみようと思います。
unite.vim は -direction コマンドオプションで開く位置も設定することができます。

:Unite messages -direction=botright


他の開き方なんかは、

:help opening-window

を参照して下さい。

[unite.vim のバッファを再描画する]

unite.vim で messages を開きっぱなしにしている場合、外部から messages の出力の再描画を行いたい場合があると思います。
そのような場合には次のようにして、外部から特定の unite.vim のバッファを再描画する事ができます。

" バッファ名を指定して unite.vim を開く
:Unite messages  -buffer-name=messages

" unite.vim の起動時に指定したバッファ名 "messages" を再描画する
call unite#force_redraw(unite#helper#get_unite_winnr("messages"))

[コマンドを定義する]

頻繁に使用するようであれば次のようなコマンドを定義しておくと便利です。

" コマンドオプションを設定したコマンドを定義
command! -nargs=* -complete=customlist,unite#complete#source
\   Message
\   Unite messages -direction=botright -log -buffer-name=messages <args>

" vim-altercmd を使用して :messages と入れ替えてみたり
AlterCommand mes Message
AlterCommand Mes mes


簡単にですがこんな感じで設定してみました。
:messages に比べて unite.vim を起動するオーバーヘッドはあるのですが、unite-filters 等を使用した拡張性は高いと思います。
デフォルトの :messages で満足できないのであれば使用してみるとよいと思います。
あとはハイライトとかを設定したいですね。