我想教Vim如何从像File::Find
这样的名字打开Perl 5模块。我已经有一个用Perl 5编写的包装脚本来处理命令行(见下文),但我希望能够说出像:tabe File::Find
这样的东西并让它真正执行:tabe /home/cowens/apps/perlbrew/perls/perl-5.14.0/lib/5.14.0/File/Find.pm
。
我目前的计划是以某种方式使用autocmd BufNewFile
和/或autocmd BufPreRead
,但我无法弄清楚如何切换文件名。
#!/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;
答案 0 :(得分:4)
否则
:verbose au BufReadCmd
会告诉你其他类型的插件是如何做到的(例如zip,netrw,fugitive)。样本输出应该给你很多想法:
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
答案 1 :(得分:3)
考虑使用ctags
。如果您能够在源代码上运行ctags进程,那么您应该能够达到以下目的:
vim -t File::Find
Vim有关于此的信息(:help vim
)我认为ctags可能远远超出您的尝试范围,允许您从一个源文件的中间跳转到原始函数定义在另一个。
答案 2 :(得分:2)
要手动打开这些文件,我建议使用:find
和
:tabfind
命令分别代替:edit
和:tabedit
。该
这两对命令之间的区别在于前者的外观
不仅适用于当前路径中的文件,还适用于中列出的目录中的文件
path
选项(请参阅:help 'path'
)。如果添加Perl @INC
目录
通过Vim path
选项,您可以使用:find
或快速找到模块文件
:tabfind
个命令。例如,要打开新标签页并进行编辑
您可以在File::Find
模块文件中键入
:tabfind File/Find.pm
(您不必手动输入整个子路径:find
和。{
:tabfind
完成时会考虑当前的path
值。)
使用gf
,^Wf
按模块名称自动查找这些文件,
^Wgf
,您需要另外更改(使用filetype插件或
autocommand)Perl文件的以下选项。
:set isfname+=:
:set suffixesadd+=.pm
:set includeexpr=substitute(v:fname,'::','/','g')
在这些选项之后(以及包含Perl path
的{{1}}选项
目录)设置,您可以使用@INC
轻松打开模块文件 - 就像
相应模块名称的命令。
答案 3 :(得分:0)
基于下面的答案的懒惰解决方案。目前的问题:
当我有更多停机时间时,我希望修复上述所有内容并将其转换为插件。
.vimrc
中的
autocmd BufReadCmd * r!cat_perl %
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 "";
答案 4 :(得分:0)
使用vim的gf
命令(转到文件)实际上可能是这样。
在您的代码中,如果您看到类似File :: Find的字符串,请将光标放在它上面并以正常模式键入gf
。对我来说,这会立即将我带到File :: Find包。
我认为这是perl文件类型库的一部分,因为它在使用--noplugin
执行vim时适用于我。
答案 5 :(得分:0)
这是一个working example showing how to use the BufReadCmd autocmd来编辑指定文件以外的文件(在这种情况下,在打开.css文件时编辑相应的.scss文件)。