vim-transform というプラグインを作っています。
※ window 環境では動きません 動かない訳でもないらしいです。作者が動作確認してないだけ。
2日前に作り始めたので、まだ日が浅く、仕様が変わる可能性はありますが、ある程度形になって来たので、他のユーザーに使用感をフィードバックして欲しくて、この記事書いてます。
そもそもは、golang の const のセットに String() メソッドを定義するのを自動でやれないか、というのがキッカケ。
vim はそもそも :!
によるフィルタコマンドの出力で置き換える機能を持っているから、発想自体は新しくもない。
vim-transform は、フィルタコマンドの呼び出し方とか、置き換え方とかのフレームワークを提供しているようなイメージ。
処理の流れ
バッファの内容 > STDIN > transformer > STDOUT > 新しいバッファの内容
transformer は標準入力から読んで、標準出力に書く、単なるフィルタプログラムです。言語は問いません。
※ default の transformer ははっきり言って、全然やっつけです。良い transformer も募集中
どの transformer を使うかは後述する transform のルール( web framework の routing みたいなもん? )で決めます。
何が強みか?
そもそも、同様のことは、UltiSnips の様なスニペットプラグインでも出来るとは思ってます(試してませんが)。
ただ、この transformer の仕組みは以下の2つの強みがあります。
- 開発が簡単(STDIN > STDOUTの単なるフィルタプログラムを書けば良い)
- transformer(フィルタプログラム)自体はエディタ非依存(Emacs, Atom, Sublime からも使える)
設定
" mac の場合、Command-Shift-r で、transform を invoke
nmap <D-R> <Plug>(transform)
xmap <D-R> <Plug>(transform)
操作
範囲選択、or transform したい場所にカーソルおいて、keymap を発動!
transform のルール
これはユーザーが設定可能です。以下の様に。
内容が transform したいものだったら、対応する transformer を call a:e.run(TRANSFORMER_NAME)
で invoke します。
この a:e.run()
は中で throw
つかって、ジャンプして終了してるので、一度呼ぶと return してきません。
戻ることを期待した処理を書かないように注意です。
詳細は github のREADME.md を見て下さい。
let g:transform = {}
function! g:transform._(e)
call a:e.run("_/stringfy_word.rb")
endfunction
function! s:route.go(e) "{{{1
let e = a:e
let c = e.content
if c.line_s =~# '\v^const\s*\(' && c.line_e =~# '\v\)\s*'
call e.run("go/const_stringfy.rb")
elseif c['line_s-1'] =~# '\v^import\s*\('
call e.run("go/import.rb")
endif
endfunction