No edit summary |
|||
Line 1: | Line 1: | ||
− | {{review}} |
||
{{TipImported |
{{TipImported |
||
|id=140 |
|id=140 |
||
Line 87: | Line 86: | ||
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. |
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. |
||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
− | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
− | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
− | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
− | |||
⚫ | |||
− | without using a VIM module stub (though that is still great for using the debugger). |
||
⚫ | |||
<pre> |
<pre> |
||
Line 246: | Line 181: | ||
The actual document delimiter doesn't have to be exactly 'EOF'. |
The actual document delimiter doesn't have to be exactly 'EOF'. |
||
+ | |||
⚫ | |||
⚫ | |||
+ | |||
⚫ | |||
⚫ | |||
+ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | |||
⚫ | |||
+ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | |||
⚫ | |||
+ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | |||
⚫ | |||
+ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
+ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
---- |
---- |
Revision as of 22:33, 23 December 2008
created October 17, 2001 · complexity advanced · author Benoit Cerrina · version 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.
Its also possible to make sure the perl code embedded in a vim file is syntacticly correct without using a VIM module stub. I use the following script:
#!/usr/bin/perl -w # Try to compile any perl code we can find embedded in the .vim file given # as an argument. use strict; use warnings; # Get the VIM code from the specified file. @ARGV == 1 or die "wrong number of arguments"; my $vim_file = $ARGV[0]; $vim_file =~ m/\.vim$/ or die "file '$vim_file' doesn't end in '.vim' (heresy)\n"; open(VIM_FILE, "<$vim_file") or die "couldn't open '$vim_file' for reading"; my @vim_code_lines = <VIM_FILE>; close(VIM_FILE) or die "couldn't close '$vim_file'"; # Get the perl chunks out of the vim file. my @perl_chunks; my @chunk_start_lines; my $in_perl_chunk = 0; my $chunk_delimiter; my $current_chunk = ""; my $current_line_number = 0; foreach ( @vim_code_lines ) { $current_line_number++; if ( ! $in_perl_chunk ) { if ( m/^\s*\:?\s*perl <<\s*(\w+)\s$/ ) { $in_perl_chunk = 1; $chunk_delimiter = $1; push(@chunk_start_lines, $current_line_number) } } else { if ( m/^$chunk_delimiter\s*$/ ) { $in_perl_chunk = 0; push(@perl_chunks, $current_chunk); $current_chunk = ""; } else { $current_chunk .= $_ } } } # Try to compile all the perl chunks. my $got_errors = 0; my $ii = 0; foreach ( @perl_chunks ) { # Add some goop to turn warnings fatal so we can postprocess them, # and to make sure we don't accidently execute the eval'ed code # (except for its BEGIN and UNITCHECK blocks, if any). my $compile_only_chunk = "use warnings FATAL => 'all'; return 1; " ."# This line was added by the check_embedded_perl utility.\n".$_; if ( not defined(eval($compile_only_chunk)) ) { my $errmsg = $@; my @errmsg_lines = split('\n', $errmsg); foreach ( @errmsg_lines ) { m/at \(eval \d+\) line (\d+)/ or (print STDERR "$_\n" and next); # We subtract one here because we added a line at the top... my $file_line = $1 - 1 + $chunk_start_lines[$ii]; s/at \(eval \d+\) line \d+/at $vim_file line $file_line/; print STDERR "$_\n"; $got_errors = 1; } } $ii++; } if ( $got_errors ) { print STDERR "$vim_file has embedded perl compilation errors.\n"; exit 1; } else { print "$vim_file embedded perl syntax OK\n"; exit 0; }
Its only argument is the name of the .vim file to process. It expects to find chunks of perl code in HERE-document style delimiters:
perl <<EOF sub foo {... EOF
The actual document delimiter doesn't have to be exactly 'EOF'.
Comments
For an example of the techniques described see script#100.
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
finally to be able to return something from perl
perl << EOF sub mySub { my $anArg=VIM::Eval("a:anArg"); #some usefull perl stuff VIM::DoCommand "let retVal=". aMeaningfullThingToReturn; } EOF function! MyFunction(anArg) perl mySub if exists('retVal') return retVal endif endfunction