sponsor Vim development Vim logo Vim Book Ad

advanced Tip #140: tip using embedded perl interpreter

 tip karma   Rating 34/13, Viewed by 7472 

created:   October 17, 2001 13:47      complexity:   advanced
author:   Benoit Cerrina      as of Vim:   6.0

When writing scripts using the embedded interpreter available if vim has the +perl ore +perl/dyn on
gives you access to this powerfull and FAST scripting language (especially fast compared to vim
scripts)  there are some gotchas.

First:
never embed complex perl command in the body of a vim function this will be recompiled and evaled
each time for a tremendous loss of time.instead to it like this

perl << EOF
sub mySub
{
  #some usefull perl stuff
}
EOF

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

to pass computed argument to your perl sub use the vim exec command
function! MyFunction
exec "perl mySub " . aLocalVar . ", " b:aBufferLocalVar
endfunction

It may be very hard to debug your perl sub since the output of the perl compiler is
somehow lost in the middle of nowhere and the debugger is not available.
When a compilation error occurs in your sub definition you'll get an error message
when you try to call it saying that the sub does not exists.
One thing which I have found very usefull is to write a fake VIM module with stub
methods which will allow you to use the command line perl interpretor to at least
compile your program.  You could make your stub smart enough to fake a vim
and use the debugger.  Here is a sample for such a fake module defining just
those method which I was using.

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;
my $filename;
my $line;
    ($package, $filename, $line) = caller;

my $command = shift;
print "at $filename $line\n";
print "DoCommand  $command\n";
}
1;


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

Good Vimming good perling.
Benoit
PS:
this tips are probably true for other scripting languages

 rate this tip  Life Changing Helpful Unfulfilling 

<<Alignment: =, LaTeX tables, declarations, etc | Add your function heading with a keystroke >>

Additional Notes

[email protected], October 19, 2001 14:27
For an example of the technics described see vimscript #100,
it is while developping this script that I found most of this.
[email protected], October 29, 2001 23:02
little changes to the tip

perl << EOF
sub mySub
{
  #some usefull perl stuff
}
EOF

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

to pass computed argument to your perl sub use the vim exec command
function! MyFunction()
exec "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 usefull perl stuff
}
EOF

function! MyFunction(anArg)
perl mySub
endfunction


finaly to be able to return something from perl
perl << EOF
sub mySub
{
  my $anArg=VIM::Eval("a:anArg");
  #some usefull perl stuff
  VIM::DoCmd "let retVal=". aMeaningfullThingToReturn;
}
EOF

function! MyFunction(anArg)
perl mySub
if exists('retVal')
return retVal
endif
endfunction
If you have questions or remarks about this site, visit the vimonline development pages. Please use this site responsibly.
Questions about Vim should go to [email protected] after searching the archive. Help Bram help Uganda.
    stats
Sponsored by Web Concept Group Inc. SourceForge.net Logo