dein.vim
でプラグインが読み込まれた時に実行させたい処理は autocmd
でユーザーイベントをフックして使うようになったようだ。NeoBundle
では独自のon_source
オプションがあったが、dein.vim
では標準の機能を上手く使ってシンプル&高速化していこうっていうことだと思う。
で、そのsourceフックの書き方について、何か上手い書き方は無いかなーと色々模索してみた記録です。
普通の書き方
dein.vim
ではプラグイン毎の設定や読み込み時の追加処理はこんな感じに書けば良いようだ。
" どこか最初の方に書いておく
augroup MyAutoCmd
autocmd!
augroup END
if dein#tap('deoplete-go') " プラグインの設定letg:deoplete#sources#go#align_class =1 " on_source処理function! deoplete_go_on_source() abort
" gocodeが無ければインストールif executable('go')&& !executable('gocode')
echo "install gocode ..."call system("go get -u github.com/nsf/gocode")endifendfunction
execute "autocmd MyAutoCmd User dein#source#deoplete-go call s:deoplete_go_on_source()"endif
ところで、autocmd
を使う場合ワンライナーな設定ならまだしも、まとまった処理を書こうとするとやはり一度関数を作って実行することになるよね。
で、その時に使うユニークな関数名を考えるのが毎度毎度凄く面倒くさいんだよな…。しかもこの関数名って関数定義時とautocmdの登録時で2回も同じ名前を書かなきゃいけないのも面倒だし、さらに言えばこの関数名をautocmdの登録以外で使うことも無いので関数名の存在価値の無さも半端ない…。
つまりもっと楽がしたい!
関数名を考えたくない
で、何とか楽ができないかと調べてたら、どうやら dein#tap()
すると g:dein#name
に今tapしたプラグイン名が入ってくれるようだ。これを使ってフック関数名を作っちゃえばいいんじゃね?…出来た!
if dein#tap('deoplete-go') " プラグインの設定letg:deoplete#sources#go#align_class =1 " on_source処理lets:on_source = substitute(g:dein#name,'\W','_','g') . '_on_source'function!s:{s:on_source}() abort
if executable('go')&& !executable('gocode')
echo "install gocode ..."call system("go get -u github.com/nsf/gocode")endifendfunction
execute "autocmd MyAutoCmd User dein#source#".g:dein#name." call s:".s:on_source."()"endif
うむ、autocmd
用の関数名を考えなくて良いって楽だね!
関数名を考えたくない&コピペ量も減らしたい
関数名考えなくて良くなって多少楽になったけど、全体的になんかちょっとゴツいし、一時変数 s:on_source
を作ったり autocmd
の登録部分はプラグイン毎に全く同じコードを実行してるだけし、もっと簡素な書き方で省力化出来ないかなー。
うーん、もうちょっとゴニョってみよう…、出来た!
" dein#tap()の代わりに使うとブロック内で s:{s:on_source}() という関数定義をするだけでフック登録出来る便利関数function!s:dein_tap(name) abort
if dein#tap(a:name)lets:on_source = substitute(a:name,'\W','_','g') . '_on_source'
execute 'autocmd MyAutoCmd User'
\ 'dein#source#' . a:name
\ 'if exists("*s:' . s:on_source . '") | call s:' . s:on_source . '() | endif'return1endifreturn0endfunction" 各プラグインのtapブロック内では後処理の関数定義をするだけでOKifs:dein_tap('deoplete-go') " プラグインの設定letg:deoplete#sources#go#align_class =1 " on_source処理function!s:{s:on_source}() abort
if executable('go')&& !executable('gocode')
echo "install gocode..."call system("go get -u github.com/nsf/gocode")endifendfunctionendif" 各プラグインのtapブロック内では後処理の関数定義をするだけでOKifs:dein_tap('totemo-sugoi-nanika')function!s:{s:on_source}() abort
echo "とても凄い何かが読み込まれたぞ!"endfunctionendif
処理の流れ的には以下の様な感じだ。
s:dein_tap()
て関数を作ってこれをdein#tap()
の代わりに使うようにする。- ブロック内では
function! s:{s:on_source}()
というコピペOKなお決まりの関数定義を書いて中にやりたい処理を書くだけでよい。 autocmd
の登録もs:dein_tap()
がやってくれているので毎回自分で書いてやる必要はない。- もちろん
s:dein_tap()
を使ったけどコールバック関数の定義しなかったって場合でもエラーになったりはしない。
個人の趣味によるかもだけど、なかなかよい感じではないかな?