Edited at

unite-buildのbuilderを自作してみる。

More than 5 years have passed since last update.

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

140日目は@tyruエンター巻き込み事故を防ぐでした。


103回目のVim Advent Calendar 2012 ujihisa 5unite-buildが紹介されていた。

unite-buildがどんなものかについては103日目の記事を参照していただければ、概要は理解できるでしょう。

103日目の記事に書いてある通り、このunite-buildはquickrunのoutputter/quickfixに似て非なるものです。

ここでは、unite-buildの使い方とunite-buildのbuilderを自作する方法を説明したいと思います。


unite-buildの使い方

まずはunite-buildの使い方ですが、unite-buildを実行するには以下の4パターンがあります。


:Unite build

これは、各builderのdetent関数によって実行されるかされないかが決まり、実行されるものは順に実行されます。

detent関数については後述するs:builder.detect(args, context)を参照してください。


:Unite build:!

これは、:Unite buildのエラーについてフィルタリングを行わないようなbuilderになります。


:Unite build:{builder-name} or :Unite build:{builder-name}:{args}

上記の2つの場合にはdetent関数によって実行の有無が決定しますが、これは実行したいbuilderを決めることが出来ます。

{builder-name}はbuilderの名前です。 {args}は実行するコマンドへ渡す引数です。

{builder-name}や{args}に空白を含まれている場合には空白をエスケープしなけらばならないことに注意してください。


unite-buildのbuilderの作り方

unite-buildのbuilderの作り方は、コードを読んでもらった方が理解しやすいと思うので最小限であろうコードを以下に示します。

これは単にlsコマンドを実行するだけのbuilderです。

" autoload/unite/sources/build/builders/ls.vim

call unite#util#set_default('g:unite_builder_ls_command', 'ls')

function! unite#sources#build#builders#ls#define()
return executable(g:unite_builder_ls_command) ? s:builder : []
endfunction

let s:builder = { 'name': 'ls', 'description': 'ls builder', }

function! s:builder.initialize(args, context)
return g:unite_builder_ls_command . ' ' . join( a:args, ' ' )
endfunction

function! s:builder.parse(string, context)
let candidate = { 'type' : 'message', 'text' : a:string }
return candidate
endfunction

このコードを&runtimepathが通っている"autoload/unite/sources/build/builders/ls.vim"のような場所に置きます。

そして、Unite build:ls:-alと実行すると以下のような感じで出力されます。


unite-buildのbuilderの詳細


s:builder.name

builderの名前です。{builder-name}にあたる部分になります。


s:builder.description

builderの説明文になります。

これは省略可能です。


s:builder.detect(args, context)

上記にコードにはありませんが、:Unite buildに引数がなにも指定されていない時のみに呼ばれます。

この関数が返す値はBool値で、真を返した時にコマンドを実行し、偽を返した時にはコマンドを実行しません。

これは省略可能です。


s:builder.initialize(args, context)

この関数は実行するコマンドを返します。

a:argsには{args}で指定された値が渡されます。


s:builder.parse(string, context)

コマンドの出力結果の1行ごとにこの関数が呼ばれます。その時、a:stringに1行の文字列が格納されます。

この関数はその行を解析して、その行に関してUniteへの出力に必要な情報を辞書で返します。

返す辞書は、以下のキーを持ちます。

type: 種類を指定します。現状、"error", "warning", "message"のうちのどれかです。

text: Uniteに表示される文字列を指定します。
filename: エラーの場合に参照するファイル名を指定します。(省略可)
line: エラーの場合に参照する行数を指定します。(省略可)
col: エラーの場合に参照する列数を指定します。(省略可)


unite#sources#build#builders#...#define()

s:builderを返す。もし、コマンドが実行出来ないなどのエラーがある場合には空リストを返す。

...の部分にはbuilder名を指定します。


終わりに

unite-buildのbuilderの作成については大体こんなところです。

実際に作成するとなると、s:builder.parse(string, context)が肥大化していくことになるでしょう。

unite-buildには標準でmakeとrepomanが入っています。これらを参考に皆さんもbuilderを作成してみてはいかがでしょうか。