<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">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: ej@id.dth.dk (Erik Johansen (none#None))
#Subject: Re: editor scripts.
Message-ID: &lt;ej.727733830@id.dth.dk&gt;
Keywords: editor editing scripts perl subroutine text
Organization: Department of Computer Science
References: &lt;1314@alsys1.aecom.yu.edu&gt;
Date: Fri, 22 Jan 1993 20:17:10 GMT
Lines: 380

manaster@yu1.yu.edu (Chaim Manaster) writes:

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

&gt;Does anybody out there in netland have any perl scripts that do
&gt;simple full-screen editing on either ascii or wordprocessor format
&gt;files that they wouldn't mind sharing? They don't have to be
&gt;anything fancy, just plain vanilla editors (in fact they could be
&gt;line oriented although full-screen would be preferred).
&gt;Preferably, they would be in the form of a subroutine, but if they
&gt;are not, I imagine that it is a minor modification for me to make.
&gt;(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 &amp;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/, &lt;&lt;TEST);
#   This is a test
#   of the editor module.
#   TEST
#
#   &amp;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 ) = @_;

  &amp;Definitions unless defined %esctab;

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

  &amp;Repaint;

  &amp;stty_cbreak_noecho;
  while ( $editing )
   {
    $key = &amp;GetKey;
    $key = $esctab{ $key } if defined $esctab{ $key };
    if ( length($key) == 1 &amp;&amp;  $key ge " " )
     {
      push(@buf, "") while ! defined $buf[$y];
      $buf[$y] .= " " x ($x - length($buf[$y])) if $x &gt; length($buf[$y]);
      substr( $buf[$y], $x++, $overstrike ) = $key;
      print $key;
     }
    elsif ( length($key) &gt; 1 &amp;&amp; $key !~ /^\033/  )
     {
      eval $key;
      print $@ if $@;
     }
    else
     {
      print "\007"; # Ring bell
     }
   }
  &amp;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 &gt; length($buf[$y])+1;
  --$y, $x=length($buf[$y])+1 if $x &lt; 0;
  $y = $#buf-$y   if $y &lt; 0;  # If further up than first line we start at end
  $y = $y-$#buf-1 if $y &gt; $#buf+1; # efter end we get back to start

  $y_off = $y, $repaint++ if $y &lt; $y_off; 
  $y_off = $y-$y_max+1, $repaint++ if $y &gt; $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
 {
  &amp;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 &amp;&amp; defined $buf[$ry];
  &amp;ShowCursor;
 }


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

sub GetKey
 {
  local( $buf ) = &amp;GetKeyPart;
  if ( $buf eq "\033" )
   {
    $buf .= &amp;GetKeyPart;
    $buf = "\033[" if $buf eq "\233";
    if ( $buf eq "\033[" )
     {
      $buf .= &amp;GetKeyPart;
      $buf .= &amp;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 @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;                          By Erik Johansen
             $version
                         HELP INFORMATION                            Page @|||
                                                                          $%

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

  format HELP =
     @&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;     ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
     $key,                 $help{$key}
~~                         ^&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;
                           $help{$key}
.
  $^ = HELP_TOP; # Set name of header format
  $~ = HELP; # Set name of format
  $= = $y_max - 2;    # Number of lines on page (minus trailer)
  $% = 0;
  $- = 0; # Page 0 line 0
  foreach $key ( sort keys %help )
   {
    write;
    next if $- &gt; 1; # unless end of page
    print &lt;&lt;SEP;
------------------------+------------------------------------------------------
SEP
    print 'Press any key to continue:';
    &amp;GetKey;
    print $CLS;
   }
  print &lt;&lt;SEP;
------------------------+------------------------------------------------------
SEP
  print "\n";
  &amp;Repaint;
 }

sub Up
 {
  $y--;
  $x=length($buf[$y])+1 if $x&gt;length($buf[$y])+1;
  &amp;ShowCursor &amp;&amp; &amp;Repaint;
 }

sub Down
 {
  $y++;
  $x=length($buf[$y])+1 if $x&gt;length($buf[$y])+1;
  &amp;ShowCursor &amp;&amp; &amp;Repaint;
 }

sub Left
 {
  $x--;
  &amp;ShowCursor &amp;&amp; &amp;Repaint;
 }

sub Right
 {
  $x++;
  &amp;ShowCursor &amp;&amp; &amp;Repaint;
 }


sub Return
 {
  splice( @buf, $y, 1, substr($buf[$y],0,$x), substr($buf[$y],$x));
  $y++; $x=0;
  &amp;Repaint;
 }

sub Key_Remove
 {
  $PasteBuffer = $buf[ $y ];
  undef $buf[ $y ];
  &amp;Repaint;
 }

sub Insert_Here
 {
  if ( defined($PasteBuffer) )
   {
    $buf[ $y ] = ""  unless defined $buf[ $y ];
    substr( $buf[ $y ], $x, $overstrike ) = $PasteBuffer;
    $y += length($PasteBuffer);
    &amp;Repaint;
   }
  else { print "\007"; } # Ring bell
 }


sub CtrlE
 {
  $x = (defined $buf[ $y ]) ? length($buf[ $y ]) : 0;
  &amp;ShowCursor &amp;&amp; &amp;Repaint;
 }

sub Home
 {
  $x = 0;
  &amp;ShowCursor &amp;&amp; &amp;Repaint;
 }

sub CtrlU   # Control-U - Erase to start of line
 {
  if ( $x &gt; 0 &amp;&amp; defined $buf[ $y ])   
   {
    $PasteBuffer = substr( $buf[ $y ], 0, $x);
    substr( $buf[ $y ], 0, $x) = "";
    &amp;Home;
    &amp;Repaint;
   }
  else { print "\007"; } # Ring bell
 }

sub BackSpace
 {
  if ( $x &gt; 0 &amp;&amp; defined $buf[ $y ] )
   {
    substr( $buf[ $y ], --$x, 1 ) = "";
    &amp;Repaint;
   }
  else { print "\007"; } # Ring bell
 }

sub PrevScreen
 {
  $y -= 12;
  &amp;Repaint;
 }

sub NextScreen
 {
  $y += 12;
  &amp;Repaint;
 }

sub DO
 {
  print "Add something here";
  &amp;Repaint;
 }

sub Definitions
 {
#  $SIG{'INT'} = 'IGNORE';

  $CSI    = "\033[";
  $CLS    = "\033[2J" . "\033[1;1H";
  $Attr   = "\033[0;7m";
  $NoAttr = "\033[0m";

  #
  # table of keyboard functions
  #
  %esctab =
   (
    "\033[A",   '&amp;Up;			# UP - Moves up',
    "\033[B",   '&amp;Down;			# DOWN - Moves down',
    "\033[C",   '&amp;Right;		# RIGHT - Moves right.',
    "\033[D",   '&amp;Left;			# LEFT - Moves left.',
    "\033[1~",  '&amp;FindFile;		# FIND - Find file ??',
    "\033[2~",  '&amp;Insert_Here;		# INSERT HERE - Insert contents of paste buffer here.',         
    "\033[3~",  '&amp;Key_Remove;		# REMOVE - Cuts field to paste buffer.',
    "\033[4~",  '&amp;Mark',		# SELECT - Mark position',
    "\033[5~",  '&amp;PrevScreen;		# PREV SCREEN - 12 lines up',
    "\033[6~",  '&amp;NextScreen;		# NEXT SCREEN - 12 lines down',
    "\033[17~", 'undef @buf;$editing=0;	# F6 - Quit.',
    "\033[21~", '$editing=0;		# F10 - Exit',
    "\033[24~", '&amp;SaveTo;',		# F12 - Save file as.
    "\033[25~", '&amp;Include;',		# F13 - Include file from.
    "\033[26~", '$overstrike = 1 - $overstrike;	# F14 - Shift between insert/overwrite',
    "\033[28~", '&amp;Help;			# HELP - Gives this Help screen.',
    "\033[29~", '&amp;DO;			# DO - Do something',
    "\001",     '&amp;Home;			# Ctrl-A - Move to start of line.',
    "\003",     'print "Control-C\n";exit;	# Ctrl-C - Quit program (no questions).',
    "\004",     '$editing=0;		# Ctrl-D - Exit program.',
    "\005",     '&amp;CtrlE;		# Ctrl-E - Move to end of line.',
    "\010",     '&amp;Home;			# Ctrl-H - Move to start of line.',
    "\012",     '&amp;Return; 		# &lt;CR&gt; - End currrent line',
    "\014",     '&amp;Repaint;',			# Ctrl-L - Repaints screen.',
    "\015",     ';			# &lt;LF&gt; - Ignore.',
    "\025",     '&amp;CtrlU;		# Ctrl-U - Delete to start of line.',
    "\177",     '&amp;BackSpace;		# BACKSPACE - Remove one character.',
  );
 }

sub stty_nocbreak_noecho
 {
  system "/bin/stty -cbreak -echo pass8 &lt;/dev/tty &gt;/dev/tty";
 }

sub stty_cbreak_noecho
 {
  system "/bin/stty cbreak -echo pass8 &lt;/dev/tty &gt;/dev/tty";
 }

sub stty_nocbreak_echo
 {
  system "/bin/stty -cbreak echo pass8 &lt;/dev/tty &gt;/dev/tty";
 }

"End of require - do not remove";    # My way of returning true

------snap here-------------------end of edit.pl-------------------------------




  Hope this helps
  Erik Johansen

---
    $txt=" ltrterhnuc--sor eep-\nkJ.a "; srand(53747414);
    for (1..26) { print substr($txt,rand 27,1); }  ### Is this a random write ?
---
Erik Johansen / Institute for Computer Science / Danish Technical University
ej@id.dth.dk
-- 
Erik Johansen / Institute for Computer Science / Danish Technical University
ej@id.dth.dk


</pre></body></html>