你能告诉Vim打开一个不同于命令行上传递的文件或:e吗?

你能告诉Vim打开一个不同于命令行上传递的文件或:e吗?,vim,Vim,我想教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,但我不知道如何切换文件名 #!/u

我想教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;

考虑使用
ctags
。如果您能够在源代码上运行ctags流程,那么您应该能够做到:

vim -t File::Find
Vim提供了这方面的信息(
:help Vim
),我认为这可能远远超出了您要做的事情,允许您从一个源文件的中间跳转到另一个源文件中的原始函数定义。

:verbose au BufReadCmd
将告诉您其他类型的插件是如何做到这一点的(例如zip、netrw、Survitive)。示例输出将为您提供大量的想法:

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
zip BufReadCmd
zipfile:*调用zip#Read(展开(“”,1)
C:\Program Files\Vim\vim73\plugin\zipPlugin.Vim中的最后一组
*.zip调用zip#浏览(展开(“”)
C:\Program Files\Vim\vim73\plugin\zipPlugin.Vim中的最后一组
网络BufReadCmd
ftp://*exe“静默doau BufReadPre”.fnameescape(展开(“”)|调用netrw#Nread(2,展开(“”)| exe“静默doau BufReadPost”.fnameescape(展开(“”)
C:\Program Files\Vim\vim73\plugin\netrwPlugin.Vim中的最后一组
http://*exe“静默doau BufReadPre”.fnameescape(展开(“”)|调用netrw#Nread(2,展开(“”)| exe“静默doau BufReadPost”.fnameescape(展开(“”)
C:\Program Files\Vim\vim73\plugin\netrwPlugin.Vim中的最后一组
逃犯档案
*.git/索引
exe s:BufReadIndex()
C:\Program Files\Vim\vimfiles\plugin\sensitive.Vim中的最后一组
*.git/*索引*.lock
exe s:BufReadIndex()
C:\Program Files\Vim\vimfiles\plugin\sensitive.Vim中的最后一组
逃犯://**/[0-3]/**
exe s:BufReadIndexFile()文件
C:\Program Files\Vim\vimfiles\plugin\sensitive.Vim中的最后一组
逃犯://**/[0-9a-f][0-9a-f]*
exe s:BufReadObject()
C:\Program Files\Vim\vimfiles\plugin\sensitive.Vim中的最后一组

要手动打开这些文件,我建议使用
:find
:tabfind
命令,而不是分别使用
:edit
:tabedit
命令。这个 这两对命令的区别在于前者看起来 对于文件,不仅在当前路径中,而且在中列出的目录中
路径
选项(请参见
:帮助“路径”
)。如果添加Perl
@INC
目录 对于Vim
path
选项,您可以使用
:find
或快速查找模块文件
:tabfind
命令。例如,打开新选项卡页面并编辑
文件::在中查找可以键入的模块文件

:tabfind File/Find.pm
(您不必手动键入整个子路径,因为
:find
:tabfind
completion会考虑当前的
路径值。)

要使用
gf
^Wf
按模块名称自动定位这些文件,
^Wgf
,您需要另外更改(使用文件类型插件或 自动命令)为Perl文件提供以下选项

:set isfname+=:
:set suffixesadd+=.pm
:set includeexpr=substitute(v:fname,'::','/','g')
在这些选项之后(以及包含Perl
@INC
目录)设置后,您可以使用
gf
-like轻松打开模块文件
相应模块名称上的命令。

基于下面sehe的答案的惰性解决方案。当前的问题:

  • 它写入的文件是原始名称,而不是模组名称
  • 看起来设置文件类型的自动命令运行得太快,根本没有运行,或者很混乱
  • 它使用一个外部命令来完成这项工作
  • 它是针对我想要的咀嚼的(即,它不是通用的)
  • 当我有更多的停机时间时,我希望修复以上所有问题,并将其转换为插件

    .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 "";
    
    #/usr/bin/perl
    严格使用;
    使用警告;
    子猫{
    我的$file=shift;
    
    打开我的$fh,“这实际上可以通过vim的
    gf
    命令实现(转到文件)

    在代码中,如果看到类似File::Find的字符串,请将光标放在其上,并在正常模式下键入
    gf
    。对我来说,这会立即将我带到File::Find包


    我认为这是perl文件类型库的一部分,因为它在使用
    --noplugin

    执行vim时对我有效。这里有一个方法可以编辑指定文件以外的文件(在本例中,打开.css文件时编辑相应的.scss文件).

    你看过并抛弃了
    ctags
    ?@searlea不,我从来没有使用过
    ctags
    ,我想我可以说
    :帮助Vim中的ctags
    了解更多信息?是的……Vim在这方面有帮助。它有助于直接从函数引用跳到源定义等,而不仅仅是基于模块名。@searlea它看起来像是一种基于当前缓冲区中的文本执行命令的方法。它还需要一个索引,每次添加文件时都必须修改该索引(将字符串映射到命令)。这不是我真正想要的。我希望能够编辑任何文件,而不仅仅是当前文件中包含的文件。
    ctags
    的一个问题是,当我说
    :tabe Foo
    时得到的文件可能会根据我的环境而变化。这可能会通过一个足够复杂的命令得到修复,但我为什么不直接修改呢使用该命令?Vim已经知道Perl 5的大部分功能。我可以在模块名和h上点击
    gF