かなりすごいブログ

新・ももんが流NeoBundle管理術(あたらしい)

Vim Advent Calendar 2012、361日目の記事になります。

全世界3000億人の美少女Vimmerのみなさん、こんにちは。

さて、今回は、おなじみのプラグインマネージャNeoBundleに最近追加されたneobundle#tapneobundle#untapや、丁度本日追加されたautoloadon_sourceオプションを活用した、新・ももんが流NeoBundle管理術をお伝えしていきたいと思います。

最近追加されたneobundle#tapneobundle#untapについて

これは、私の以前の記事「ももんが流NeoBundle管理術」にてご紹介したs:bundle_tap関数やs:bundle_untap関数などを、NeoBundle作者であるShougoさんがオフィシャルな機能として実装してくださったものです。

NeoBundle付属の関数となったことで若干ですが必要な記述量も減り、よりいい感じになりました。ももんが流NeoBundle管理術のコンセプト・考え方は上記記事を参考にしてください。

コンセプトは、プラグイン管理とプラグイン設定を分離させる、です。

具体的には、NeoBundle及びNeoBundleLazyコマンドのオプションは、依存関係やビルドコマンドなどの「プラグインのインストール方法・管理方法」といったものに絞り、autoloadの設定やプラグイン読み込み時の設定は固有のセクションで管理していきます。

これにより、プラグインリストの見通しがよくなりますし、まぁ色々便利になります。

本日追加されたautoloadon_sourceオプションについて

本日、私が出していた要望が実装されました。それがautoloadon_sourceオプションです。

NeoBundleがプラグインの遅延ロードに対応していることはご存知かと思います。遅延ロード、つまりLazy化を行ったプラグインには、どういったタイミングでプラグインを読み込むのかを設定する必要があります。それがautoloadオプションになります。

filetypecommandsなどを指定し、それをトリガーにしてプラグインが読み込まれるのですが、本日新たにon_sourceというオプションが加わりました。

これは、on_sourceで指定したプラグインが読み込まれようとした際、その前にプラグインをロードするというオプションになります。

これによって、特定のプラグインが読み込まれていることを動作の前提としたプラグインの設定の記述がより簡潔に行えるようになります。

具体例

どういうことなのか、あまりピンとこない方が多いかと思います。そこで、具体例を挙げましょう。私のお気に入りの、VimShellというプラグインがあります。また、VimShellの見た目や機能を拡張するプラグインとして、拙作のVimShell-Pureというプラグインがあります。この2つのプラグインの設定を例とします。

まず、VimShell-PureVimShellのプロンプトを書き換える機能を搭載しているため、VimShellが起動する前にロード(読み込み)が完了している必要があります。そして、Lazy化された設定において、VimShellが起動するタイミングはVimShellをロードするタイミングとほぼ同じです。つまり、VimShellが:VimShellコマンドなどの実行によって起動されようとし、そのためにロードが行われる際、そのタイミングで割り込んでVimShell-Pureを先にロードする必要があります。

この場合、on_sourceオプションを使用せずにそれを実現する設定を記述すると、以下の様になります。

" Plugin list
NeoBundleLazy 'Shougo/vimshell.vim', { 'depends' : [ 'Shougo/vimproc.vim' ] }
NeoBundleLazy 'supermomonga/vimshell-pure.vim', { 'depends' : [ 'Shougo/vimshell.vim' ] }

" Plugin settings
if neobundle#tap('vimshell.vim')
  call neobundle#config({
        \   'autoload' : {
        \     'commands' : [ 'VimShell', 'VimShellPop' ]
        \   }
        \ })
  function! neobundle#tapped.hooks.on_source(bundle)
    if neobundle#is_installed('vimshell-pure.vim')
      call neobundle#source('vimshell-pure.vim')
    endif
  endfunction
  call neobundle#untap()
endif

if neobundle#tap('vimshell-pure.vim')
  call neobundle#untap()
endif

注目して欲しいのはneobundle#tapped.hooks.on_source関数の中身です。これは、そのプラグインがロードされようとした時に呼ばれるhook関数です。その中で、neobundle#is_installed()関数によってVimShell-Pureがインストールされているかの確認を行い、インストールされている場合はneobundle#source()関数によってVimShell-Pureを読み込むという設定が記述されています。neobundle#tapped.hooks.on_sourceの実行が完了、つまりVimShell-Pureのロードが完了した後、VimShellがロードされます。

もちろん、この様に設定を行っても、意図した通りの動作にはなります。しかし、この設定のよくない点は、neobundle#tapによってスコープ化されたVimShellの設定セクションの中で、VimShell-Pureの読み込みタイミングに関する設定を行っているという所です。つまり、VimShell-Pureがいつ・どのようなタイミングで読み込まれるべきなのかといった「VimShell-Pureのふるまい」を、「VimShellのふるまいを定義するべきセクション」の中で定義してしまっているのです。

せっかくneobundle#tapを用いることでプラグインの設定セクションが明確化されたのに、複数のプラグインのふるまいに関する設定が1つのセクション内に混在している状況は精神衛生上よろしくありません。また、VimShell-Pureのふるまいを決める設定、特に読み込みに関するものがVimShellの設定セクション内に残っていると、たとえばVimShell-Pureプラグインの使用を一時的に中止たいと思い、VimShell-Pureプラグインの設定セクション(tapからuntapまで)をコメントアウトした場合も、VimShellの設定セクション内にVimShell-Pureの読み込み設定が残っており、意図せずプラグインが読み込まれてしまうといった弊害も考えられます。

それに対して、on_sourceオプションを利用した設定は以下の通りになります。

" Plugin list
NeoBundleLazy 'Shougo/vimshell.vim', { 'depends' : [ 'Shougo/vimproc.vim' ] }
NeoBundleLazy 'supermomonga/vimshell-pure.vim', { 'depends' : [ 'Shougo/vimshell.vim' ] }

" Plugin settings
if neobundle#tap('vimshell.vim')
  call neobundle#config({
        \   'autoload' : {
        \     'commands' : [ 'VimShell', 'VimShellPop' ]
        \   }
        \ })
  call neobundle#untap()
endif

if neobundle#tap('vimshell-pure.vim')
  call neobundle#config({
        \   'autoload' : {
        \     'on_source' : [ 'vimshell.vim' ]
        \   }
        \ })
  call neobundle#untap()
endif

VimShell-Pureがいつ・どのようなタイミングで読み込まれるべきなのかといった「VimShell-Pureのふるまい」が、ちゃんと「VimShell-Pureのふるまいを定義するべきセクション」の中で完結して定義されていることがお分かりでしょうか。

neobundle#tapneobundle#untapを使用しそれぞれのプラグインの設定をそれぞれのセクション内に閉じ込めるということで、どのプラグインの設定がどこに記述されているのかといった情報が明確になりvimrc管理がとても行い易くなります。autoloadon_sourceオプションを利用することで、読み込み順に関してもそれが行えるようになり、より見通しのよい.vimrcを作れるようになりました。

まとめ

  • 「プラグインのインストール管理」と「プラグインのふるまい方の設定」の記述を分離させよう
  • それぞれのプラグインのふるまいを決める設定は、neobundle#tapneobundle#untapで作ったそれぞれのセクション内に閉じ込め、混在しないようにしよう
  • プラグインの読み込みタイミング制御は、新しく実装されたautoloadon_sourceオプションによりセクジョン内で記述できるようになった
  • 「新・ももんが流NeoBundle管理術」という割には、NeoBundleの標準機能しか使っていない

Vim Advent Calendar 2012 362日目は

Vim Advent Calendar 2012 362日目の担当は@thincaさんです。

いよいよ、365日制覇目前です。恐らくこの記事がVim Advent Calendar 2012における私の最後の記事になるでしょう。とても感慨深く思います。