PerlVision
view release on metacpan or search on metacpan
#!/usr/bin/perl
# -*-cperl-*-
#
# rap - Minimal text editor made using PerlVision
# Copyright (c) Ashish Gulhati <perlvision at hash.neo.email>
#
# $Id: bin/rap v1.508 Tue Feb 17 13:55:44 EST 2026 $
require 5.000;
use Curses;
use PerlVision;
package MY_Editor;
use Curses;
use PerlVision;
@ISA = (PerlVision::Editbox);
sub new {
my $type=shift; # MY_Editor (margin,text,index,filename);
my @params=(@_);
my ($maxheight,$maxwidth); getmaxyx($maxheight, $maxwidth);
my $self=new PerlVision::Editbox (1,3,$maxwidth-2,$maxheight-2,@params[0..2],0);
move ($maxheight-1,0);
attron (COLOR_PAIR(7));
addstr(" <Esc>-H for Help <Esc>-X for Menu");
$$self[12]=0; # Mark position
$$self[13]="INS TOP"; # status
$$self[14]=""; # status shown
$$self[15]=$params[3]; # filename
$$self[16]=""; # Kill buffer
$$self[17]=0; # Kill buffer clear toggle
($$self[15] =~/^~/) && (substr ($$self[15],0,1)=(getpwuid ($<))[7]);
bless $self;
}
sub statusbar {
my $self=shift;
my ($maxheight,$maxwidth); getmaxyx($maxheight, $maxwidth);
substr ($$self[13],0,3) = ($$self[11] ? "OVT" : "INS");
if ($$self[13] ne $$self[14]) {
move ($maxheight-1,$maxwidth-12);
addstr($$self[13]);
refresh();
$$self[14]=$$self[13];
}
}
sub cursor {
my $self=shift;
my $total = $#{$$self[9]};
my @ret=$self->PerlVision::Editbox::cursor();
if ($$self[8]==0) {
if ($total < 18) {
substr ($$self[13],5) = "ALL";
}
else {
substr ($$self[13],5) = "TOP";
}
}
else {
my $percent = $ret[1]/$total*100;
if ($percent == 100) {
substr ($$self[13],5) = "BOT";
}
else {
substr ($$self[13],5)=sprintf("%2d%",$percent);
}
}
return @ret;
}
sub help {
my $helptext="RAP is a very basic editor with emacs-like keybindings.
Keystroke sequences are presented in the Emacs format:
C-<key> means hold down 'CONTROL' and type <key>.
M-<key> means hold down 'ALT' and type <key>, or
alternately, press 'ESCAPE' and then press <key>.
Movement Commands:
Arrow keys, Page Up, Page Down should work. If not,
there are alternates:
C-f Move forward one character
C-b Move back one character
C-n Move down one line
C-p Move up one line
C-v Move down a page
M-v Move up a page
from the menu bar.
Two things that can be accessed only from the menu bar
are the RAP 'About Box' and the Preferences dialog.
_/_/_/ _/ _/_/_/
_/ _/ _/_/ _/ _/
_/_/_/ _/_/_/ _/_/_/
_/_/ _/_/_/_/ _/
_/ _/_/_/_/_/ _/
_/
_/
RAP Ain't Pico
Copyright (c) Ashish Gulhati";
my $help1 = new PerlVision::Viewbox (2,1,62,12,$helptext,0);
my $help2 = new PerlVision::Pushbutton (" OK ",28,13);
my ($maxheight,$maxwidth); getmaxyx($maxheight, $maxwidth);
my $help = new PerlVision::Dialog ("",int($maxwidth/2)-32,int($maxheight/2)-8,int($maxwidth/2)+32,int($maxheight/2)+8,1,1,
$help1,0,0,0,0,1,1,2,0,
$help2,1,2,2,1,2,3,1,0);
$help->activate;
}
sub options {
my $fun0 = new PerlVision::Static ("On Startup:",2,1,40,9);
my $fun1 = new PerlVision::Checkbox ("Mail president\@whitehouse.gov",2,3,0,1);
my $fun2 = new PerlVision::Checkbox ("Play a Rush song:",2,4,0,1);
my $fun3 = new PerlVision::Listbox ("Song",4,6,22,11,
"Force Ten",0,
"The Trees",0,
"Kid Gloves",0,
"Tom Sawyer",0,
"Tai Shan",0,
"2112",0,
"Red Sector A",0,
"Freewill",0,
"Anthem",0);
my $fun4 = new PerlVision::Radio ("Lo Volume",24,6,0,1);
my $fun5 = new PerlVision::Radio ("Hi Volume",24,7,1,1);
my $fun6 = new PerlVision::RadioG ($fun4, $fun5);
my $fun7 = new PerlVision::Pushbutton ("Yes",27,9);
my ($maxheight,$maxwidth); getmaxyx($maxheight, $maxwidth);
my $options = new PerlVision::Dialog ("",int($maxwidth/2)-20,int($maxheight/2)-6,int($maxwidth/2)+20,int($maxheight/2)+6,1,1,
$fun1,1,2,2,1,1,1,2,0,
$fun2,1,3,3,1,2,2,3,0,
$fun3,0,0,4,2,3,3,4,4,
$fun4,2,5,5,3,4,4,5,0,
$fun5,4,6,6,3,5,5,6,0,
$fun7,5,6,6,3,6,6,1,0,
$fun0,0,0,0,0,0,0,0,0);
$options->activate;
}
sub readfile {
my $filename=shift;
my $text="";
($filename =~/^~/) && (substr ($filename,0,1)=(getpwuid ($<))[7]);
open (INPUT, $filename) || return (0);
foreach (<INPUT>) {
$text.=$_;
}
close INPUT;
return (1,$text);
}
sub dirty {
my $self=shift;
my $dirty = ($$self[6] eq "\n") ? 0 : 1;
if ($$self[15]) {
my @origfile = readfile ($$self[15]);
if ($origfile[0]) {
$origfile[1].="\n";
($origfile[1] eq $$self[6]) && ($dirty = 0);
}
}
return $dirty;
}
sub findfile {
my $self=shift;
if ($self->dirty) {
return 0 unless PerlVision::PVD::yesno("Sure you want to abandon this file?",42,1);
}
my ($maxheight,$maxwidth); getmaxyx($maxheight, $maxwidth);
my $newfile = new PerlVision::Entryfield (2,$maxheight-1,50,0,"Find File:","");
$newfile->display; $newfile->activate;
my $filename = ($newfile->stat);
undef $newfile;
move ($maxheight-1,0);
attron (COLOR_PAIR(7));
addstr(" <Esc>-H for Help <Esc>-X for Menu ");
refresh();
if ($filename) {
my ($ret, $initial) = readfile ($filename);
if ($ret) {
$$self[6]=$initial."\n";
$$self[7]=0;
$$self[15]=$filename;
($$self[15] =~/^~/) && (substr ($$self[15],0,1)=(getpwuid ($<))[7]);
$self->justify(1);
$self->rfsh();
}
else {
PerlVision::PVD::message ("Error: Couldn't open file.",30,1);
}
}
$self->cursor;
refresh();
}
sub insertfile {
my $self=shift;
my ($maxheight,$maxwidth); getmaxyx($maxheight, $maxwidth);
my $newfile = new PerlVision::Entryfield (2,$maxheight-1,50,0,"Insert File:","");
$newfile->display; $newfile->activate;
my $filename = ($newfile->stat);
undef $newfile;
move ($maxheight-1,0);
attron (COLOR_PAIR(7));
addstr(" <Esc>-H for Help <Esc>-X for Menu ");
refresh();
if ($filename) {
my ($ret, $initial) = readfile ($filename);
if ($ret) {
substr ($$self[6],$$self[7],0)=$initial;
$self->justify(1);
$self->rfsh();
}
else {
PerlVision::PVD::message ("Error: Couldn't open file.",30,1);
}
}
$self->cursor;
refresh();
}
sub saveas {
my $self=shift;
my ($maxheight,$maxwidth); getmaxyx($maxheight, $maxwidth);
my $savefile = new PerlVision::Entryfield (2,$maxheight-1,52,0,"Save As:",$$self[15]);
$savefile->display; $savefile->activate;
my $filename = ($savefile->stat);
($filename =~/^~/) && (substr ($filename,0,1)=(getpwuid ($<))[7]);
undef $savefile;
move ($maxheight-1,0);
attron (COLOR_PAIR(7));
addstr(" <Esc>-H for Help <Esc>-X for Menu ");
refresh();
if ($filename) {
if (-e $filename) {
return unless (PerlVision::PVD::yesno ("File exists. Overwrite?",30,1));
}
$$self[15]=$filename;
$self->savefile;
}
$self->cursor;
refresh();
}
sub savefile {
my $self=shift;
if ($$self[15]) {
if ($self->dirty) {
open (SAVE, ">$$self[15]") || do {
PerlVision::PVD::message ("Error: Couldn't open file.",40,12);
return;
};
chop $$self[6];
print SAVE $$self[6];
close (SAVE);
$$self[6].="\n";
}
}
else {
$self->saveas();
}
}
sub killfile {
my $self=shift;
if ($self->dirty) {
return 0 unless (PerlVision::PVD::yesno ("Sure you want to abandon this file?",42,1));
}
$$self[6]="\n";
$$self[7]=0;
$$self[15]="";
$self->justify(1);
$self->rfsh();
return 1;
}
sub word {
my $self=shift;
my $dir=shift;
my $chars="";
if ($dir) {
$chars = substr ($$self[6],$$self[7]);
$chars =~ s/(\W*\w+).*/$1/s;
}
else {
$chars = substr ($$self[6],0,$$self[7]);
$chars =~ s/.*\W(\w)/$1/s;
}
return (2);
};
((!$key[1]) && ($key[0] eq "")) && do { # Save file
$self->savefile;
$self->cursor();
refresh();
return (2);
};
(($key[1]==200) && ($key[0] =~ /[sS]/)) && do { # Save file
$self->savefile;
$self->cursor();
refresh();
return (2);
};
((!$key[1]) && ($key[0] eq "")) && do { # Write file
$self->saveas;
$self->cursor();
refresh();
return (2);
};
(($key[1]==200) && ($key[0]=~/[Kk]/)) && do { # Abandon file
$self->killfile;
$self->cursor();
refresh();
return (2);
};
return (3,@key);
}
elsif ($key[1]==20) {
$self->wordforward;
return (2);
}
elsif ($key[1]==13) {
$self->wordback;
return (2);
}
elsif ($key[1]==16) {
$self->beginning;
return (2);
}
elsif ($key[1]==17) {
$self->end;
return (2);
}
elsif ((!$key[1]) && ($key[0] eq "")) {
$self->yank;
return (2);
}
else {
return 0;
}
}
package main;
use PerlVision;
sub readfile {
my $filename=shift;
my $text="";
($filename =~/^~/) && (substr ($filename,0,1)=(getpwuid ($<))[7]);
open (INPUT, $filename) || return (0);
foreach (<INPUT>) {
$text.=$_;
}
close INPUT;
return (1,$text);
}
$initial="";
$COPYRIGHT = "
RAP (RAP ain't Pico) Copyright (C) 1995, Ashish Gulhati.
A simple text editor for newcomers to Unix, with Emacs-like
keybindings to ease the upgrade path ;-)
";
$ABOUT="
_/_/_/ _/ _/_/_/
_/ _/ _/_/ _/ _/
_/_/_/ _/_/_/ _/_/_/
_/_/ _/_/_/_/ _/
_/ _/_/_/_/_/ _/
_/
_/
RAP Ain't Pico
(C) 1995, Ashish Gulhati
";
(($#ARGV >0) || ($ARGV[0] =~/^-/)) && die ($COPYRIGHT."Usage:\nrap [filename]\n\n");
if ($#ARGV == 0) {
($ret, $initial) = readfile ($ARGV[0]);
$ret || die ($COPYRIGHT."Couldn't open $ARGV[0]\n\n");
undef $ret;
}
init PerlVision;
my ($height,$width); getmaxyx($height, $width);
attron (COLOR_PAIR(1));
move (0,0); hline(" ",$width);
move (1,0); hline(" ",$width);
move (2,0); hline(" ",$width);
attron (COLOR_PAIR(3));
move (3,0); vline(" ",$height-2);
move (3,$width-1); vline(" ",$height-2);
move ($height-1,0); hline(" ",$width);
$menu = new PerlVision::Menubar("File",18,9,
"Open C-x C-f",0,
"Insert C-x i",0,
"Save C-x s",0,
"Save As C-x C-w",0,
"Abandon C-x k",0,
"Quit C-x C-c",0,
"Help M-h",0,
"About ",0);
$menu->add("Edit",20,8,
"Set Mark M-<Spc>",0,
( run in 1.469 second using v1.01-cache-2.11-cpan-6aa56a78535 )