Using embedded Perl interpreter

From Vim Tips Wiki

Jump to: navigation, search
Tip 140 Printable Monobook Previous Next

created 2001 · complexity advanced · author Benoit Cerrina · version 7.2


Writing scripts using the embedded Perl interpreter provides a powerful and fast scripting language (much faster than Vim scripts). Embedded Perl is available if the Vim :version command shows the +perl or +perl/dyn configuration options. This tip shows how to access embedded Perl scripts from Vim.

[edit] Defining a Perl function efficiently

Never embed complex Perl command in the body of a Vim function as this will be recompiled and evaled each time for a tremendous loss of time. Instead do it like this:

perl << EOF
sub mySub
{
  # some useful Perl stuff
}
EOF

function! MyFunction
  perl mySub "an argument", "another"
endfunction

[edit] Passing values between Vim and Perl

To pass a computed argument to your Perl sub use the Vim :execute command:

function! MyFunction
  execute "perl mySub " . aLocalVar . ", " b:aBufferLocalVar
endfunction

Another way to do this is to get the arguments from within the Perl function:

perl << EOF
sub mySub
{
  my $anArg=VIM::Eval("a:anArg");
  # some useful Perl stuff
}
EOF

function! MyFunction(anArg)
perl mySub
endfunction

To be able to return something from Perl:

perl << EOF
sub mySub
{
  my $anArg=VIM::Eval("a:anArg");
  # some useful Perl stuff
  VIM::DoCommand "let retVal=". aMeaningfullThingToReturn;
}
EOF

function! MyFunction(anArg)
perl mySub
if exists('retVal')
  return retVal
endif
endfunction

[edit] Debugging embedded Perl

It may be hard to debug your Perl sub since the output of the Perl compiler is lost in the middle of nowhere, and the debugger is not available.

To make sure you see all the warnings that Perl generates, make most warnings fatal by using something like this at the start of your Perl section:

use strict;
use warnings FATAL => 'all';
use warnings NONFATAL => 'redefine';

This way both compile-time and run-time warnings are propagated up to the Vim UI level. Redefinitions are allowed so that you can continually re-execute your .vimrc or other scripts from a single running Vim session.

It's possible to make sure the Perl code embedded in a Vim file is syntacticly correct when it is saved using script#3411.

You can get accurate run-time file and line number errors using script#3406.

It may be useful to write a fake Vim module with stub methods which will allow you to use the command line Perl interpreter to at least compile your program. You could make your stub smart enough to fake a Vim and use the debugger, for example:

package VIM;
use diagnostics;
use strict;
sub VIM::Eval
{
 $_ = shift;
 print "Eval $_\n";
 {
 return '^(?!!)([^\t]*)\t[^\t]*\t(.*);"\t([^\t]*)\tline:(\d*).*$' if (/g:TagsBase_pattern/);
 return $ARGV[0] if (/b:fileName/);
 return '$3' if (/g:TagsBase_typePar/);
 return '$1' if (/g:TagsBase_namePar/);
 return '$4' if (/g:TagsBase_linePar/);
 return 'Ta&gs' if (/s:menu_name/);
 return $ARGV[1] if (/g:TagsBase_groupByType/);
 die "unknown eval $_";
 }
}

sub VIM::Msg
{
 my $msg = shift;
 print "MSG $msg\n";
}

sub VIM::DoCommand
{
 my ($package, $filename, $line) = caller;
 my $command = shift;
 print "at $filename $line\n";
 print "DoCommand $command\n";
}

1;

Then you can copy your other Perl code in a separate file and add a use VIM; at the top, and you are set to debug.

[edit] Comments

For an example of the techniques described see script#100.


Personal tools