Help us understand the problem. What is going on with this article?

Effective NeoBundle -- autoload関数を理解しNeoBundleを使いこなすための8の方法 --

More than 5 years have passed since last update.

この記事は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番目のNeoBundleLocalset 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書かないかな?

rbtnn
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした