この記事はVim Advent Calendar 2012 : ATND 160日目の記事になります。
159日目は@tyruのこれであなたも節約上手!キーボード上のキーを最大限活用できる人のN個の習慣とは?でした。
第44回 vimrc読書会で「neobundle#config() に関する記事を書くと有り難がられる。」
という話になったので、今回はNeoBundleのコアな設定(もしくは意外と知られていない設定)
について紹介したいと思います。
neobundle#rc()は引数を省略できる。
この関数neobundle#rc([{base-path}])
は引数である{base-path}を省略することができます。
省略するとどうなるかというと、下記のコードは同じ意味を持つことになります。
call neobundle#rc()
call neobundle#rc(expand('~/.vim/bundle'))
NeoBundle使っている方は知っているかと思いますが念のためneobundle#rc()の説明をします。
neobundle#rc()はNeoBundleを初期化する関数です。
この関数を呼ぶ前に必ず以下のようにneobundle.vimのディレクトリをhas('vim_starting')
内でruntimepathに加えておかなければなりません。決して、has('vim_starting')
内でneobundle#rc()
を呼び出してはいけません。
set nocompatible
if has("vim_starting")
set runtimepath+=~/.vim/neobundle.vim
endif
call neobundle#rc(expand("~/.vim/bundle"))
...
filetype plugin indent on
ちなみに、なぜhas('vim_starting')
内でneobundle#rc()
を呼び出してはいけないかというとvimrcの再読み込みに備えるためにです。
has('vim_starting')
はVimの起動時のみ真になります。なので、vimrcをso $MYVIMRC
などで再読み込みした時にはもうすでにhas('vim_starting')
は偽になってしまいます。
ということは、set runtimepath+=~/.vim/neobundle.vim
は再読み込みした時にもう一度設定する必要がないためhas('vim_starting')
内でよく、call neobundle#rc(expand("~/.vim/bundle"))
はこの後設定するNeoBundle '~'
のために一度設定をクリアにしとかなければなりません。
また、この関数は自動的に:filetype off
を行います。
なのでわざわざ、vimrcに:filetype off
を行うようなコードは必要ありません。
引数である{base-path}はNeoBundleで管理されたプラグインがデフォルトでインストール
されるディレクトリです。{base-path}は省略可能です。省略した場合、デフォルトで
インストールされるディレクトリは下記のような式で設定されます。
expand(get( filter(split(globpath(&runtimepath, 'bundle', 1), '\n'), 'isdirectory(v:val)'), 0, '~/.vim/bundle'))
なので、call neobundle#rc()
とcall neobundle#rc(expand('~/.vim/bundle'))
は全く
同じ意味になります。
":set rtp+=..."やNeoBundle系のコマンドの違いを理解する。
Vimプラグインを使用する場合NeoBundle系のコマンドを使用すると思いますが、
NeoBundle系のコマンドには何種類か存在します。
ここで、:set rtp+=...
やNeoBundle系のコマンドの違いをまとめてみたいと思います。
とりあえず、簡単に表にまとめてみました。
&rtpに追加される | NeoBundleで管理される | プラグインが読み込むタイミング | |
---|---|---|---|
set rtp+=... | ○ | × | filetype on が実行された直後 |
NeoBundleLocal | ○ | ○ | filetype on が実行された直後 |
NeoBundle | ○ | ○ | filetype on が実行された直後 |
NeoBundleFetch | × | ○ | 読み込まれない |
NeoBundleLazy | ○ | ○ | hookかNeoBundleSourceを実行後 |
1番目のset rtp+=...
は問題ないですね。&runtimepathに新しいパスを追加するだけです。
NeoBundleで管理もされませんし、プラグインが読み込むタイミングを遅延させることも出来ません。
2番目のNeoBundleLocal
はset rtp+=...
の追加を楽にしたバージョンという感じです。
NeoBundleLocal ~/.vim/mybundle
使いかたは上記のような感じでパスを指定し、このパスのサブディレクトリに当たるパスを
それぞれ&runtimepathに加えることができます。
これもNeoBundleで管理もされませんし、これはNeoBundleで管理もされます。
しかし、プラグインが読み込むタイミングを遅延させることは出来ません。
3番目のNeoBundle
も問題ないですね。
&runtimepathに新しいパスを追加しNeoBundleで管理します。
基本的にはプラグインが読み込むタイミングを遅延させることも出来ませんが、
後述するneobundle#config()
によって特性をいくらでも変更することは可能です。
4番目のNeoBundleFetch
は使いどころが難しいコマンドです。
このコマンドはNeoBundleで管理するだけです。
&runtimepathに追加しないので、プラグインを読み込むこともしません。
主な使いどころはneobundle.vim で github の C++ ライブラリを管理するのような
Vimプラグインでないライブラリの管理くらいでしょうか。
5番目のNeoBundleLazy
は簡単にいうとNeoBundle
の遅延評価版です。
NeoBundleでは管理されますが、すぐに&runtimepathにパスが追加されることはありません。
NeoBundleSourceを実行して初めて&runtimepathに追加されます。
もしくは、コマンドなどにフックを設定しておくことで遅延して読み込ませることが可能になります。
NeoBundleLazy
も後述するneobundle#config()
によって特性をいくらでも変更することは可能です。
NeoBundleで管理されているプラグインかどうかを知る。
NeoBundleで管理されているプラグインかどうかがわかると、NeoBundle系コマンドを
コメントアウトしただけでプラグインの設定をオフにすることが可能になります。
で、NeoBundleで管理されているプラグインかどうかを知るには下記のようなコードで実現できます。
" NeoBundle 'Shougo/neocomplcache'
if ! empty(neobundle#get("neocomplcache"))
" コメントアウトしているのでここにはきません。
endif
NeoBundleを導入する場合、autoload関数を呼ぶコストを考える。
NeoBundleを導入すると、必ず下記のファイルを読み込まれることになります。
- neobundle.vim/autoload/neobundle/util.vim
- neobundle.vim/autoload/neobundle.vim
- neobundle.vim/autoload/neobundle/config.vim
- neobundle.vim/ftdetect/vimrecipe.vim
- neobundle.vim/plugin/neobundle.vim
ということは、neobundle#rc()
やneobundle#config#bundle()
は呼び出しても
差ほどコストにはなりませんが、neobundle#autoload#get_unite_sources()
などを
vimrcから読みだすと'neobundle.vim/autoload/neobundle/autoload.vim'が
新しく読み込まれるので、Vimの起動時間を長くする原因になりえるかもしれません。
NeoBundleに限った話ではありませんがvimrcからautoload関数を呼ぶ際には
注意しておくとよいかもしれません。
NeoBundle系コマンドのオプションとneobundle#config()との関係を理解する。
:NeoBundle {repository} [[,{revision}] [,{options}]]
:NeoBundle {repository} ,{revision}, {default} [,{options}]]
:NeoBundle
コマンドは上記のような構文になっております。(:NeoBundleLazy
コマンドも同じく)
たとえば、下記のコマンドは{repository}が'vimproc'
、{options}が{ 'build' : { ... }}
に当たります。
NeoBundle "vimproc", {
\ "build" : {
\ "windows" : "mingw32-make -f make_mingw32.mak",
\ "cygwin" : "make -f make_cygwin.mak",
\ "mac" : "make -f make_mac.mak",
\ "unix" : "make -f make_unix.mak",
\ },
\ }
で、この{options}部はneobundle#config()
を使って次のように分割することができます。
NeoBundle "vimproc"
call neobundle#config("vimproc", {
\ "build" : {
\ "windows" : "mingw32-make -f make_mingw32.mak",
\ "cygwin" : "make -f make_cygwin.mak",
\ "mac" : "make -f make_mac.mak",
\ "unix" : "make -f make_unix.mak",
\ },
\ })
ちなみに、{revision}部も{options}に含めることが可能です。
call neobundle#config('vimproc', { 'rev' : '43AF234' })
また、neobundle#config()
は既存の{options}に追加されるようになっていますので、
次の2つのような書き方ができます。
" 分割して設定
call neobundle#config("vimproc", { "A" : "..." })
call neobundle#config("vimproc", { "B" : "..." })
" まとめて設定
call neobundle#config("vimproc", { "A" : "...", "B" : "..." })
NeoBundle系コマンドの{options}部で設定するのと、neobundle#config()で設定するのとでの違いはほとんどありません。
NeoBundleLazyの正体
プラグインの読み込みを遅延させてくれるコマンドNeoBundleLazy
というものがあります。
実はこれは、NeoBundle
に'lazy'オプションを有効にしただけのaliasにすぎません。
なので、下記の2つは同じ挙動になります。
NeoBundleLazy 'vimproc'
NeoBundle 'vimproc', { 'lazy': 1 }
ただし、:call neobundle#config('vimproc', { 'lazy': 1 })
とする場合、
:filetype on
される前に呼ばないと遅延されないので気を付けてください。
プラグインの設定をon_sourceでできるだけ遅延させる。
on_sourceというhookを利用することで、プラグインの設定をできるだけ遅延させることができます。
" `Unite`コマンドが実行されるときに初めてプラグインを読み込む
NeoBundleLazy "Shougo/unite.vim", {
\ 'autoload' : {
\ 'commands' : [ "Unite" ]
\ }
\}
let s:hooks = neobundle#get_hooks("unite.vim")
function! s:hooks.on_source(bundle)
" 遅延させたいプラグインの設定を記述する
endfunction
詳細はneobundle.vim の遅延処理で Vim の起動を高速化するを参考に!
NeoBundleのほとんどの設定はneobundle#config#get_neobundles()で把握できる。
これまで、neobundle#config()
を中心にしてきましたが、実際にどういう風に設定されているかは、
neobundle#config#get_neobundles()
かneobundle#get({bundle-name})
ですべて把握できます。
(オプションの詳細については今回は説明しません。:help neobundle-options を参照してみて下さい。)
neobundle#config#get_neobundles()
この関数はNeoBundleの現状のセッティングを辞書のリストで返します。
" echo neobundle#config#get_neobundles()
[
{
"autoload": {},
"base": "C:/Users/rbtnn/.vimplugins",
"depends": [],
"description": "",
"directory": "vimdoc-ja",
"disabled": 0,
"dummy_commands": [],
"dummy_mappings": [],
"external_commands": {},
"gui": 0,
"hooks": {},
"lazy": 1,
"name": "vimdoc-ja",
"orig_arg": '''vim-jp/vimdoc-ja''',
"orig_name": "vim-jp/vimdoc-ja",
"orig_opts": [],
"overwrite": 1,
"path": "C:/Users/rbtnn/.vimplugins/vimdoc-ja",
"resettable": 1,
"rev": "",
"rtp": "C:/Users/rbtnn/.vimplugins/vimdoc-ja",
"script_type": "",
"sourced": 0,
"stay_same": 0,
"tail_path": 1,
"terminal": 0,
"type": "git",
"uri": "git://github.com/vim-jp/vimdoc-ja.git"
},
{
"autoload": {"commands": ["HexriptToBinaryFile", "VinariseHex2Script", "VinariseScript2Hex"], "function_prefix": "hexript"},
"base": "C:/Users/rbtnn/.vimplugins",
...
実際に実行して見てもらえればわかると思いますが、NeoBundleLazy '...'
やNeoBundle '...',{ ... }
やneobundle#config('...',{...})
で行った設定はこの関数で確認することが出来ます。
この関数は出力が非常に多いので私は以下のようなコマンドをvimrcに作成しておいて、
QuickRunPP neobundle#config#get_neobundles()
を実行して確認しています。
" NeoBundle "thinca/vim-quickrun"
" NeoBundle "thinca/vim-prettyprint"
function! s:quickrun_pp(q_args)
let dict = { "type" : "vim", "runner" : "vimscript", "outputter" : "buffer",
\ "outputter/buffer/filetype" : "vim", "hook/eval/enable" : 1,
\ "hook/eval/template" : "echo PP(%s)", "src" : a:q_args, }
call quickrun#run(dict)
endfunction
command! -nargs=1 -complete=expression QuickRunPP :call <sid>quickrun_pp(<q-args>)
毎回、neobundle#config#get_neobundles()から取り出してくるのは億劫なので、以下のようなショートカットautoload関数が用意されています。
neobundle#get({bundle-name})
この関数はneobundle#config#get_neobundles()
のキー'name'が{bundle-name}の辞書を
返します。もし、存在しない場合には{}
を返します。
neobundle#get_hooks({bundle-name})
この関数はneobundle#get({bundle-name})
のキー'hooks'の値を返します。
もし、存在しない場合には{}
を返します。
neobundle#is_sourced({bundle-name})
この関数はneobundle#get({bundle-name})
のキー'sourced'の値を返します。
もし、存在しない場合には0
を返します。
neobundle#is_installed({bundle-name})
この関数はneobundle#get({bundle-name})
のキー'path'の値を返します。
もし、存在しない場合には''
を返します。
終わり
始めはNeoBundleについて15個くらいのネタを書こうかと用意していたのですが、
段々飽きてきて最終的に8個になってしまいましたw。
今回は、neobundle#config()
とQuickRunPP neobundle#config#get_neobundles()
が結構便利だなーっていうことが書きたかっただけでした。以上
誰か、Effective Vim script書かないかな?