#!/u3/thesis/clipper/pl/perl
# A bash-like readline subroutine for perl
# Copyright 1990 by Khun Yee Fung (clipper@csd.uwo.ca)
# See the end of the program for warranty information
# $Source: /u3/thesis/clipper/own/lib/perl/RCS/readline.pl,v $
# $Id: readline.pl,v 1.1 90/05/05 12:32:17 clipper Exp $
sub prep_terminal {
  open(TTY, '/dev/tty');
  ioctl(TTY, $TIOCGETP, $foo);
  ($ispeed, $ospeed) = unpack('cc', $foo);

  $term = $ENV{'TERM'};

  if ($term eq "unknown") {
    print "Can't control unknown terminal\n";
    exit 0;
  }

  if (! &Tgetent($term)) {
    print "Can't find terminal: $term\n";
    exit 255;
  }
  $history = 30;
  $histart = 0;
  do initkeymap();
}

sub readline {
  $numc = 0;
  $totc = 0;
  $row = 1;
  $col = length($_[0]);
  $hiscount = $#history + 1;
  do set_cbreak(1);
  $read_string = "";
  $r_prompt = $_[0];
  print $_[0];
  $done = 0;
  $literal = 0;
  $meta = 0;
  while (! $done) {
    $c = getc(STDIN);
    if ($literal) {
      do insert($c);
      $literal = 0;
    }
    elsif ($meta) {
      $fun = $keymap[ord($c) + 128];
      do $fun($c);
      $meta = 0;
    }
    else {
      $fun = $keymap[ord($c)];
      do $fun($c);
    }
  }
  print "\n";
  &puthistory();
  do set_cbreak(0);
  $read_string . "\n";
}

sub rubout {
  local($len) = length($read_string) - $numc;
  if ($numc <= 0) { return; }
  &Tputs($TC{'le'}, 1, 'STDOUT');
  print substr($read_string, $numc, $len), " ";
  while ($len >= 0) {
    &Tputs($TC{'le'}, 1, 'STDOUT');
    $len--;
  }
  substr($read_string, $numc-1, 1) = "";
  $numc--;
  $totc--;
}

sub delete {
  local($len) = length($read_string) - $numc - 1;
  if ($numc == $totc) { return; }
  print substr($read_string, $numc+1, $len), " ";
  while ($len >= 0) {
    &Tputs($TC{'le'}, 1, 'STDOUT');
    $len--;
  }
  substr($read_string, $numc, 1) = "";
  $totc--;
}

sub moveleft {
  if ($numc <= 0) { return; }
  &Tputs($TC{'le'}, 1, 'STDOUT');
  $numc--;
}

sub moveright {
  if ($numc == $totc) { return; }
  &Tputs($TC{'nd'}, 1, 'STDOUT');
  $numc++;
}

sub beginofline {
  if ($numc <= 0) { return; }
  while ($numc > 0) {
    &Tputs($TC{'le'}, 1, 'STDOUT');
  }
  continue {
    $numc--;
  }
}

sub endofline {
  while ($numc != $totc) {
    &Tputs($TC{'nd'}, 1, 'STDOUT');
  }
  continue {
    $numc++;
  }
}

sub killline {
  &Tputs($TC{'ce'}, 1, 'STDOUT');
  substr($read_string, $numc, $totc - $numc) = "";
  $totc = $numc;
}

sub clearscreen {
  &Tputs($TC{'cl'}, 1, 'STDOUT');
  print "$r_prompt> ", $read_string;
}

sub unixkillline {
  while ($numc > 0) {
    &Tputs($TC{'le'}, 1, 'STDOUT');
    $numc--;
  }
  &Tputs($TC{'ce'}, 1, 'STDOUT');
  $read_string = "";
  $totc = 0;
}

sub puthistory {
  if ($#history == $history) {
    splice(@history, 0, 1);
    $histart++;
  }
  $history[$#history+1] = $read_string;
}

sub lasthist {
  if ($hiscount == 0) { return; }
  $hiscount--;
  do unixkillline();
  print $history[$hiscount];
  $read_string = $history[$hiscount];
  $totc = length($history[$hiscount]);
  $numc = $totc;
}

sub nexthist {
  if ($hiscount > $#history) { return; }
  do unixkillline();
  $hiscount++;
  print $history[$hiscount];
  $read_string = $history[$hiscount];
  $totc = length($history[$hiscount]);
  $numc = $totc;
}

sub complete_file {
  local($prefix) = $_[0];
  local($parts) = split('/', $prefix);
  local($cwd) = $pwd;

}

sub printhistory {
  local($index);
  for ($index = $histart; $index < $hiscount; $index++) {
    print $index, "  $history[$index - $histart]\n";
  }
}

sub insert {
  print $_[0]; substr($read_string, $numc, 0) = $_[0];
  $numc++;
  $totc++;
}

sub literal {
  $literal = 1;
}

sub meta {
  $meta = 1;
}

sub done {
  $done = 1;
}

sub nothing {
  print "In Nothing";
  1;
}

sub initkeymap {
  $#keymap = 256;
  $keymap[0] = 'nothing';
  $keymap[1] = 'beginofline'; # ^A
  $keymap[2] = 'moveleft';    # ^B
  $keymap[3] = 'nothing';
  $keymap[4] = 'delete';      # ^D
  $keymap[5] = 'endofline';   # ^E
  $keymap[6] = 'moveright';   # ^F
  $keymap[7] = 'nothing';
  $keymap[8] = 'rubout';      # ^H
  $keymap[9] = 'nothing';
  $keymap[10] = 'done';       # ^J
  $keymap[11] = 'killline';   # ^K
  $keymap[12] = 'clearscreen';# ^L
  $keymap[13] = 'done';# ^M
  $keymap[14] = 'nexthist';   # ^N
  $keymap[15] = 'nothing';
  $keymap[16] = 'lasthist';   # ^P
  $keymap[17] = 'literal';    # ^Q
  $keymap[18] = 'nothing';
  $keymap[19] = 'nothing';
  $keymap[20] = 'transpose';  # ^T
  $keymap[21] = 'unixkillline'; # ^U
  $keymap[22] = 'literal';    # ^V
  $keymap[23] = 'nothing';
  $keymap[24] = 'nothing';
  $keymap[25] = 'nothing';
  $keymap[26] = 'nothing';
  $keymap[27] = 'meta';       # ESC
  $keymap[28] = 'nothing';
  $keymap[29] = 'nothing';
  $keymap[30] = 'nothing';
  $keymap[31] = 'nothing';
  local($index);
  for ($index = 32; $index < 127; $index++) {
    $keymap[$index] = 'insert';
  }
  $keymap[127] = 'rubout';
  for ($index = 128; $index < 256; $index++) {
    $keymap[$index] = 'nothing';
  }
}
1;

# Copyright 1990 Khun Yee Fung <clipper@csd.uwo.ca>
#
# Permission to use, copy, modify, and distribute, this software and its
# documentation for any purpose is hereby granted without fee, provided that
# the above copyright notice appear in all copies and that both that
# copyright notice and this permission notice appear in supporting
# documentation, and that the name of the copyright holders be used in
# advertising or publicity pertaining to distribution of the software with
# specific, written prior permission, and that no fee is charged for further
# distribution of this software, or any modifications thereof.  The copyright
# holder make no representations about the suitability of this software for
# any purpose.  It is provided "as is" without express or implied warranty.
#
# THE COPYRIGHT HOLDER DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
# EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
# DATA, PROFITS, QPA OR GPA, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 
# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
