Perl Programming


HOME HTML Tree Super Sorts Graphical df Search Subdirs CPU Hogs

INDEX

HOME
Content...
About this site...
HTML Tree
Super Sorts
Graphical df
Search Subdirs
CPU Hogs

Enhancing vi and vim with Perl


The following script demonstrates a little-used feature of "vi" under Unix, which permits a text filtering program to update the text currently being displayed. This is just one example of a Perl "macro" for vi; similar scripts can be written to perform just about any repetitive and tedious editing task.

When using vi, an external program can be used to affect the current text from the command mode by typing an exclamation point, a character to indicate which text will be affected, another exclamation point, and the name of the external program to execute.

The following perl script accepts as its first argument a string to replace. The following arguments are the replacement strings, which will be duplicated on each subsequent line. This is a very useful item for programming!

        #!/usr/bin/perl
        # Filter program to replace str1 in the next argc strings with 
        # the remaining arg replacements.  A good way to cut/paste a
        # series of similar lines in a source code project.
        
        $argcount = $#ARGV;
        if ($argcount < 2 )
        {  
            print "Usage: reps.pl search-string repl-string [repl-string] ...\n";
            exit 0;
        }
        
        $searchstr = shift;
        
        while ()
        {
            if ( $replstr = shift )
            { 
               # get new string if there is one 
            }
            else
            { last; }
            
            s/$searchstr/$replstr/g;
            print;
        }

(If your perl binary is not in /usr/bin/perl, you'll need to update the first line to the correct location.)

This script is very useful when the same line in a program needs to be duplicated several times, with only a variable name as the difference on each line. Suppose we need to copy several text strings from temporary variables into a structure. Each line would look like

strcpy( record.varname, varname );

The perl script above, which I call reps.pl, makes this task much easier. Simply use the vi commands "yy" and "p" to make as many copies of the given line as are needed. If there are five, we'd have

strcpy( record.varname, varname );
strcpy( record.varname, varname );
strcpy( record.varname, varname );
strcpy( record.varname, varname );
strcpy( record.varname, varname );

Now we can use reps.pl to replace "varname" with whatever variable names we need. Since there are five lines to update, we'd only need to move the text cursor to the first line to change, and then enter the following:

!5!reps.pl varname first_name last_name street city state

The above text will then become

strcpy( record.first_name, first_name );
strcpy( record.last_name, last_name );
strcpy( record.street, street );
strcpy( record.city, city );
strcpy( record.state, state );

Of course, it's much quicker to actually accomplish this editing than it is to explain it! Just about any editing task we perform frequently can be replaced by a perl script that does in-place editing.

Here's another example that creates a C++ comment block for a single line comment:


        #!/usr/local/bin/perl
        # boxcomment.pl
        #
        # Filter program to insert a "box_comment" into the current
        # source file around the provided text string.
        # 
        $argcount = $#ARGV;
        if ($argcount < 1 )
        {  
            print "Usage: boxcomment.pl comment_string \n";
            exit 0;
        }
        local( $writepipe )   = STDOUT;
        local( $printme )     = join( ' ', @ARGV );
        
        $printme = "\U$printme\E";
        
        $fullwidth = length( $printme ) + 8;
        
        print $writepipe "\n    ";
        foreach $i ( 1..$fullwidth ) { print $writepipe "/"; }
        print $writepipe "\n   //";
        foreach $i ( 1..$fullwidth-4 ) { print $writepipe " "; }
        print $writepipe "//\n  //  $printme  //\n //";
        foreach $i ( 1..$fullwidth-4 ) { print $writepipe " "; }
        print $writepipe "//\n";
        foreach $i ( 1..$fullwidth ) { print $writepipe "/"; }
        print $writepipe "\n\n";

Using this script, we can pause anywhere in our source file and insert a box comment. For example,

!!boxcomment.pl local function prototypes

results in the following:


         /////////////////////////////////
        //                             //
       //  LOCAL FUNCTION PROTOTYPES  //
      //                             //
     /////////////////////////////////

Well that's it for now. Enjoy.

The above text and scripts are Copyright 1997 © by Scott Chilcote.

HOME HTML Tree Super Sorts Graphical df Search Subdirs CPU Hogs