dein.vim は NeoBundle に変わるプラグインマネージャです。詳しくはこちらの記事に書きました。
プラグインのリストを TOML ファイルに書くとき、そこにプラグインの設定も一緒に入れてしまうといろいろ捗ります。
この記事ではこれに使われる hook 機能についてまとめてみました。
hook の種類
hook の名前 | 実行されるタイミング | lazy OFF | lazy ON |
---|---|---|---|
hook_add |
プラグインが dein.vim によって追加されたとき | OK | OK |
hook_source |
プラグインが読み込まれる直前 | NG | OK |
hook_post_source |
プラグインが読み込まれた直後 | NG | OK |
hook_post_update |
プラグインが更新された直後 | OK | OK |
hook_done_update |
プラグイン全ての更新が終わった直後 | OK | OK |
以下、それぞれについて例を挙げて見ていきます。
hook_add
dein.vim によってプラグインが認識されたときに発火される hook です。non lazy な(Vim の起動と同時に読み込まれる)プラグインの場合、設定情報を置くにはこれを使うしかありません。
便利な用途としては、プラグインを起動するための mapping を書いたり、プラグインのための変数を設定したりします。
[[plugins]]
repo = 'tpope/vim-capslock'
hook_add = 'imap <C-L> <Plug>CapsLockToggle'
[[plugins]]
repo = 'elzr/vim-json'
hook_add = 'let g:vim_json_syntax_conceal = 0'
hook_source
プラグインを読み込む直前に実行されます。たとえばこんな感じ。
[[plugins]]
repo = 'Shougo/echodoc.vim'
hook_source = 'let g:echodoc_enable_at_startup = 1'
この程度の分量なら hook_add
と大して違いはない(あるいは vimrc
に直接書くのと変わらない)ですが、本当に必要になるときまで設定を遅らせることができるので、Vim 起動時に環境を汚さないようになります。
hook_post_source
プラグインを読み込んだ直後に実行されます。hook_source
と似てますが、プラグイン自体の機能が必要なときはこちらに設定しなければなりません。
[[plugins]]
repo = 'osyo-manga/vim-watchdogs'
depends = [
'vim-hier',
'quickfixstatus',
'shabadou.vim',
'vim-quickrun',
]
# 追記参照 2016/05/09
on_event = ['FocusLost', 'CursorHold']
hook_add = '''
let g:quickrun_config = get(g:, 'quickrun_config', {})
let g:quickrun_config['watchdogs_checker/_'] = {'outputter/quickfix/open_cmd': ''}
let g:quickrun_config['watchdogs_checker/jshint'] = {'cmdopt': '--config `/.jshintrc'}
'''
hook_post_source = '''
call watchdogs#setup(g:quickrun_config)
'''
vim-watchdogs はファイル保存時などに非同期でコンパイルチェックをしてくれるプラグインです。依存関係の複雑なプラグインですので、on_event
を使って Vim 起動後、非同期に読み込んでいます。
/* 追記ここから 2016/05/09 */
on_idle
は deprecated になりました。該当部分のコードを見るとわかりますように、現在は単なる on_event
へのエイリアスになっています。
/* 追記ここまで */
このプラグインは設定の最後に watchdogs#setup()
を呼ぶ必要があるのですが、これは当然、プラグインを読み込んだ後でないと実行できません。こういうときに hook_post_source
は便利です。
hook_post_update
vimproc.vim や Tern for Vim 等、インストール後にコンパイルや関連ツールのインストールが必要なプラグインがあります。dein.vim では、このようなとき build
オプションが使えます。
[[plugins]]
repo = 'Shougo/vimproc.vim'
build = 'make'
以前までこのオプションには OS 毎に別のコマンドを指定することが出来ましたがその機能がなくなってしまいました(このコメントで教えていただきました。thx!)。現在はこのような用途で hook_post_update
を使うことが推奨されています。
[[plugins]]
repo = 'Shougo/vimproc.vim'
hook_post_update = '''
if has('win32')
let cmd = 'tools\\update-dll-mingw'
elseif has('win32unix') " for Cygwin
let cmd = 'make -f make_cygwin.mak'
elseif executable('gmake')
let cmd = 'gmake'
else
let cmd = 'make'
endif
let g:dein#plugin.build = cmd
'''
別にこの hook_post_update
に限った話ではないのですが、全ての hook
では g:dein#plugin
を直接指定して設定を動的に書き換えることができます。1
hook_done_update
最後はこれです。hook_post_update
は各プラグインのインストール直後に実行されるものですが、hook_done_update
はプラグイン全てがインストールされた後(正確には、Runtimepath updated: ...
のメッセージが表示された後)に実行されます。call dein#update()
の後に、自動的に設定を読み込み直す用途などに使えそうです。
設定が膨らんできたら……
便利な hook
なのですが、ここに設定をたくさん載せていくと今度は TOML がカオスになってしまいます。これを避けるため、設定が複雑になってきたら関数に切り出すようにしました。2
set runtimepath+=~/.vim
function! delphinus#init#vimproc#hook_post_update() abort
if has('win32')
let cmd = 'tools\\update-dll-mingw'
elseif has('win32unix') " for Cygwin
let cmd = 'make -f make_cygwin.mak'
elseif executable('gmake')
let cmd = 'gmake'
else
let cmd = 'make'
endif
let g:dein#plugin.build = cmd
endfunction
[[plugins]]
repo = 'Shougo/vimproc.vim'
hook_post_update = 'call delphinus#init#vimproc#hook_post_update()'
autoload
関数にすると、本当に必要になったときだけ、ファイルが読み込まれるようになるので CPU にもストレージにも優しいです。このようにすれば、見通しよくプラグインの管理ができると思います。