かなりすごいブログ

プロジェクトのハンドリングを効率化するプラグイン、ProjectLocal.vimをリリースしました。

Vim Advent Calendar 2013、66日目の記事になります。

ProjectLocal.vimをリリースしました

プロジェクトのハンドリングを効率化する薄い機能を提供するプラグイン、ProjectLocal.vimをリリースしましたのでご紹介します。

https://github.com/supermomonga/projectlocal.vim

ProjectLocal.vimの機能

プロジェクトのルートディレクトリにProjectfileという名前のファイルを配置すると、そのディレクトリは1つのプロジェクトとして扱われるようになり、ディレクトリ以下のファイルを開いた時に以下の2つの機能が発動します。

1. プロジェクトルートディレクトリの設定

ProjectLocal.vimは、現在開いているファイルのプロジェクトのルートディレクトリを、ファイル(バッファ)のローカル変数に自動でセットします。これにより、プロジェクト内のどのファイルを開いた時も、常にバッファがプロジェクトルートの位置を知ることができます。具体的には、b:projectlocal_root_dirというバッファローカル変数にパスがセットされます。

2. プロジェクト用filetypeの自動設定

プロジェクト内のファイルを開いた時、そのファイルのfiletypeに、予め設定したfiletypeを付加することができます。たとえば、.rbファイルを開いた時、通常はrubyというfiletypeが設定されますが、自動でrailsというfiletypeが付加されるように設定することが可能になります。ちなみに、Vimにおいて1つのバッファに複数のfiletypeを割り当てたい時は、それらを.(ドット記号)で連結します。この場合はruby.railsになるわけですね。

この設定はプロジェクト毎に変えることができます。方法は簡単で、Projectfileの中に、設定したいfiletypeをカンマ区切りもしくは改行区切りで記載するだけです。

ProjectLocal.vimの利用例

ProjectLocal.vimは、それ単体では利便性に直接影響することはない、薄い機能を持った低レイヤプラグインです。ここでは、ProjectLocalの便利な利用例をご紹介します。

プロジェクト内のファイルのみ検索するUniteコマンドを呼び出す

特定のプロジェクトに関するプログラミングを行っている時、そのプロジェクトに関係するファイルのみを対象に検索したいことがあると思います。そのような場合、gitなどのVCSで管理されているディレクトリはUnite.vimの標準機能で検索を行うことができますが、すべてのプロジェクトが必ずしもVCSで管理されているとは限りませんし、プロジェクト内でも更に細かくスコープを分けたいなどの要望があると思います。

そういった場合、ProjectLocal.vimにて任意の場所にProjectfileを配置することで、簡単にプロジェクト、もしくはプロジェクトの一部のファイルを検索することができるようになります。

.vimrc

nnoremap <silent> <Space>p  :<C-u>call Unite_project_files('-start-insert')<CR>
function! Unite_project_files(options)
  if exists('b:projectlocal_root_dir')
    execute ':Unite file_rec/async:' . b:projectlocal_root_dir . ' ' . a:options
  else
    echo "You are not in any project."
  endif
endfunction

Unite.vimのfirerec/asyncというソースは、引数として検索対象のディレクトリを取ることができます。これを利用して、`b:projectlocalroot_dir`が存在する場合はその値を引数として渡す関数を実装し、キーバインドに割り当てています。

プロジェクト毎に最適なUniteコマンドを呼び出す

同じキーバインドでも、状況によって最適な内容を実行してくれたら素敵です。ここでは、Unite.vimを例に、普段はディスク全体を対象にファイルを列挙するが、railsプロジェクトを開いている時にはunite-railsというRails用のUnite sourceを呼び出すといった設定を行ってみます。

Projectfile

rails

.vimrc

nnoremap <silent> <Space>j  :<C-u>Unite file_mru<CR>

function! s:unite_rails_init()
  nnoremap <buffer> <Space>j  :<C-u>Unite rails/model rails/controller rails/view rails/db rails/config rails/javascript rails/stylesheet rails/helper rails/mailer<CR>
endfunction

aug MyAutoCmd
  au FileType *rails* call s:unite_rails_init()
aug END

このように、<Space>jというキーバインドに対して、普段はfile_mruソースを呼び出すものの、railsのプロジェクトではunite-railsのソースを呼び出すといった設定を完結に記載することができました。AutoCmdのパターンは完全一致なので、*で囲むことでruby.railsなどといったfiletypeにもマッチする様な工夫を行っています。

まとめ

ProjectLocal.vimを利用することで、現在どのプロジェクトのファイルを開いているのか、プロジェクトの種類はなんなのか、プロジェクトのルートディレクトリはどこなのか、といった情報が提供されるようになり、プロジェクトに依存する固有の設定が格段に行い易くなりました。小さい実装ながらも強力なプラグインですので、皆さんもぜひお試し頂ければと思います。