This could use some work, but it's quickly become an indispensable navigation tool for me. Place your cursor on any package name and type ',gm' (GotoModule -- assumes your leader is a comma) and you will automatically jump to that module.
Features:
let g:perl_path_to = {}
function! GotoModule(module)
let files = []
if !has_key(g:perl_path_to, a:module)
let g:perl_path_to[a:module] = []
let lib = split(system("perl -le 'print join $/ => @INC'"), "\n")
let module = substitute(a:module, '::', '/', 'g') . '.pm'
for path in lib
let path = path . '/' . module
if filereadable(path)
let g:perl_path_to[a:module] = g:perl_path_to[a:module] + [ path ]
endif
endfor
endif
let paths = g:perl_path_to[a:module]
if empty(paths)
echomsg("Module '".a:module."' not found")
else
let file = PickFromList('file', paths)
endif
execute "edit " . file
endfunction
function! PickFromList( name, list, ... )
let forcelist = a:0 && a:1 ? 1 : 0
if 1 == len(a:list) && !forcelist
let choice = 0
else
let lines = [ 'Choose a '. a:name . ':' ]
\ + map(range(1, len(a:list)), 'v:val .": ". a:list[v:val - 1]')
let choice = inputlist(lines)
if choice > 0 && choice <= len(a:list)
let choice = choice - 1
else
let choice = choice - 1
endif
end
return a:list[choice]
endfunction
There are a couple of bugs (such as still trying to edit a file if you cancel), but I'll work 'em out later. For now, you probably want the following added to your .vimrc to make those work:
" only works for Perl au! FileType perl :noremapgm :call GotoModule(expand(' ')) " make sure we pick up the colon as part of our keyword autocmd FileType perl setlocal iskeyword+=: " don't kill 'undo' in other buffers set hidden
I now use this thing constantly to quickly and easily navigate to any module listed in my code, even core modules. It's really sped things up for me.
Sounds good, but could you clarify what this does over Vim's supplied gf command? That's normally "goto file", but for Perl files it munges colons and @INC to DTRT. (Also for Ctrl+W f, which opens a new window with the file.
Re:gf
Ovid on 2008-06-06T09:52:57
Because it always puts you to the first incarnation of that file and this makes it very problematic for me. Due to the large size of our project, we have many locally patched modules (28 and growing) and if there is more than one version of a given module, I need to see this. As is often the case with vim, its functions don't quite do what I need.