There are presently two packages which comprise this interface. They are:
The perl command may also appear in macros in vile's internal macro language, in which case the perl statements to execute must appear as a double quoted string to the perl command. The user is not prompted in this case.
Regardless, prior to execution, the global variable,
$Vile::current_buffer is set to an object of type Vile::Buffer
which represents the current buffer. The statements to be executed may
choose to act either directly or indirectly on the current buffer via this
variable or a suitable alias.
Normally, the cursor's current position, also referred to as dot, is left unchanged upon return from perl. It can be propagated back to a
viewable window by explicitly setting via the
Vile::Buffer::
dot method.
For purposes of reading from the buffer, there is always a region associated with the buffer object. By default, this region is the entire buffer. (Which means that potentially, the entire buffer may be acted upon.) This range may be restricted by the user in the normal way through the use of a range specification which precedes the perl command. E.g,
30,40perl @l = <$Vile::current_buffer>
will cause lines 30 thru 40 to be placed into the @l
array.
After entering the perldo command (preceded by an optional range
specification) on the :-line, the user will be prompted for some perl
statements to execute. These should usually be written to operate on the
$_
variable and leave the result in $_.
After pressing the Enter key, you'll be prompted for a set of options. The default options are -lpi
and will even be displayed as such. The -i switch causes the buffer to be edited in place. The -p switch causes the user supplied statements to be placed in a loop which
fetches lines one by one place them in $_
for each iteration
of the loop along with a trailing print which'll cause whatever's left in $_
to be put back into the
buffer. The -l switch causes an initial chomp to be done on each line after it is read. It
will also cause the output record separator to be set so that when
$_
is written back to the buffer, it will end up on a line of
its own.
For example, the command:
:25,30perldo $_ = sprintf("%4d",$lnum++) . $_ -lpi
will cause each line in between 20 and 30 inclusive to be prefixed with a
the number given by $lnum, which is also incremented for each line
processed. You'll probably want to initialize $lnum
to some
appropriate value via the perl command first, perhaps like this:
:perl $lnum = 142;
[I include this example, because this is something that I've wanted to do from time to time, when citing snippets of code which I want to discuss in an email message.]
statement(s)
in a loop which iterates of the
records (usually lines) of the region. Each record in the region will be
placed in $_.
Unlike the corresponding perl command line switch, it is not possible to specify a backup file. If you don't like what happens, just hit the 'u' key to undo it.
$_
after a record has
been read.
@F
array.
:1,$perldo s/a/b/g
@INC
path. For vile, the @INC
array has
been augmented to include $HOME/.vile/perl and /usr/local/share/vile. (This
latter path may differ depending upon your machine and configuration
options.) If you want to see what exactly what these paths are, just issue
the following command from within vile:
:perl print join ':', @INC[0,1]
Let us suppose that the following script is stored in $HOME/.vile/perl/number_lines.pl.
sub number_lines { my ($lnum, $width) = @_;
$lnum = 1 unless defined($lnum); $width = 4 unless defined($width);
$Vile::current_buffer->inplace_edit(1);
while (<$Vile::current_buffer>) { print $Vile::current_buffer ' ' x ($width - length($lnum) - 1), $lnum, ' ', $_; $lnum++; } }
1;
Note the trailing ``1;'' at the end. The reason for this is so that true is returned as the result of the script. If things are not done this way, the loading mechansim might flag an error. (All it needs to do is return a true value somehow.)
Assuming the above code has been placed in the file 'number_lines.pl', the following vile command may be used to load it:
:perl require 'number_lines.pl'
When writing a new script, I will often test it in the same editor session that I've created the script in. My script may have a bug in it and I'll fix it. In order to reload the script, you can do the following:
:perl do 'number_lines.pl'
Perl's builtin 'require' function wouldn't have worked to reload the file because it keeps track of files that have been loaded via this facility and refuses to load a file twice. The 'do' function on the other hand is a more general facility for executing the contents of a file and doesn't care how often it's called.
Caveat: Sometimes it's better to start with a clean slate, particularly if you've renamed your subroutines or if there are global variables involved. Just start a fresh copy of vile and start over.
Now to invoke our number_lines program, we do it as follows:
:perl number_lines(1)
It is also possible to use vile's builtin macro language to load perl modules and call them. The hgrep.pl module comes with the vile distribution. You may want to put this macro in your .vilerc file:
store-procedure hgrep perl "require 'hgrep.pl'" perl hgrep error-buffer $cbufname ~endm
Notice that there are two perl commands in the above macro. The first will make sure that the script hgrep.pl is loaded. The second will actually call the main subroutine of the script.
See also the Vile::register functions.
This is not exactly safe in all contexts. (It is easy to cause seg faults.) If you need access to some portion of vile that would lead you to want to use this subroutine, let me know and I will work on suitable facilities.
The optional WAITVAL indicates if the editor should wait for the next keystroke. When WAITVAL is false, undef will be returned if no input is ready.
Returns the user's response string. If the user aborts (via the use of the escape key) the query, an undef is returned.
Returns the user's response string. If the user aborts (via the use of the escape key) the query, an undef is returned.
Returns the user's response string. If the user aborts (via the use of the escape key) the query, an undef is returned.
Returns the user's response string. If the user aborts (via the use of the escape key) the query, an undef is returned.
When getting the selection, the buffer object that has the current selection is returned and its region is set to be the same region as is occupied by the selection. If there is no current selection, undef is returned.
When setting the selection, a buffer object must be passed in. The editor's selection is set to the region associated with the buffer object. If successful, the buffer object is returned; otherwise undef will be returned.
Examples:
$sel = Vile->selection_buffer->fetch; # Put the current selection in $sel
Vile->selection_buffer($Vile::current_buffer); # Set the selection to the region # contained in the current buffer
Vile::Buffer::set_selection is an alias for Vile::selection_buffer, but can only function as a setter. It may be used like this:
Vile->current_buffer->set_region('w')->set_selection; # set the selection to be the word # starting at the current position # in the current buffer
Vile->current_buffer->motion('?\/\*' . "\n") ->set_region('%') ->set_selection(); # set the selection to be the nearest # C-style comment above or at the # current position.
For the set methods, PAIRLIST should be a list of key => value pairs, where key is a mode name and value is an appropriate value for that mode. When used in an array context, the resulting key => value pairs are returned. (The value may be a different, but equivalent string than originally specified.) When used in an array context, either the package name or buffer object is returned (depending on how it was invoked) in order that the result may be used as the target of further method calls.
When one of the get forms is used, a list of modes should be supplied. When used in an array context, a list of key => value pairs is returned. When used in a scalar context, only one mode name may be supplied and the value associated with this mode is returned.
The methods in Vile::Buffer attempt to get the local modes associated with the buffer (falling back to the global ones if no specific local mode has been specified up to this point).
Note: Access to certain internal attributes such as the buffer name and file name are not provided via this mechanism yet. There is no good reason for this other than that vile does not provide access to these attributes via its set command.
When passed an argument, modifies value of the working message.
SUB may be given either as a string to eval, or a reference to a subroutine. If omitted, SUB defaults to NAME.
HELP provides a description of the subroutine for the [Binding List] functions.
An optional file to require may be given.
Example:
Vile::register grep => 'hgrep', 'recursive grep', 'hgrep.pl';
or
require 'hgrep.pl'; Vile::register grep => \&hgrep, 'recursive grep';
also
sub foo { print "foo" } Vile::register 'foo'; Vile::register bar => 'print "bar"'; Vile::register quux => sub { print "quux" };
*cb = \$Vile::current_buffer; Vile::register_motion 'my-forward-line-at-bol' => sub { $cb->dot((scalar $cb->dot) + 1, 0); };
Vile::register_oper 'my-delete-til' => sub { $cb->delete };
WATCHTYPE must be one of 'read', 'write', or 'except' and have the obvious meanings.
The callback should either be a string representing a vile command to execute (good luck) or (more usefully) a Perl subroutine reference.
A Vile::Buffer object may be viewed as a filehandle. Therefore, the usual sorts of methods for reading from and writing to filehandles will work as expected.
Example:
A word count program that you might invoke from your favorite shell could be written as follows:
#!/usr/local/bin/perl -w
my $words; while (<>) { $words += split; } print "$words words\n";
A programmer accustomed to the above, will find Vile's perl interface to be a comfortable one. Here is the above script modified slightly to count the words in the current buffer:
sub wc { my $words; while (<$Vile::current_buffer>) { $words+=split; } print "$words words"; }
When used in an array context, returns the rest of the lines (or portions thereof) in the current region.
The current region is either set with set_region or set by default for you when perl is invoked from vile. This region will either be the region that the user specified or the whole buffer if not user specified. Unless you know for sure that the region is set properly, it is probably best to set it explicitly.
After a line is read, DOT is left at the next location in the buffer at which to start reading. Note, however, that the value of DOT (which a convenient name for the current position in the buffer) is not propogated back to any of the users windows unless it has been explicitly set by calling dot (the method).
When the inplace_edit flag has been set via the inplace_edit method, text that is retrieved from the buffer is deleted immediately after retrieval.
Examples:
# Example 1: Put all lines of the current buffer into # an array
$Vile::current_buffer->set_region(1,'$$'); # Set the region to be the # entire buffer. my @lines = <$Vile::current_buffer>; # Fetch all lines and put them # in the @lines array. print $lines[$#lines/2] if @lines; # Print the middle line to # the status line
# Example 2: Selectively delete lines from a buffer
my $curbuf = $Vile::current_buffer; # get an easier to type handle # for the current buffer $curbuf->inplace_edit(1); # set the inplace_edit flag # so that lines will be deleted # as they are read
while (<$curbuf>) { # fetch line into $_ unless (/MUST\s+DELETE/) { # see if we should keep the line print $curbuf $_; # put it back if we should keep it } }
These attributes may be any of the following:
'color' => NUM (where NUM is the color number from 0 to 15) 'underline' 'bold' 'reverse' 'italic' 'hyper' => HYPERCMD (where HYPERCMD is a string representing a vile command to execute. It may also be a (perl) subroutine reference. 'normal'
Normal is a special case. It will override any other arguments passed in and remove all attributes associated with the region.
Returns the buffer object.
Note: The name of the buffer returned may be different than that passed in due some adjustments that may be done on the buffer name. (It will be trimmed of spaces and a length limit is imposed.)
Returns BUFOBJ if successful, otherwise returns undef.
This method may also be used to set the current buffer. When used in the form
$oldbuf->current_buffer($newbuf)
then $newbuf
will replace $oldbuf
in one of the
visible windows. (This only makes sense when $oldbuf
was
visible in some window on the screen. If it wasn't visible, it'll just
replace whatever buffer was last both current and visible.)
When used as a setter, the current buffer is still returned. In this case it will be the new buffer object which becomes the current buffer.
Note also that the current_buffer method is in both the Vile package and the Vile::Buffer package. I couldn't decide which package it should be in so I put it into both. It seemed like a real hassle to have to say
my $curbuf = Vile::Buffer->current_buffer
So instead, you can just say
my $curbuf = Vile->current_buffer;
current_buffer is also a variable, so you can also do it this way:
my $curbuf = $Vile::current_buffer;
If you want $main::curbuf (or some other variable) to be an alias to the current buffer, you can do it like this:
*main::curbuf = \$Vile::current_buffer;
Put this in some bit of initialization code and then you'll never have to call the current_buffer method at all.
One more point, since $Vile::current_buffer is magical, the alias above will be magical too, so you'll be able to do
$curbuf = $newbuf;
in order to set the buffer. (Yeah, this looks obvious, but realize that
doing the assignment actually causes some vile specific code to run which
will cause $newbuf
to become the new current buffer upon
return.)
Returns the buffer object if all went well, undef otherwise.
When supplied with one argument, the line number, dot is set to the beginning of that line. When supplied with two arguments, both the line number and offset components are set.
Either the line number or offset (or both) may be the special string '$' which represents the last line in the buffer and the last character on a line.
Often times, however, the special string '$$' will be more useful. It truly represents the farthest that it possible to go in both the vertical and horizontal directions. As a line number, this represents the line beyond the last line of the buffer. Characters inserted at this point will form a new line. As an offset, '$$' refers to the newline character at the end of a line. Characters inserted at this point will be inserted before the newline character.
Examples:
my $cb = $Vile::current_buffer; # Provide a convenient handle # for the current buffer.
$linenum = $cb->dot; # Fetch the line number at which dot # is located.
$cb->dot($cb->dot+1); # Advance dot by one line $cb->dot($cb->dot('$') - 1); # Set dot to the penultimate line of # the buffer.
$cb->dot(25, 6); # Set dot to line 25, character 6
($ln,$off) = $cb->dot; # Fetch the current position $cb->dot($ln+1,$off-1); # and advance one line, but # back one character.
$cb->inplace_edit(1); $cb->set_region(scalar($cb->dot), $cb->dot+5); @lines = <$cb>; $cb->dot($cb->dot - 1); print $cb @lines; # The above block takes (at # most) six lines starting at # the line DOT is on and moves # them before the previous # line.
Note: current_position is an alias for dot.
Example:
$word = $Vile::current_buffer->set_region('w')->fetch; # Fetch the next word and put it in $word
This flag determines whether a line is deleted after being read. E.g,
my $curbuf = $Vile::current_buffer; $curbuf->inplace_edit(1); while (<$curbuf>) { s/foo/bar/g; print; }
The <$curbuf> operation will cause one line to be read and deleted.
DOT will be left at the beginning of the next line. The print statment will
cause $_
to get inserted prior the the next line.
Setting this flag to true is very similar to setting the
$INPLACE_EDIT
flag (or $^I) for normal filehandles or using
the -i
switch from the command line.
Setting it to false (which is its default value) will cause the lines that are read to be left alone.
When used in an array context, returns a 4-tuple containing the beginning and ending positions. This 4-tuple is suitable for passing to set_region.
When used in a scalar context, returns the buffer object that it was called with.
In either an array or scalar context, if the motion string was bad, and undef is returned. Motions that don't work are okay, such as 'h' when you're already at the left edge of a line. But attempted ``motions'' like 'inewstring' will result in an error.
Example:
# The following code deletes the previous 2 words and then # positions the cursor at the next occurrence of the word # "foo".
my $cb = $Vile::current_buffer; $cb->set_region($cb->motion("2b"))->delete; # delete the previous two words
$cb->set_region("2b")->delete; # another way to delete the previous # two words
$cb->motion("/foo/"); # position DOT at the beginning of # "foo".
$cb->dot($cb->dot); # Make sure DOT gets propogated back. # (It won't get propogated unless # explicitly set.)
When no filename is supplied, an anonymous buffer is created. These buffer's will be named [unnamed-1], [unnamed-2], etc. and will not have a file name associated with them.
When a name is supplied as an argument to new or edit, a check is made to see if the name is the same as an already existing buffer. If so, that buffer is returned. Otherwise, the name is taken to be a file name. If the file exists, it is opened and read into the newly created buffer. If the file does not exist, a new buffer will be created with the associated file name. The name of the buffer will be based on the file name. The file will be created when the buffer is first written out to disk.
new and edit are synonyms. In each case, PKGNAME is Vile::Buffer. There is no difference between Vile::Buffer->new($fname) and $buf->new($fname). These two different forms are merely provided for convenience.
Example:
$Vile::current_buffer = new Vile::Buffer 'makefile'; # open makefile and make it visible # on the screen.
$abuf = new Vile::Buffer; # Create an anonymous buffer print $abuf "Hello"; # put something in it Vile->current_buffer($abuf); # make the anonymous buffer current # (viewable).
Vile->current_buffer($abuf->edit('makefile')); # Now makefile is the current # buffer $abuf->current_buffer(Vile::Buffer->new('makefile')); # Same thing
When STDERR or STDOUT are printed to, the output will be directed to the message line.
Examples:
print "Hello, world!"; # Print a well known greeting on # the message line. print $Vile::current_buffer "new text"; # put some new text in the current # buffer.
my $passbuf = new Vile::Buffer '/etc/passwd'; # Fetch the password file $passbuf->dot('$$'); # Set the position at the end print $passbuf "joeuser::1000:100:Joe User:/home/joeuser:/bin/bash # Add 'joeuser' to the this buffer Vile->current_buffer($passbuf); # Make it visible to the user.
Either the line number or offset (or both) may be the special string '$' which represents the last line in the buffer and the last character on a line.
Often times, however, the special string '$$' will be more useful. It truly represents the farthest that it possible to go in both the vertical and horizontal directions. As a line number, this represents the line beyond the last line of the buffer. Characters inserted at this point will form a new line. As an offset, '$$' refers to the newline character at the end of a line. Characters inserted at this point will be inserted before the newline character.
When used in an array context, returns a five element array with the start line, start offset, end line, end offset, and a string indicating the type of region (one of 'line', 'rectangle', or 'exact').
When used in a scalar context, returns the buffer object so that cascading method calls may be performed, i.e,
$Vile::current_buffer->set_region(3,4) ->attribute_cntl_a_sequences;
There is a special form of set_region which may be used as follows:
$Vile::current_buffer->set_region('j2w');
The above statement will set the region beginning at the current location of DOT and ending at the location arrived at by moving down one line and over two words. This may be viewed as a shorthand way of expressing the following (somewhat cumbersome) statement:
$Vile::current_buffer->set_region( $Vile::current_buffer->motion('j2w'));
Notes:
Returns the buffer object.