Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Ovid (2709)

  (email not shown publicly)
AOL IM: ovidperl (Add Buddy, Send Message)

Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.

Journal of Ovid (2709)

Friday June 06, 2008
03:11 AM

My Favorite Vim Function, ever!

[ #36602 ]

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.


  • Uses @INC to find the same modules Perl would find.
  • If only one version is found, automatically jumps to it.
  • If more than one version is found, you will be presented with a list to pick from.
  • Cached searches for better performance.
  • Highlighted "Module '$module' not found" if the module is not found.

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 ]

    let paths = g:perl_path_to[a:module]
    if empty(paths)
        echomsg("Module '".a:module."' not found")
        let file = PickFromList('file', paths)
    execute "edit " . file

function! PickFromList( name, list, ... )
    let forcelist = a:0 && a:1 ? 1 : 0

    if 1 == len(a:list) && !forcelist
        let choice = 0
        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
            let choice = choice - 1

    return a:list[choice]

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 :noremap <buffer> <leader>gm  :call GotoModule(expand('<cword>'))<cr>

" 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.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • 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.