Reputation: 64939
I want to teach Vim how to open Perl 5 modules from names like File::Find
. I already have a wrapper script written in Perl 5 that handles the commandline (see below), but I would like to be able to say things like :tabe File::Find
and have it really execute :tabe /home/cowens/apps/perlbrew/perls/perl-5.14.0/lib/5.14.0/File/Find.pm
.
My current plan is to somehow use autocmd BufNewFile
and/or autocmd BufPreRead
, but I can't figure out how to switch the file name.
#!/usr/bin/perl
use strict;
use warnings;
my @files = @ARGV;
for my $file (@files) {
next if -f $file; #skip files that really exist
#convert from module name to module file
(my $module = $file) =~ s{::}{/}g;
$module .= ".pm";
#look for module in the include paths
for my $dir (@INC) {
my $candidate = "$dir/$module";
if (-f $candidate) {
$file = $candidate;
last;
}
}
}
#replace this script with vim
exec "vim", "-p", @files;
Upvotes: 4
Views: 823
Reputation: 11378
Here's a working example showing how to use the BufReadCmd autocmd to edit a file other than the one specified (in this case editing a corresponding .scss file when you open a .css file).
Upvotes: 0
Reputation: 29014
For opening those files manually I would recommend to use :find
and
:tabfind
commands instead of :edit
and :tabedit
respectively. The
difference between these two pairs of commands is that the former ones look
for a file not only in the current path, but also in directories listed in
path
option (see :help 'path'
). If you add your Perl @INC
directories
to Vim path
option, you can quickly locate a module file by using :find
or
:tabfind
commands. For example, to open a new tab page and edit
File::Find
module file in you can type
:tabfind File/Find.pm
(You don't have to type the whole sub-path manually since :find
and
:tabfind
completion takes the current path
value into account.)
To locating those files automatically by module name using gf
, ^Wf
,
^Wgf
, you need to additionally change (either with filetype plugin or
autocommand) the following options for Perl files.
:set isfname+=:
:set suffixesadd+=.pm
:set includeexpr=substitute(v:fname,'::','/','g')
After these options (as well as path
option containing Perl @INC
directories) are set, you can easily open module files using gf
-like
commands on corresponding module names.
Upvotes: 2
Reputation: 760
This may actually be possible with vim's gf
command (go to file).
In your code, if you see a string like File::Find, place your cursor over it and in normal mode type gf
. For me, that immediately takes me to the File::Find package.
I think this is native as part of the perl filetype libraries because it works for me when executing vim with --noplugin
.
Upvotes: 0
Reputation: 64939
Lazy solution based on sehe's answer below. Current problems:
When I have more downtime, I hope to fix all of the above and turn it into a plugin.
in .vimrc
autocmd BufReadCmd * r!cat_perl %
in cat_perl
#!/usr/bin/perl
use strict;
use warnings;
sub cat {
my $file = shift;
open my $fh, "<", $file
or die "could not open $file: $!";
print while <$fh>;
exit;
}
my $file = shift;
cat $file if -f $file;
#convert from module name to module file
(my $module = $file) =~ s{::}{/}g;
$module .= ".pm";
#look for module in the include paths
for my $dir (@INC) {
my $candidate = "$dir/$module";
cat $candidate if -f $candidate;
}
print "";
Upvotes: 0
Reputation: 8388
Consider using ctags
. If you're able to run the ctags process over your source code, you should be able to get to a point where you simply do:
vim -t File::Find
Vim has information about this (:help vim
) I think ctags probably goes well beyond what you're trying to do, allowing you to jump from the middle of one source file to the original function definition in another.
Upvotes: 4
Reputation: 393934
Doing
:verbose au BufReadCmd
Will tell you how other types of plugins do this (e.g. zip, netrw, fugitive). Sample output that should give you plenty of ideas:
zip BufReadCmd
zipfile:* call zip#Read(expand("<amatch>"), 1)
Last set from C:\Program Files\Vim\vim73\plugin\zipPlugin.vim
*.zip call zip#Browse(expand("<amatch>"))
Last set from C:\Program Files\Vim\vim73\plugin\zipPlugin.vim
Network BufReadCmd
ftp://* exe "silent doau BufReadPre ".fnameescape(expand("<amatch>"))|call netrw#Nread(2,expand("<amatch>"))|exe "silent doau BufReadPost ".fnameescape(expand("<amatch>"))
Last set from C:\Program Files\Vim\vim73\plugin\netrwPlugin.vim
http://* exe "silent doau BufReadPre ".fnameescape(expand("<amatch>"))|call netrw#Nread(2,expand("<amatch>"))|exe "silent doau BufReadPost ".fnameescape(expand("<amatch>"))
Last set from C:\Program Files\Vim\vim73\plugin\netrwPlugin.vim
fugitive_files BufReadCmd
*.git/index
exe s:BufReadIndex()
Last set from C:\Program Files\Vim\vimfiles\plugin\fugitive.vim
*.git/*index*.lock
exe s:BufReadIndex()
Last set from C:\Program Files\Vim\vimfiles\plugin\fugitive.vim
fugitive://**//[0-3]/**
exe s:BufReadIndexFile()
Last set from C:\Program Files\Vim\vimfiles\plugin\fugitive.vim
fugitive://**//[0-9a-f][0-9a-f]*
exe s:BufReadObject()
Last set from C:\Program Files\Vim\vimfiles\plugin\fugitive.vim
Upvotes: 5