Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

dein.vimでon_source処理を簡単に書けるようにした

$
0
0

dein.vimでプラグインが読み込まれた時に実行させたい処理は autocmdでユーザーイベントをフックして使うようになったようだ。NeoBundleでは独自のon_sourceオプションがあったが、dein.vimでは標準の機能を上手く使ってシンプル&高速化していこうっていうことだと思う。

で、そのsourceフックの書き方について、何か上手い書き方は無いかなーと色々模索してみた記録です。

普通の書き方

dein.vimではプラグイン毎の設定や読み込み時の追加処理はこんな感じに書けば良いようだ。

~/.config/nvim/init.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したプラグイン名が入ってくれるようだ。これを使ってフック関数名を作っちゃえばいいんじゃね?…出来た!

~/.config/nvim/init.vim
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の登録部分はプラグイン毎に全く同じコードを実行してるだけし、もっと簡素な書き方で省力化出来ないかなー。
うーん、もうちょっとゴニョってみよう…、出来た!

~/.config/nvim/init.vim
" 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()を使ったけどコールバック関数の定義しなかったって場合でもエラーになったりはしない。

個人の趣味によるかもだけど、なかなかよい感じではないかな?


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>