はじめに
vim を利用していて、gf コマンドが思うように動かねえ!と嫌な気持ちになっている人向けです。
考え方
対象となるファイルパスを取得し、それにマッチするパスを project root から検索する
実装
set suffixesadd=.php,.js,.rb,.java,.json,.md,.as
nnoremap gf<CR> :<C-u>execute printf('edit %s', MyProjectRootFindFile(expand('<cfile>')))<CR>
nnoremap gfs :<C-u>execute printf('split %s', MyProjectRootFindFile(expand('<cfile>')))<CR>
nnoremap gfv :<C-u>execute printf('vsplit %s', MyProjectRootFindFile(expand('<cfile>')))<CR>
function! MyProjectRootFindFile(path)
return findfile(substitute(a:path, '^[\.\/]*', '', 'g'), MyProjectRoot(expand('%:p')) . '**;')
endfunction
function! MyProjectRoot(path)
let path = a:path
while path != '/'
for target in ['.svn', '.git', 'package.json', 'composer.json'] " etc...
let targetPath = printf('%s/%s', path, target)
if isdirectory(targetPath) || filereadable(targetPath)
return path " found project root.
endif
endfor
let path = fnamemodify(path, ':p:h:h')
endwhile
return expand('%:p:h') " not found project root.
endfunction