neobundle.vimには,遅延読み込み機能があり,適切に設定してやることで,プラグインの使用感はそのままで,Vimの起動時間を短縮することができる. autoloadの設定には,
- ファイルタイプ検出時
filetypes
- ファイル名検出時
filename_patterns
- コマンド実行時
commands
- 関数実行時
functions
,function_prefix
- マップ実行時
mappings
- Uniteのソース読み込み時
unite_sources
- インサートモードに入った時
insert
など,様々なタイミングで,プラグインのパスを runtimepath
に追加し,読み込みを行うことができる.
コマンドの実行時の検出は,仮のコマンドを定義しておいて,それが実行されたとき,プラグイン本体を読み込む仕組みとなっていると思われる.
そして,仮のコマンドには引数の補完関数を指定することもできる.
basyura/TweetVimのNeoBundleLazyの設定を例にとると,以下のような形になるだろう.
NeoBundleLazy 'basyura/TweetVim' if neobundle#tap('TweetVim') call neobundle#config({ \ 'depends': ['tyru/open-browser.vim', 'basyura/twibill.vim'], \ 'autoload': { \ 'commands': [ \ 'TweetVimAccessToken', \ 'TweetVimAddAccount', \ 'TweetVimClearIcon', \ 'TweetVimCommandSay', \ 'TweetVimCurrentLineSay', \ 'TweetVimHomeTimeline', \ {'name': 'TweetVimListStatuses', 'complete': 'custom,tweetvim#complete#list'}, \ 'TweetVimMentions', \ {'name': 'TweetVimSay', 'complete': 'custom,tweetvim#complete#account'}, \ {'name': 'TweetVimSearch', 'complete': 'custom,tweetvim#complete#search'}, \ {'name': 'TweetVimSwitchAccount', 'complete': 'custom,tweetvim#complete#account'}, \ 'TweetVimUserStream', \ {'name': 'TweetVimUserTimeline', 'complete': 'custom,tweetvim#complete#screen_name'}, \ 'TweetVimVersion' \ ], \ 'unite_sources': 'tweetvim' \ } \}) call neobundle#untap() endif
この例のautoloadのcommands設定にあるように,コマンドの補完関数には, custom
や customlist
に,プラグインの autoload/hoge.vim
で定義されている関数を指定してもよい.
その場合,コマンド引数のTab補完を行った瞬間に,プラグインのロードが行われる.
しかし,プラグインによっては, custom
や customlist
に, plugin/hoge.vim
のスクリプトローカル関数を指定している場合もある.
スクリプトローカル関数はneobundle側からは見えないので,指定することはできない.
プラグインのロードが行われるまで我慢してもよいが,少し気分が悪い.
そこで,.vimrcに plugin/hoge.vim
で定義されている関数をコピペし,neobundleから見えるようにスクリプト番号と共に渡してやるとよい.
その補完関数はプラグインのロード後には不必要になるので,プラグイン読み込み時に呼び出されるフック関数で消去する,あるいは消去するオートコマンドを定義する.
そういったプラグインの例として,mattn/gist-vimやosyo-manga/vim-reanimateなどがあるので,その2つのプラグインを例にとって,設定例を紹介する.
if has('vim_starting') set rtp+=~/.vim/bundle/neobundle.vim endif call neobundle#begin() NeoBundleFetch 'Shougo/neobundle.vim' let g:neobundle#default_options = {'_': {'verbose': 1}} augroup CompleteDummy autocmd! augroup END function! s:SID() abort return matchstr(expand('<sfile>'), '<SNR>\zs\d\+\ze_SID$') endfun let s:sid = s:SID() delfunction s:SID function! s:to_global_name(scriptlocal_funcname) abort return '<SNR>' . s:sid . '_' . a:scriptlocal_funcname endfunction " 適当なイベントが発生したら,補完関数を消去 function! s:delete_function_lazy(funcname) abort execute 'autocmd CompleteDummy CursorHold,CursorHoldI,CursorMoved,CursorMovedI,InsertEnter *' \ 'delfunction' a:funcname \ '| autocmd! CompleteDummy CursorHold,CursorHoldI,CursorMoved,CursorMovedI,InsertEnter *' endfunction if neobundle#load_cache() NeoBundleLazy 'mattn/gist-vim' NeoBundleLazy 'osyo-manga/vim-reanimate' " キャッシュされる設定はこっちに書く if neobundle#tap('gist-vim') call neobundle#config({ \ 'autoload': { \ 'commands': {'name': 'Gist', 'complete': 'customlist,' . s:to_global_name('gist_CompleteArgs')} \ } \}) call neobundle#untap() endif if neobundle#tap('vim-reanimate') let s:_ = 'customlist,' . s:to_global_name('reanimate_save_point_completelist') call neobundle#config({ \ 'autoload': { \ 'commands': [ \ {'name': 'ReanimateSave', 'complete': s:_}, \ 'ReanimateSaveCursorHold', \ 'ReanimateSaveInput', \ {'name': 'ReanimateLoad', 'complete': s:_}, \ 'ReanimateLoadInput', \ 'ReanimateLoadLatest', \ {'name': 'ReanimateSwitch', 'complete': s:_}, \ {'name': 'ReanimateEditVimrcLocal', 'complete': s:_}, \ 'ReanimateUnLoad' \ ] \ } \}) unlet s:_ call neobundle#untap() endif NeoBundleSaveCache endif call neobundle#end() " キャッシュされないグローバル変数の設定等はこっち if neobundle#tap('gist-vim') " plugin/gist.vim を見てコピペ function! s:gist_CompleteArgs(arg_lead,cmdline,cursor_pos) abort return filter(["-p", "-P", "-a", "-m", "-e", "-s", "-d", "+1", "-1", "-f", "-c", "-l", "-la", "-ls", "-b", \ "--listall", "--liststar", "--list", "--multibuffer", "--private", "--public", "--anonymous", "--description", "--clipboard", \ "--rawurl", "--delete", "--edit", "--star", "--unstar", "--fork", "--browser" \ ], '!stridx(v:val, a:arg_lead)') endfunction function! neobundle#tapped.hooks.on_post_source(bundle) abort delfunction s:gist_CompleteArgs endfunction call neobundle#untap() endif if neobundle#tap('vim-reanimate') " plugin/reanimate.vim を見てコピペ function! s:reanimate_save_point_completelist(arglead, ...) abort return filter(reanimate#save_points(), "v:val =~? '" . a:arglead . "'") endfunction " neobundle#tapped.hooks.on_source() でもいい function! neobundle#tapped.hooks.on_post_source(bundle) abort " 一時的な補完関数の中でautoload関数をコールをしているので, " このタイミングで補完関数は消去できない " なので,適当なタイミングで一時的な補完関数を消去する call s:delete_function_lazy('s:reanimate_save_point_completelist') endfunction let g:reanimate_save_dir = '~/.vim/save' let g:reanimate_default_save_name = 'reanimate' let g:reanimate_sessionoptions = 'curdir,folds,help,localoptions,slash,tabpages,winsize' call neobundle#untap() endif if !has('vim_starting') call neobundle#call_hook('on_source') endif filetype plugin indent on