news.utdallas.edu!tamsun.tamu.edu!cs.utexas.edu!zaphod.mps.ohio-state.edu!saimiri.primate.wisc.edu!ames!haven.umd.edu!uunet!mcsun!sunic!uts!id.dth.dk!ej Tue Jan 26 23:52:53 CST 1993
Article: 578 of comp.lang.perl
Xref: feenix.metronet.com comp.lang.perl:578
Newsgroups: comp.lang.perl
Path: feenix.metronet.com!news.utdallas.edu!tamsun.tamu.edu!cs.utexas.edu!zaphod.mps.ohio-state.edu!saimiri.primate.wisc.edu!ames!haven.umd.edu!uunet!mcsun!sunic!uts!id.dth.dk!ej
From: [email protected] (Erik Johansen (none#None))
#Subject: Re: editor scripts.
Message-ID: <[email protected]>
Keywords: editor editing scripts perl subroutine text
Organization: Department of Computer Science
References: <[email protected]>
Date: Fri, 22 Jan 1993 20:17:10 GMT
Lines: 380

[email protected] (Chaim Manaster) writes:

>The following is a repost in the hope that more people will respond
>this time. I have had many inquiries asking for the results of my
>posting, so I know there is a good deal of interest in the matter.
>This is quite logical as it is a very common need. Please respond
>if you can. Here it is once again.
>________________________________________________________________

>Does anybody out there in netland have any perl scripts that do
>simple full-screen editing on either ascii or wordprocessor format
>files that they wouldn't mind sharing? They don't have to be
>anything fancy, just plain vanilla editors (in fact they could be
>line oriented although full-screen would be preferred).
>Preferably, they would be in the form of a subroutine, but if they
>are not, I imagine that it is a minor modification for me to make.
>(I am obviously no pro at this stuff yet).

Well, well, I made up a require file for the times when you need to
edit a small text (Actual: Array of texts).

The idea is to pass an array to an &Edit call allowing the user
to do the desired changes to the text before continuing.
As this was a quick written up procedure, I am sure that a better
version will be available at some time.

Not so much talk, here it is:

------snap snap---- edit.pl -----------snap snap--------
#
# Edit module.
#
# Example of calling:
#
#   require "edit.pl";
#
#   @user_text = split(/\n/, <<TEST);
#   This is a test
#   of the editor module.
#   TEST
#
#   &Edit( *user_text );
#
#   print "Your text now:\n", @user_text;
#
#
# Works on UNIX, some changes will be needed to run on PC
# The lines in @user_test should not contain "\n".
#

$version = "1.0";

sub Edit
{
 local( *buf ) = @_;

 &Definitions unless defined %esctab;

 local($x_max, $y_max, $x, $y, $x_off, $editing) =  (80, 24, 0,0,0, 1);

 &Repaint;

 &stty_cbreak_noecho;
 while ( $editing )
  {
   $key = &GetKey;
   $key = $esctab{ $key } if defined $esctab{ $key };
   if ( length($key) == 1 &&  $key ge " " )
    {
     push(@buf, "") while ! defined $buf[$y];
     $buf[$y] .= " " x ($x - length($buf[$y])) if $x > length($buf[$y]);
     substr( $buf[$y], $x++, $overstrike ) = $key;
     print $key;
    }
   elsif ( length($key) > 1 && $key !~ /^\033/  )
    {
     eval $key;
     print $@ if $@;
    }
   else
    {
     print "\007"; # Ring bell
    }
  }
 &stty_nocbreak_echo;
 print $CLS;  # Clear screen (remove if you don't like this)
}

sub ShowCursor
{
 local( $repaint ) = 0;

 # Make full wraparound

 $y++, $x=0 if $x > length($buf[$y])+1;
 --$y, $x=length($buf[$y])+1 if $x < 0;
 $y = $#buf-$y   if $y < 0;  # If further up than first line we start at end
 $y = $y-$#buf-1 if $y > $#buf+1; # efter end we get back to start

 $y_off = $y, $repaint++ if $y < $y_off;
 $y_off = $y-$y_max+1, $repaint++ if $y > $y_off + $y_max;

 print $CSI, "23;70H ($y, $x)  "; # DEBUG -remove if you don't like this

 print $CSI, $y-$y_off+1, ";", $x+1, "H" unless $repaint; # Position cursor

 $repaint;  # Return true if repaint is needed
}

sub Repaint
{
 &ShowCursor; # First make sure that offset etc. are right
 print $CLS;
 local( $ry, $count ) = ($y_off, $y_max);
 print substr( $buf[$ry++], 0, $x_max ), "\n"
    while --$count && defined $buf[$ry];
 &ShowCursor;
}


sub GetKeyPart
{
local( $buf ) = "";
read(STDIN, $buf, 1);
$buf;
}

sub GetKey
{
 local( $buf ) = &GetKeyPart;
 if ( $buf eq "\033" )
  {
   $buf .= &GetKeyPart;
   $buf = "\033[" if $buf eq "\233";
   if ( $buf eq "\033[" )
    {
     $buf .= &GetKeyPart;
     $buf .= &GetKeyPart  while $buf =~ /[0-9;,]$/;
    }
  }
 $buf;
}

#-----------------------------------------------------------------------------
# Interactive Keyboard functions
#-----------------------------------------------------------------------------
sub Help
{
 print $CLS; # Clear scroll region and screen

 local( %help, $txt );
 foreach $val ( values %esctab )
  {
   next unless $val =~ /\#\s*(.+)\s*\-\s*/;
   $help{ $1 } = $';
  }

 format HELP_TOP =
Edit Version @<<<<<<<<<<<<<<<<<<<<<<<                          By Erik Johansen
            $version
                        HELP INFORMATION                            Page @|||
                                                                         $%

    Function key            Description
------------------------+------------------------------------------------------