諸事情によりプロジェクトの開発サーバが起動するまで時間がかかりそうだったので、unite の source 作りに取り組んでみた。
自分のプロジェクトは資源を CVS で管理し、各ユーザごとにタグ付けをしている。フォルダ構成としては、
root_directory ├ user A │ ├ ContextRoot │ │ ├ scripts │ │ └ css │ └ src │ ・・・ │ ├ libA │ └ libC ├ user B │ ├ ContextRoot │ │ ├ script │ │ └ css │ └ src │ ・・・ │ ├ libA │ └ libC ├ user C ・・・ ├ user D
といった感じで、root_directory に各ユーザごとの資源をチェックアウトして同じ構成で配置している。
このユーザ選択と、各下位フォルダへの移動を楽にできないかとやってみた。
if !exists('g:unite_project_root') let g:unite_project_root = '/' endif if !exists('g:unite_project_sub_dirs') let g:unite_project_sub_dirs = [] endif let s:unite_source = {} let s:unite_source.name = 'project' let s:unite_source.default_action = {'cdable' : 'cd'} let s:unite_source.action_table = {'src' : 'cd'} function! s:unite_source.gather_candidates(args, context) let list = map(split(globpath(g:unite_project_root ,'*'),'\n') , \ '[fnamemodify(v:val , ":t") , v:val]') return map(list, '{ \ "abbr" : v:val[0], \ "word" : v:val[1], \ "source" : "project", \ "kind" : "cdable", \ "action__directory": v:val[1], \ }') endfunction " action table let s:action_table = {} " cd src let s:action_table.src = {'description' : 'cd src'} function! s:action_table.src.func(candidate) execute 'cd ' . a:candidate.word . '/src' endfunction " cd ContextRoot let s:action_table.context_root = {'description' : 'cd ContextRoot'} function! s:action_table.context_root.func(candidate) execute 'cd ' . a:candidate.word . '/ContextRoot' endfunction " cd scripts let s:action_table.scripts = {'description' : 'cd scripts'} function! s:action_table.scripts.func(candidate) execute 'cd ' . a:candidate.word . '/ContextRoot/scripts' endfunction " cd jsp let s:action_table.jsp = {'description' : 'cd jsp'} function! s:action_table.jsp.func(candidate) execute 'cd ' . a:candidate.word . '/ContextRoot/jsp' endfunction " sub dir for s:v in g:unite_project_sub_dirs let s:action_table[s:v['action']] = {'description' : s:v['description']} function! s:action_table[s:v['action']].func(candidate, ...) dict if a:0 != 0 let self.path = a:1 return self.path else execute 'cd '. a:candidate.word . '/' . self.path endif endfunction call s:action_table[s:v['action']].func(0, s:v['path']) endfor let s:unite_source.action_table.cdable = s:action_table " source function! unite#sources#project#define() return s:unite_source endfunction
source 名は project なんだけど、一般的に想像されるような機能は全くない・・・。
Unite project
で、user A、user B・・・が候補として上がり、選択(Enter)するとそこへ cd する。選択(Enter)せずに Tab すると、各下位フォルダの候補(src,ContextRoot,scripts,jsp)が上がり、選択(Enter)するとそこへ cd する。それだけ。
外部設定(g:unite_project_sub_dirs)で、cd 先を設定できるようにもしてみた("sub dir のあたり)。本当はクロージャ(?)でカッコよく書きたかったけど、どうもうまくいかない(理解出来ない)ので無理やり dict を使って実装してみた。
頑張ってみたけど、unite の bookmark や、file で substitute 定義とか、vimshell で alias 切ったりした方が何倍もいい・・・な・・・orz
これとは別に
nnoremap <Leader><Leader> :Unite "Unite の後ろは半角空白がある
この定義が最近のお気に入り。leader は m なので、 mm の後にソース名を入力ってのがなかなかイイ。