.vimrc基于实际的perl版本自动编译perl代码

时间:2014-01-14 22:30:10

标签: perl vim

我的.vimrc配置为在保存时自动编译我的Perl脚本。 然而,它很难编码为perl 5.14 我维护的一些脚本是5.8.8,其他脚本是5.16
我希望vim根据hashbang#中的版本编译我的代码!线
这可能吗?

这是我目前的.vimrc:

" check perl code with :make
"     by default it will call "perl -c" to verify the code and, if there are any errors, the cursor will be positioned in the offending line.
" errorformat uses scanf to extract info from errors/warnings generated by make.
"     %f = filename  %l = line number  %m = error message
" autowrite tells vim to save the file whenever the buffer is changed (for example during a save)
" BufWritePost executes the command after writing the buffer to file
" [F4] for quick :make
autocmd FileType perl set makeprg=/home/utils/perl-5.14/5.14.1-nothreads-64/bin/perl\ -c\ %\ $*
autocmd FileType perl set errorformat=%f:%l:%m
autocmd FileType perl set autowrite
autocmd BufWritePost *.pl,*.pm,*.t :make 

3 个答案:

答案 0 :(得分:1)

您必须根据shebang行动态更改'makeprg'中的Perl路径。例如:

:let perlExecutable = matchstr(getline(1), '^#!\zs\S\+')
:let perlExecutable = (empty(perlExecutable) ? '/home/utils/perl-5.14/5.14.1-nothreads-64/bin/perl' : perlExecutable) " Default in case of no match
:let &makeprg = perlExecutable . ' -c % $*'

你可以在FileType事件中调用它(可能封装在一个函数中),但是它不能正确检测到还没有shebang的新文件。或者将呼叫前置到autocmd BufWritePost *.pl,*.pm,*.t :make;每次保存后都会重新检测到。


PS:我希望:autocmd FileType中的所有~/.vimrc代替~/.vim/after/ftplugin/perl.vim中的所有:filetype plugin on(如果您有:setlocal)。此外,您应该使用:set代替(全局){{1}}。

答案 1 :(得分:0)

使用plenv更改项目的perl版本:plenv local 5.8.8

https://github.com/tokuhirom/plenv

您不必指定shebang和makeprg的路径。

答案 2 :(得分:0)

我找到了解决这个问题的另一种方法 我告诉vim执行另一个脚本,而不是将makeprg设置为perl可执行文件 该脚本确定适当的perl版本,然后使用-c
运行该版本 此解决方案可以扩展到其他脚本语言

在.vimrc中,更改:
    autocmd FileType perl set makeprg = / home / utils / perl-5.14 / 5.14.1-nothreads-64 / bin / perl \ -c \%\ $ *
于:
    autocmd FileType perl set makeprg = / home / username / check_script_syntax.pl \%\ $ *

#!/home/utils/perl-5.14/5.14.1-nothreads-64/bin/perl
use 5.014;    # enables 'say' and 'strict'
use warnings FATAL => 'all';
use IO::All;
my $script = shift;
my $executable;
for my $line ( io($script)->slurp ) {
    ##!/home/utils/perl-5.14/5.14.1-nothreads-64/bin/perl
    ##!/home/utils/perl-5.8.8/bin/perl
    if ( $line =~ /^#!(\/\S+)/ ) {
        $executable = $1;
    } elsif ( $script =~ /\.(pm)$/ ) {
        if ( $script =~ /(releasePatterns.pm|p4Add.pm|dftform.pm)$/ ) {
            $executable = '/home/utils/perl-5.8.8/bin/perl';
        } else {
            $executable = '/home/utils/perl-5.14/5.14.1-nothreads-64/bin/perl';
        }
    } else {
        die "ERROR:  Could not find #! line in your script $script";
    }
    last;
}
if ( $script =~ /\.(pl|pm|t)$/ ) {
    $executable .= " -c";
} else {
    die "ERROR:  Did not understand how to compile your script $script";
}
my $cmd = "$executable $script";
say "Running $cmd";
say `$cmd`;