#!/bin/sh
# this is SoftList_shar.03 (part 3 of SoftList 3.0 Beta)
# do not concatenate these parts, unpack them in order with /bin/sh
# file dotSoftListrc continued
#
touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$
if [ -s /tmp/s3_touch$$ ]
then
    TOUCH=can
else
    TOUCH=cannot
fi
rm -f /tmp/s3_touch$$
CurArch=3
if test ! -r s3_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s3_seq_.tmp || exit 1
echo "x - Continuing file dotSoftListrc"
sed 's/^X//' << 'SHAR_EOF' >> dotSoftListrc
X	&pushd(*main_dir_stack, *pushd_arg);
X	$tag_ref++;
X	if (! -f "tags") {
X		print "\nyou must make a tags file with ptags first\n";
X		&popd(*main_dir_stack);
X		last;
X	}
X
X	&sh($ENV{"EDITOR"}, "-t", "$alias_args[1]");
X	open (TAGFILE, "< tags");
X	while (<TAGFILE>) {
X		($routine, $filename, $ignore) = split (\' \',$_, 3);
X		last if ($routine =~ $alias_args[1]);
X	}
X	$req_name = $DIRS{"LIB"} . "/" . $filename . ".req". $tag_ref;
X	close (TAGFILE);
X	open (SOURCE_FILE, "< $filename") || warn "can\'t open source file:$!\n";
X	open (TMP_REQUIRE_FILE, "> $req_name")
X		|| warn "can\'t open source file:$!\n";
X	while (<SOURCE_FILE>) {
X		next unless /^sub $routine/o;
X		print TMP_REQUIRE_FILE;
X		last;
X	}
X	while (<SOURCE_FILE>) {
X		print TMP_REQUIRE_FILE;
X		last if /^}/o;
X	}
X	print TMP_REQUIRE_FILE "\n1;";
X	close(SOURCE_FILE);
X	close(TMP_REQUIRE_FILE);
X	require "$req_name";
X	unlink("$req_name");
X	&popd(*main_dir_stack);
X}',
X
X'unalias',	"{ # undefine an alias
X	undef(\$aliases{\$alias_args[1]});
X}",
X	
X'upcat',	"{ # force an update to the current Softlist catalog file
X	&force_dir_update;
X        &do_fork('&init_filenames', 'filenames_done', 'QUIT');
X}",
X
X'which',	'{ # find where one or more commands reside
X	shift @alias_args;
X	print TTYOUT "\n";
X	&which(@alias_args);
X}',
X
X); # end of %aliases main definition.
X
X#	Here's how you use previously defined aliases as building blocks
X#	for new ones.  Remember to use ';' in your basic definitions.
X
X$aliases{'cdl'} = $aliases{'cd'}.$aliases{'l'};
X$aliases{'pl'} = $aliases{'p'}.$aliases{'l'};
X$aliases{'ppl'} = $aliases{'pp'}.$aliases{'l'};
X
X# fill this in (slowly!) with your frequently used commands...
Xforeach $same_as_shell ('cat', 'cp', 'date', 'df', 'emacs', 'epoch',
X			'fortune',
X			'head',
X			'egrep', 'find', 'ftp', 'ls', 'ps', 'pwd', 'man', 'mv',
X			'now', 'rm',
X			'tail',
X			'tar', 'vi') {
X	$aliases{$same_as_shell} = $aliases{'basic_sh_cmd'};
X	$aliases{$same_as_shell} =~ s/shell_command/$same_as_shell/;
X}
X
X# menus within Softlist
Xforeach $menu_name ('add', 'batch', 'lookup', 'main') {
X	#$aliases{$menu_name} = '&'.$menu_name.'_menu';
X	$aliases{$menu_name} = 'eval $cmds{"'.$menu_name.'_menu"}';
X}
X
X# initialise main directory stack...
X@main_dir_stack = &fastcwd;
X
X# @cdpath for cd and pushd
X@cdpath = ('.', '..', '../..', $ENV{"HOME"}."/.dirs", '/usr');
X
X
X#	a sample of something you can set... if you want to defualt to a local
X#	data dir then change this...
X$data_dir = "DATA_remote";              # or "DATA_local"
X
X#	if you don't want to hear the bell or see your screen flash when
X#	the catalog file is ready, then uncomment this next line.
X$nobeep = 1;
X
X
X%dynamic_paths = (
X        '_SRC', '/usr/local/src',
X        '_X11_SRC', '/usr/local/src/X11:/usr/X11/src/clients',
X        '_BIN', '/usr/bin:/usr/local/bin:/usr/gnu/bin',
X        '_X11_BIN', '/usr/bin/X11:/usr/local/bin',
X        '_LIB', '/usr/lib:/usr/local/lib',
X        '_X11_LIB', '/usr/lib/X11:/usr/local/lib',
X        '_GIF', '/usr/local/images',
X        '_JPEG', '/usr/local/images',
X        '_XBM', '/usr/include/X11/bitmaps:/usr/local/images',
X        '_FLI', '/usr/local/flics',
X        '_FLC', '/usr/local/flics',
X        '_AU', '/usr/demo/SOUND/sounds:/usr/local/sounds',
X        '_NEWS', '/usr/spool/news',
X        '_NEWS_LIB', '/usr/lib/news',
X);
X
X#	you're free to define/reference any perl routines in this file.
X#	In the case of duplicate names, yours will override those in Softlist
X#	(except for any	that Softlist generates on the fly). 
X#	You should be free to use anything named user*.  You may want to
X#	declare a package and hang out there.  If you declare a package, be
X#	sure that you have "package main;" at the end of this file.
X#	You can core dump perl if you aren't careful here...add one thing
X#	at a time.  Measure twice, cut once.
X
Xpackage main;
X
X#	this line should always be here to return 1.
X1;
SHAR_EOF
echo "File dotSoftListrc is complete"
chmod 0644 dotSoftListrc || echo "restore of dotSoftListrc fails"
if [ $TOUCH = can ]
then
    touch -am 1205004592 dotSoftListrc
fi
set `wc -c dotSoftListrc`;Wc_c=$1
if test "$Wc_c" != "11160"
then echo original size 11160, current size $Wc_c;fi
# ============= editing.pl ==============
echo "x - extracting editing.pl (Text)"
sed 's/^X//' << 'SHAR_EOF' > editing.pl &&
X#
X#	start of command line editing functions
X#
X
X$cmds{"batch_file_input"} = '&batch_file_input';
X$cmds{"backward_char"} = '&backward_char';
X$cmds{"backward_delete_char"} = '&backward_delete_char';
X$cmds{"backward_word"} = '&backward_word';
X$cmds{"beginning_of_line"} = '&beginning_of_line';
X$cmds{"cli_error"} = '&cli_error';
X$cmds{"end_of_line"} = '&end_of_line';
X$cmds{"escape_prefix"} = '&escape_prefix';
X$cmds{"expand_known_word"} = '&expand_known_word';
X$cmds{"forward_char"} = '&forward_char';
X$cmds{"forward_delete_char"} = '&forward_delete_char';
X$cmds{"forward_word"} = '&forward_word';
X$cmds{"get_input"} = '&get_input';
X$cmds{"kill_backward_word"} = '&kill_backward_word';
X$cmds{"kill_forward_word"} = '&kill_forward_word';
X$cmds{"kill_line"} = '&kill_line';
X$cmds{"kill_to_beginning"} = '&kill_to_beginning';
X$cmds{"kill_whole_line"} = '&kill_whole_line';
X$cmds{"new_line"} = '&new_line';
X$cmds{"next_history"} = '&next_history';
X$cmds{"previous_history"} = '&previous_history';
X$cmds{"redraw_line"} = '&redraw_line';
X$cmds{"run_shell"} = '&run_shell';
X$cmds{"search_previous_history"} = '&search_previous_history';
X$cmds{"self_insert"} = '&self_insert';
X$cmds{"tab"} = '&tab';
X$cmds{"transpose"} = '&transpose';
X
X# support for field editing/CLI
X# keystrokes pass through %edit_cmds and %escape_cmds on their
X# way to different editing functions.
X
X# gawd this is so silly...
Xforeach $i (0..127) {
X    $edit_cmds{pack("c", $i)} = '&self_insert';
X}
X
X
X#	editing commands...
X$edit_cmds{pack("c", 0)} = '&set_mark';	# C-SP
X$edit_cmds{pack("c", 1)} = '&beginning_of_line';	# C-a
X$edit_cmds{pack("c", 2)} = '&backward_char';		# C-b
X$edit_cmds{pack("c", 4)} = '&forward_delete_char';	# C-d
X$edit_cmds{pack("c", 5)} = '&end_of_line';		# C-e
X$edit_cmds{pack("c", 6)} = '&forward_char';		# C-f
X$edit_cmds{pack("c", 9)} = '&tab';			# TAB
X$edit_cmds{pack("c", 10)} = '&new_line';		# NL
X$edit_cmds{pack("c", 11)} = '&kill_line';		# C-k
X$edit_cmds{pack("c", 12)} = '&redraw_line';		# C-l
X$edit_cmds{pack("c", 14)} = '&next_history';		# C-n
X$edit_cmds{pack("c", 16)} = '&previous_history';	# C-p
X$edit_cmds{pack("c", 18)} = '&redraw_line';		# C-r
X$edit_cmds{pack("c", 20)} = '&transpose';		# C-t
X$edit_cmds{pack("c", 21)} = '&kill_whole_line';		# C-u
X$edit_cmds{pack("c", 23)} = '&kill_region';             # C-w
X$edit_cmds{pack("c", 24)} = '&kill_to_beginning';	# C-x
X$edit_cmds{pack("c", 25)} = '&yank';			# C-y
X$edit_cmds{pack("c", 27)} = '&escape_prefix';		# ESC
X$edit_cmds{pack("c", 127)} = '&backward_delete_char';	# DEL
X$edit_cmds{pack("c", 8)} = '&backward_delete_char';	# BS
X
X#	The ESCape prefix...
X$escape_cmds{'!'} = '&run_shell';			# ESC-!
X$escape_cmds{'~'} = '&forward_char_flip';		# ESC-~
X$escape_cmds{'b'} = '&backward_word';			# ESC-b
X$escape_cmds{'c'} = '&capitalize_word';			# ESC-c
X$escape_cmds{'d'} = '&kill_forward_word';		# ESC-d
X$escape_cmds{'f'} = '&forward_word';			# ESC-f
X$escape_cmds{'l'} = '&downcase_word';			# ESC-l
X$escape_cmds{'p'} = '&search_previous_history';		# ESC-p
X$escape_cmds{'t'} = '&transpose_word';      		# ESC-t
X$escape_cmds{'u'} = '&upcase_word';      		# ESC-u
X$escape_cmds{pack("c", 127)} = '&kill_backward_word';	# ESC-DEL
X$escape_cmds{pack("c", 8)} = '&kill_backward_word';	# ESC-BS
X$escape_cmds{pack("c", 9)} = '&expand_known_word';	# ESC-TAB
X
X#	there's a lot to filename expansion, so we'll tuck this 
X#	off into a file of its own.  Once it's loaded this next line
X#	becomes: "$escape_cmds{pack("c", 27)} = '&expand_file_name'"
X$escape_cmds{pack("c", 27)} =
X	'&load_routine ("expand.pl", "expand")'; # ESC-ESC
X
X#	hmmm, recursive CLI's anyone?  maybe someday :-)
X# $escape_cmds{'@'} = '&eval_perl_expression';		# ESC-@
X
X$forward_char_func = "forward_char";
X
X#	get_input - print a prompt and get an entry
Xsub get_input {
X    local($prompt) = @_;
X
X    # this is a hack that lets you force feed a default answer that can be
X    # edited.  Should be particulary useful in the case of long pathnames
X    $| = 1;
X    if (defined($force_input)) {
X	print TTYOUT "\n";
X	$cur_line = $force_input;
X	$cur_len = length($cur_line);
X	$cur_pos = $cur_len;
X	&redraw_line;
X	undef($force_input);
X    } else {
X	print TTYOUT $prompt;
X    }
X    $keep_going = 1;
X    $in_digit = 0;
X    $dig_arg = 1;
X    while ($keep_going) {
X	read(TTYIN, $ans, 1);
X	&do_callbacks("KeyPress");
X	eval($edit_cmds{$ans});
X    }
X    1;
X}
X
X
X#	set_mark (C-space on console, C-shift-@ on terminal)
Xsub set_mark {
X    $mark_pos = $cur_pos;
X    1;
X}
X
X
X#	escape_prefix
Xsub escape_prefix {
X    read(TTYIN, $ans, 1);
X    eval($escape_cmds{$ans});
X    1;
X}
X
X#	tab
Xsub tab {
X    1;	# I don't feel like defining this yet, have at it...
X}
X
X
X#	previous_history - scroll backwards through current history stack
Xsub previous_history {
X    &kill_whole_line;
X    $| = 1;
X    $cur_line = pop @command_history;
X    unshift(@command_history, "$cur_line");
X    $cur_pos = $cur_len = length($cur_line);
X    print TTYOUT $cur_line;
X    1;
X}
X
X
X#	next_history - scroll forwards through current history stack
Xsub next_history {
X    &kill_whole_line;
X    $| = 1;
X    $cur_line = shift @command_history;
X    push(@command_history, "$cur_line");
X    $cur_pos = $cur_len = length($cur_line);
X    print TTYOUT $cur_line;
X    1;
X}
X
X
X#	search_previous_history - look for regexp in current history stack
X#
X#	this barely works, should work like ESC-p in tcsh
Xsub search_previous_history {
X    @foo = grep(/^$cur_line/, @command_history);
X    &kill_whole_line;
X    $cur_line = $foo[0];
X    $cur_pos = $cur_len = length($cur_line);
X    print TTYOUT $cur_line;
X    1;
X}
X
X
X
X#	expand_known_word
X#
X# this is a flaky start, but then, it's starting to work...
Xsub expand_known_word {
X    @current_line_words = split(/\W*\s+\W*/, substr($cur_line, 0, $cur_pos));
X    @expansions = sort grep(/^$current_line_words[$#current_line_words]/,
X			    (keys %known_words));
X    if ($#expansions == 0 && length($expansions[0]) > 1 &&
X	$expansions[0] !~ " ") {
X	# then tack onto current word...
X	$our_expansion = substr($expansions[0],
X			length($current_line_words[$#current_line_words]));
X
X	# have the self_insert routine do the work for us, keeping
X	# the current line in a known state
X	foreach $ans (split(//, $our_expansion)) {
X	    &self_insert;
X	}
X    } else {
X	if ($#expansions > 0) {
X	    foreach $possibilities (@expansions) {
X		print TTYOUT "\n$possibilities";
X	    }
X	    &redraw_line;
X	    
X	}
X    }
X    1;
X}
X
X
X#	new_line - handle end of line
Xsub new_line {
X    $keep_going = 0;
X    $mark_pos = 0;
X    $yank_str = '';
X    push(@command_history, ($cur_line));
X    foreach $word (split(/\W*\s+\W*/, $cur_line)) {
X	$known_words{$word}++;    # Increment the entry.
X    }
X    $cur_line = '';
X    $cur_pos = $cur_len = 0;
X    1;
X}
X
X
X#	beginning_of_line (C-a)
Xsub beginning_of_line {
X    if ($cur_pos > 0) {
X	print TTYOUT "\b" x $cur_pos;
X	$cur_pos = 0;
X    }
X    1;
X}
X
X
X#	redraw_line (C-r)
Xsub redraw_line {
X    $| = 1;
X    print TTYOUT "\n$prompt$cur_line";
X    print TTYOUT "\b" x ($cur_len - $cur_pos);
X    1;
X}
X
X
X#	backward_char (C-b)
Xsub backward_char {
X    if ($cur_pos > 0) {
X	$cur_pos--;
X	print TTYOUT "\b";
X    }
X    1;
X}
X
X
X#	forward_char (C-f)
Xsub forward_char {
X    if ($cur_pos < $cur_len) {
X	print TTYOUT substr($cur_line, $cur_pos, 1);
X	$cur_pos++;
X    }
X    1;
X}
X
X#	forward_char_upper
Xsub forward_char_upper {
X    substr($cur_line, $cur_pos, 1) =~ tr/a-z/A-Z/;
X    &forward_char;
X    1;
X}
X
X
X#	forward_char_lower
Xsub forward_char_lower {
X    substr($cur_line, $cur_pos, 1) =~ tr/A-Z/a-z/;
X    &forward_char;
X    1;
X}
X
X#	forward_char_flip - change existing case
Xsub forward_char_flip {
X    local($flipme) = substr($cur_line, $cur_pos, 1);
X
X    if ($flipme =~ /[a-z]/) {
X	substr($cur_line, $cur_pos, 1) =~ tr/a-z/A-Z/;
X    } elsif ($flipme =~ /[A-Z]/) {
X	substr($cur_line, $cur_pos, 1) =~ tr/A-Z/a-z/;
X    }
X    &forward_char;
X    1;
X}
X
X#	transpose (C-t)
Xsub transpose {
X    if ($cur_pos > 1) {
X	$last = substr($cur_line, $cur_pos - 1, 1);
X	$first = substr($cur_line, $cur_pos - 2, 1);
X	substr($cur_line, $cur_pos - 2, 1) = $last;
X	substr($cur_line, $cur_pos - 1, 1) = $first;
X	print TTYOUT "\b\b".substr($cur_line, $cur_pos - 2, 2);
X	&forward_char;
X    }
X    if ($cur_pos < 2) {
X	&forward_char;
X    }
X    1;
X}
X
X
X
X#	kill_forward_word (ESC-d)
Xsub kill_forward_word {
X    $yank_str = '';
X    $save_pos = $cur_pos;
X    &forward_word;
X    foreach $i (1..($cur_pos - $save_pos)) {
X	&backward_delete_char;
X    }
X    1;
X}
X
X
X#	kill_backward_word (ESC-DEL)
Xsub kill_backward_word {
X    $yank_str = '';
X
X    $save_pos = $cur_pos;
X    &backward_word;
X    foreach (1..($save_pos - $cur_pos)) {
X	&forward_delete_char;
X    }
X    1;
X}
X
X
X#	transpose_word
Xsub transpose_word {
X
X
X    # nope, not yet...
X
X    &forward_word;
X    &set_mark;
X    &backword_word;
X    &backword_word;
X    &kill_region;
X    $save_word = $yank_str;
X
X    $yank_str = '';
X    &set_mark;
X    &forward_word;
X    &kill_region;
X    foreach $ans (split(//, $save_word)) {
X	&self_insert;
X    }
X    &yank;
X    1;
X
X}
X
X
X#	case changing functions
X#
X#	These next three (upcase_word, downcase_word, and capitalize_word,
X#	were pretty easy to implement (half an hour).  They work with
X#	forward_char_{upper,lower}.  &forward_word now uses
X#	&$forward_char_func to call the appropriate function.
X
X#	upcase_word (ESC-u)
Xsub upcase_word {
X    local($save_ff) = $forward_char_func;
X    $forward_char_func = "forward_char_upper";
X    &forward_word;
X    $forward_char_func = $save_ff;
X    1;
X}
X
X
X#	downcase_word (ESC-l)
Xsub downcase_word {
X    local($save_ff) = $forward_char_func;
X    $forward_char_func = "forward_char_lower";
X    &forward_word;
X    $forward_char_func = $save_ff;
X    1;
X}
X
X#	capitalize_word (ESC-c)
Xsub capitalize_word {
X    &forward_word; &backward_word; # yes, this is silly, we're trying to
X				   # get to the first char of a word reliably
X				   # and I don't feel like writing a special
X				   # case just for that...
X    &forward_char_upper;
X    &downcase_word;		# all hail tcsh!
X    1;
X}
X
X
X#	forward_word (ESC-f)
Xsub forward_word {
X    if (substr($cur_line, $cur_pos, 1) =~ /\W/) {
X	for (;;) {
X	    last if ($cur_pos == $cur_len);
X	    last if (substr($cur_line, $cur_pos, 1) =~ /\w/);
X	    &$forward_char_func;
X	}
X    }
X    
X    for (;;) {
X	last if ($cur_pos == $cur_len);
X	last if (substr($cur_line, $cur_pos, 1) =~ /\W/);
X	&$forward_char_func;
X    }
X    1;
X}
X
X
X#	backward_word (ESC-b)
X#
X#	gee, there's more to this one than I thought there would be.  Not
X#	for the squeamish
Xsub backward_word {
X    # never mind, we're at the beginning of the line
X    if ($cur_pos == 0) {
X	return 1;
X    }
X
X    # end of line?
X    if ($cur_pos == $cur_len) {
X	&backward_char;
X    }
X
X    # on the beginning of a word?
X    if ((substr($cur_line, $cur_pos, 1) =~ /\w/) &&
X	(substr($cur_line, $cur_pos - 1 , 1) =~ /\W/)) {
X	&backward_char;
X    }
X
X    # head backwards to the previous word...
X    if (substr($cur_line, $cur_pos, 1) =~ /\W/) {
X	while ($cur_pos >= 1 &&
X	       (substr($cur_line, $cur_pos - 1, 1) =~ /\W/)) {
X	    &backward_char;
X	}
X    }
X
X    # work backwards through a word
X    while ($cur_pos >= 1 && (substr($cur_line, $cur_pos - 1, 1) =~ /\w/)) {
X	&backward_char;
X    }
X    1;
X}
X
X
X#	kill_whole_line (C-u)
Xsub kill_whole_line {
X    &beginning_of_line;
X    &kill_line;
X    1;
X}
X
X
X#	watch out, this is likely to get remapped in 4.0 so that we have
X#	a ^X prefix...still mulling that one over (regions)
X
X#	kill_to_beginning (C-x)
Xsub kill_to_beginning {
X    $yank_str = '';
X    $save_pos = $cur_pos;
X    &beginning_of_line;
X    foreach $i (1..($save_pos - $cur_pos)) {
X	&forward_delete_char;
X    }
X    1;
X}
X
X
X#	kill_line (C-k)
Xsub kill_line {
X    if ($cur_len > 1) {
X	$yank_str = $cur_line;
X	$cur_line = substr($cur_line, 0, $cur_pos);
X	print TTYOUT " " x ($cur_len - $cur_pos);
X	print TTYOUT "\b" x ($cur_len - $cur_pos);
X	$cur_len = $cur_pos;
X    }
X    1;
X}
X
X#	kill_region (C-w)
Xsub kill_region {
X    $yank_str = '';
X    if ($mark_pos == $cur_pos) {
X	&forward_delete_char;
X    } elsif ($mark_pos > $cur_pos) {
X	foreach $i (1..($mark_pos - $cur_pos)) {
X	    &forward_delete_char;
X	}
X    } elsif ($mark_pos < $cur_pos) {
X	foreach $i (1..($cur_pos - $mark_pos)) {
X	    &backward_delete_char;
X	}
X    }
X    1;
X}
X
X
X#	forward_delete_char (C-d)
Xsub forward_delete_char {
X    if ($cur_len > $cur_pos) {
X	$yank_str = $yank_str . substr($cur_line, $cur_pos, 1);
X	$save = substr($cur_line, $cur_pos + 1);
X	$cur_len--;
X	$cur_line = substr($cur_line, 0, $cur_pos).$save;
X	print TTYOUT $save." ";
X	print TTYOUT "\b" x ($cur_len - $cur_pos + 1);
X    }
X    1;
X}
X
X
X#	end_of_line (C-e)
Xsub end_of_line {
X    if ($cur_len > $cur_pos) {
X	print TTYOUT substr($cur_line, $cur_pos);
X	$cur_pos = $cur_len;
X    }
X    1;
X}
X
X
X#	run_shell (ESC-!)
Xsub run_shell {
X    print TTYOUT "\npushing shell, \"exit\" will get you back here...\n";
X    &quick_shell;
X    &redraw_line;
X}
X
X
X#	backward_delete_char (DEL or BS)
Xsub backward_delete_char {
X    if ($cur_pos > 0) {
X	$yank_str =  substr($cur_line, $cur_pos - 1, 1) . $yank_str;
X	if ($cur_len > $cur_pos) { #save rest of line...
X	    $save = substr($cur_line, $cur_pos);
X	}
X	$cur_pos--;
X	$cur_len--;
X	$cur_line = substr($cur_line, 0, $cur_pos);
X	print TTYOUT "\b \b";
X	if ($cur_len > $cur_pos) { #save rest of line...
X	    substr($cur_line, $cur_pos, 1) = $save;
X	    print TTYOUT substr($cur_line, $cur_pos)." ";
X	    print TTYOUT "\b" x ($cur_len - $cur_pos + 1);
X	}
X    }
X    1;
X}
X
X
X#	self_insert
Xsub self_insert {
X    $| = 1;
X    substr($cur_line, $cur_pos, 0) = $ans;
X    print TTYOUT substr($cur_line, $cur_pos);
X    $cur_pos++;
X    $cur_len++;
X    if ($cur_len > $cur_pos) {
X	print TTYOUT "\b" x ($cur_len - $cur_pos);
X    }
X    1;
X}
X
X#	added Sun Mar 15 17:12:08 PST 1992
X#	cli_error - use to print out quick helpful messages
Xsub cli_error {
X    local($cli_err_msg) = @_;
X
X    foreach $ans (split(//, $cli_err_msg)) {
X	&self_insert;
X    }
X    sleep 1;
X    foreach $ans (split(//, $cli_err_msg)) {
X	&backward_delete_char;
X    }
X    1;
X}
X
Xsub yank {
X    foreach $ans (split(//, $yank_str)) {
X	&self_insert;
X    }
X    1;
X}
X
X#
X#	end of command line editing functions
X#
X1;
SHAR_EOF
chmod 0644 editing.pl || echo "restore of editing.pl fails"
if [ $TOUCH = can ]
then
    touch -am 1205044792 editing.pl
fi
set `wc -c editing.pl`;Wc_c=$1
if test "$Wc_c" != "14023"
then echo original size 14023, current size $Wc_c;fi
# ============= eval_perl.pl ==============
echo "x - extracting eval_perl.pl (Text)"
sed 's/^X//' << 'SHAR_EOF' > eval_perl.pl &&
X
X;#	eval_perl_expression - provide a perl based CLI
X;#
X;#	this gives you lots of functionality.  You can enter perl statements,
X;#	make aliases to run unix commands, recall previous commands, edit
X;#	them, push menus, and more.  It's a good start, now I just have to
X;#	completely rewrite it!  Note that &get_input() actually does a lot
X;#	of the work.  BUG: if you push a CLI, and then push a menu of any
X;#	sort, and then push another CLI, your history gets clobbered.
X
X$cmds{'eval_perl_expression'} = '&eval_perl_expression';
Xif (! defined($production)) {
X    $keep_looping = 1;
X} else {
X    $keep_looping = 0;
X}
X
Xsub eval_perl_expression {
X    push(@menu_stack, "&eval_perl_expression");
X    print TTYOUT "\n";
X    @command_history = @perl_history;
X    $perl_exp = "?"; # put something there to get into the loop
X    while ($perl_exp !~ /^$/ || $keep_looping) {
X	($perl_exp =~ /^$/) && break;
X	print TTYOUT "\n";
X	&get_input("perl $dir_prompt>> ");
X	$perl_exp = $command_history[$#command_history];
X	@alias_args = split(' ', $perl_exp);
X	
X	;# ok, this has room for vast improvement.  Aliases are
X	;# defined in your ~/.SoftListrc
X	if ($aliases{$alias_args[$[]}) {
X	    eval $aliases{$alias_args[$[]};
X	    
X	    ;# this funny line here seems to make menus and the
X	    ;# CLI work ok if they are interspersed...however..
X	    ;# if you use an alias to call a menu, and then push
X	    ;# another CLI, your history can be clobbered.  This
X	    ;# isn't a biggie to deal with right now, but it's
X	    ;# there.
X	    
X	    $perl_exp = "?";
X	} else {
X	    if ($perl_exp !~ /^$/) {
X		print TTYOUT "\n";
X		if ($perl_exp =~ /^!/) {
X		    system(substr ($perl_exp, 1));
X		} else {
X		    eval $perl_exp;
X		    print TTYOUT $@;
X		}
X	    }
X	}
X    }
X    @perl_history = @command_history;
X    &pop_level;
X    1;
X}
X1;
SHAR_EOF
chmod 0644 eval_perl.pl || echo "restore of eval_perl.pl fails"
if [ $TOUCH = can ]
then
    touch -am 1205142992 eval_perl.pl
fi
set `wc -c eval_perl.pl`;Wc_c=$1
if test "$Wc_c" != "1807"
then echo original size 1807, current size $Wc_c;fi
# ============= expand.pl ==============
echo "x - extracting expand.pl (Text)"
sed 's/^X//' << 'SHAR_EOF' > expand.pl &&
X;#	-*-Perl-*-
X;#
X;#	expand.pl - filename and variable expansion for SoftList, version 3.0
X;#
X;#	Daniel Smith, dansmith@autodesk.com
X;#
X;#	There's so much going on with filename and variable expansion that
X;#	this deserves its own file, and its own special brand of insanity :-)
X;#
X;#	There are many cases with filename expansion:
X;#
X;#	1) an easy one.  someone types "cd pe<expand>".  Expanding in the
X;#	current directory is straightforward.
X;#
X;#	2) introduction of special characters.  someone
X;# 	types "cd ./pe<expand>".
X;#	As soon as we see '.', we are either dealing with a hidden file or
X;#	directory, or, a relative path of some sort.
X
X
X;# likely that I'll rewrite this from scratch..Wed Nov  4 11:26:07 PST 1992
X
X
X;# Sun Feb 16 13:42:46 PST 1992
X;#
X;# I'm currently unhappy with this, and am going to leave it for a little
X;# while and come back to it.  It's a mess.
X;#
X;# First off, the current word needs to be narrowed down better.  It should
X;# not matter where the cursor is (beginning, middle, end).  If the cursor
X;# is in the word, then we should find the whole word...
X;#
X;# The first_pass code is pretty good.  It narrows down all of the cases
X;# I can think of at this time.  Now I just need code to deal with all of
X;# them.  I need to seperate out a lot of the redundant stuff, like finding
X;# the longest expansion for two or more possible matches...that one happens
X;# all over the place...
X;#
X;# On the other hand, for casual use this is good enough for now.  The goal
X;# is to get it as good as the expansion in tcsh.
X;#
X;# A couple of other goals, as long as I am writing...
X;# One is to be able to expand scalar, list, associative array, and subroutine
X;# references.  This won't be easy, but then I don't think it will be as
X;# hard as trying to handle all of the filename expansion cases.  Just takes
X;# lots of code :-)
X;#
X;# Another goal is to have a sub-mode to handle multiple matches.  The way
X;# it would work is that when you get more than one match, you will be able
X;# to use the TAB key to traverse through all of the matches.  Any other
X;# key would exit out of that sub-mode and get fed into whatever is handling
X;# the current line editing.
X;#
X
X#	Some notes on all of this
X#
X#	ok, we have our word from the current line.  Let's dive into
X#	an unbelievable behind the scenes world of trying to make sense
X#	of it...
X#
X#	some cases:
X#
X#	* we're on whitespace, so we simply show the directory entries
X#	in the current directory.  If all of the entries share some common
X#	prefix, we'll expand that
X#
X#	* it's local to the directory, and we can just expand the filename
X#
X#	* it's local to the directory, but there is more than one match,
X#	so we expand as far as we can, and show the entries that matched
X#
X#	* it's local to the directory, and it's a directory name.  In that
X#	case, we'll tack on a '/'.  If there is more than one match though,
X#	we just expand...
X#
X#	* it's a pathname with any sort of '/' in it.  Do our best to
X#	separate the directory component from any filename.  Look for
X#	lone '/'.  Completely ignore Apollo "//" in this implementation.
X
X
X;#	references into $cmds after this point get here directly
X$cmds{"expand"} = '&expand';
X
X;#	expand
X;#
X;#	first pass, need to handle expansions in middle of line, full paths,
X;#	and a few other cases...
Xsub expand {
X    local($char_under_cursor);
X    #local(@local_filenames);
X    local(@current_line_words);
X    local($our_word);
X    
X    push(@current_line_words,
X	 split(/\s+/, substr($cur_line, 0, $cur_pos)));
X    
X    if ($cur_pos > 0) {
X	$char_under_cursor = substr($cur_line, $cur_pos - 1);
X	if ($char_under_cursor =~ /\s/) {
X	    $our_word = '.';
X	} else {
X	    $our_word = pop(@current_line_words);
X	}
X    }
X    
X    # make wild assumptions (set variables)
X    &first_pass($our_word);
X    
X    # a few easy cases....
X    # this one is right here...
X    if ($local_entry) {
X	&do_local;
X	return 1;
X    }
X    
X    # the root '/'
X    if ($root_path) {
X	opendir (THISDIR, "/");
X	@local_filenames = (readdir (THISDIR));
X	closedir (THISDIR);
X	print TTYOUT "\n@local_filenames\n";
X	&redraw_line;
X	return 1;
X    }
X    
X    # no filename hanging off of path...
X    if ($all_path) {
X	opendir (THISDIR, $our_word);
X	@local_filenames = (readdir (THISDIR));
X	closedir (THISDIR);
X	if ($our_word !~ /\/$/) {
X	    $ans = '/';
X	    &self_insert;
X	}
X	&redraw_line;
X	return 1;
X    }
X    
X    # ok, now we start handling tougher ones...
X    
X    if ($abs_path) {
X	local ($path) = $our_word;
X	$where_slash = rindex($path, "/");	
X	$dirpath = substr($path, 0, $where_slash);
X	
X	if (length($dirpath) == 0) {
X	    &do_root_plus_entry;
X	    return 1;
X	} else {
X	    if (opendir(THISDIR, $dirpath)) {
X		local(@fnames) = ();
X		
X		@rfn = readdir (THISDIR);
X		closedir(THISDIR);
X		foreach (@rfn) {
X		    push(@fnames, "$dirpath/$_");
X		}
X		@local_filenames = sort grep(/^$path/, @fnames);
X		if ($#local_filenames == 0) {
X		    foreach $ans (split(//,
X					substr($local_filenames[0],
X					       length($our_word)))) {
X			&self_insert;
X		    }
X		} else {
X		    print TTYOUT "\n\n\n we get @local_filenames\n";
X		}
X		&redraw_line;
X	    }
X	    return 1;
X	}
X    }
X    1;
X}
X
X;#	otherdir
X;#
X;#	be brave in the face of a potentially bizarre path
Xsub otherdir {
X    local($path) = @_;
X    
X    $where_slash = rindex($path, "/");	
X    
X    if ($where_slash == -1) {
X	return 0;
X    }
X    # a case of this would be "/u<expand>"
X    if ($where_slash == 0 && ! -d $path) {
X	$dirpath = "/";
X    } else {
X	if (-d $path) {
X	    $dirpath = $path;
X	} else {
X	    $dirpath = substr($path, 0, $where_slash);
X	}
X    }
X    
X    if (opendir(THISDIR, $dirpath)) {
X	local(@fnames) = ();
X	
X	@rfn = readdir (THISDIR);
X	closedir(THISDIR);
X	if ($dirpath =~ /^\/$/) {
X	    foreach (@rfn) {
X		push(@fnames, "/$_");
X	    }
X	} else {
X	    foreach (@rfn) {
X		push(@fnames, "$dirpath/$_");
X	    }
X	}
X	if (-d $path) {
X	    $our_word = '.';
X	} else {
X	    $our_word = '/' . $our_word;
X	}
X	@local_filenames = sort grep(/^$path/, @fnames);
X	return 1;
X    }
X    0;
X}
X
Xsub first_pass {
X    local($suspect) = @_;
X    
X    $has_path = $abs_path = $root_path = $all_path = $parent_path = 
X	$local_entry = $local_dir = $expand_scalar = $expand_list = 
X	    $expand_assoc = $expand_sub = 0;
X    
X    if ($suspect =~ /\//) {	# a path in there...
X	$has_path = 1;
X	if ($suspect =~ /^\//) { # absolute path
X	    $abs_path = 1;
X	}
X	if (length($suspect) == 1) { # really absolute (root)
X	    $root_path = 1;
X	}
X	if (-d $suspect) {	# it's all a path
X	    $all_path = 1;
X	}
X    } elsif ($suspect =~ /\.\./) {	# up a level
X	$parent_path = 1;
X    } else {			# call it local for now...
X	$local_entry = 1;
X	if (-d $suspect) {
X	    $local_dir = 1;
X	}
X    }
X    
X    ;#	and for future use...
X    ;#	the way this may work is to grab substr's and eval them
X    if ($first =~ /\$/) {	# possibly expand a scalar
X	$expand_scalar = 1;
X    }
X    if ($first =~ /@/) {	# possibly expand a list
X	$expand_list = 1;
X    }
X    if ($first =~ /[%]/) {	# possibly expand associative array
X	;#$expand_assoc = 1;
X    }
X    if ($first =~ /\&/) {	# possibly run a subroutine reference
X	;#$expand_sub = 1;
X    }
X    
X    
X    0 &&
X	print TTYOUT "
Xhas_path $has_path
Xabs_path $abs_path
Xroot_path $root_path
Xall_path  $all_path
Xparent_path $parent_path
Xlocal_entry  $local_entry
Xlocal_dir  $local_dir
Xexpand_scalar $expand_scalar
Xexpand_list $expand_list
Xexpand_assoc $expand_assoc
Xexpand_sub $expand_sub
X
X	";
X    
X}
X
X
Xsub do_local {
X    opendir (THISDIR, ".");
X    @local_filenames = sort grep(/^$our_word/, readdir (THISDIR));
X    closedir (THISDIR);
X    
X    if ($#local_filenames == 0) {
X	foreach $ans (split(//, substr($local_filenames[0],
X				       length($our_word)))) {
X	    &self_insert;
X	}
X    } elsif ($#local_filenames == -1) {
X	&cli_error("\(none\)");
X    } else {
X	# attempt to expand the shortest match
X	local ($loop) = 0;
X	$same = 1;
X	while ($same) {
X	    if ($loop > 0) {
X		$last_base = $base;
X	    }
X	    $base = substr($local_filenames[0], 0, $loop + 1);
X	    foreach (@local_filenames) {
X		if ($base !~ substr($_, 0, $loop + 1)) {
X		    $same = 0;
X		    last;
X		}
X	    }
X	    $loop++;
X	}
X	if (length($last_base) > 0) {
X	    foreach $ans (split(//,
X				substr($last_base, length($our_word)))) {
X		
X		&self_insert;
X	    }
X	}
X	print TTYOUT "\n@local_filenames\n";
X	&redraw_line;
X    }
X    1;
X    
X}
X
X
Xsub do_root_plus_entry {
X    opendir(ROOTDIR, '/');
X    local(@fnames) = ();
X    @rfn = readdir (ROOTDIR);
X    closedir(ROOTDIR);
X    foreach (@rfn) {
X	push(@fnames, "/$_");
X    }
X    @local_filenames = sort grep(/^$path/, @fnames);
X    if ($#local_filenames == 0) {
X	foreach $ans (split(//, substr($local_filenames[0],
X				       length($our_word)))) {
X	    &self_insert;
X	}
X    } else {
X	# attempt to expand the shortest match
X	local ($loop) = 0;
X	$same = 1;
X	while ($same) {
X	    if ($loop > 0) {
X		$last_base = $base;
X	    }
X	    $base = substr($local_filenames[0], 0, $loop + 1);
X	    foreach (@local_filenames) {
X		if ($base !~ substr($_, 0, $loop + 1)) {
X		    $same = 0;
X		    last;
X		}
X	    }
X	    $loop++;
X	}
X	if (length($last_base) > 0) {
X	    foreach $ans (split(//, substr($last_base,
X					   length($our_word)))) {
X		
X		&self_insert;
X	    }
X	}
X	&redraw_line;
X    }
X}
X1;
SHAR_EOF
chmod 0644 expand.pl || echo "restore of expand.pl fails"
if [ $TOUCH = can ]
then
    touch -am 1205004592 expand.pl
fi
set `wc -c expand.pl`;Wc_c=$1
if test "$Wc_c" != "9206"
then echo original size 9206, current size $Wc_c;fi
# ============= fastcwd.pl ==============
echo "x - extracting fastcwd.pl (Text)"
sed 's/^X//' << 'SHAR_EOF' > fastcwd.pl &&
X# By John Bazik
X#
X# Usage: $cwd = &fastcwd;
X#
X# This is a faster version of getcwd.  It's also more dangerous because
X# you might chdir out of a directory that you can't chdir back into.
X
Xsub fastcwd {
X	local($odev, $oino, $cdev, $cino, $tdev, $tino);
X	local(@path, $path);
X	local(*DIR);
X
X	($cdev, $cino) = stat('.');
X	for (;;) {
X		($odev, $oino) = ($cdev, $cino);
X		chdir('..');
X		($cdev, $cino) = stat('.');
X		last if $odev == $cdev && $oino == $cino;
X		opendir(DIR, '.');
X		for (;;) {
X			$_ = readdir(DIR);
X			next if $_ eq '.';
X			next if $_ eq '..';
X
X			last unless $_;
X			($tdev, $tino) = lstat($_);
X			last unless $tdev != $odev || $tino != $oino;
X		}
X		closedir(DIR);
X		unshift(@path, $_);
X	}
X	chdir($path = '/' . join('/', @path));
X	$path;
X}
X1;
SHAR_EOF
chmod 0644 fastcwd.pl || echo "restore of fastcwd.pl fails"
if [ $TOUCH = can ]
then
    touch -am 1205004592 fastcwd.pl
fi
set `wc -c fastcwd.pl`;Wc_c=$1
if test "$Wc_c" != "754"
then echo original size 754, current size $Wc_c;fi
# ============= help.pl ==============
echo "x - extracting help.pl (Text)"
sed 's/^X//' << 'SHAR_EOF' > help.pl &&
X
X#
X#	Help routines and man page from here on
X#
X
X#       update $cmds so that we just load once
X$cmds{"help"} = '&help($arg)';
X
X#	a mnemonic to put in the menu, routine to call, and description
X%help_screens = (
X        'A',    'A &help_about About SoftList',
X	'a', 	'a &help_add The Add Menu',		
X	'b',	'b &help_batch The Batch Menu',
X	'e',	'e &help_editing Editing Lines',
X	'k', 	'k &help_keystrokes Menu Keystrokes',
X	's',	's &help_search The Search Menu',
X	'm', 	'm &help_main The Main Menu',
X	'o', 	'o &help_options The Options Menu',	
X	'r', 	'r &help_references The References Menu',	
X	'c', 	'c &help_shell The Perl Shell (CLI)',
X);
X
X
X
X#	help - entry point to help routines
Xsub help {
X	local ($which_help) = @_;
X	($mnemonic, $routine, $menu_item) =
X		split (/ /, $help_screens{$which_help}, 3);
X	print TTYOUT <<"+++";
X$clear_str
X
X        $menu_item ($mnemonic)
X
X	Press the space bar to get help for \"$menu_item\"...
X
X	Or, any other key for a menu of available help topics
X
X+++
X	print TTYOUT "\tyour choice >> "; &flush;
X	read (TTYIN, $ans, 1);
X	if ($ans =~ ' ') {
X		print TTYOUT "$menu_item\n";
X	} else {
X		print TTYOUT "\n\n\tavailable help items:\n\n";
X		foreach $help_item (sort (values %help_screens)) {
X			($mnemonic, $ignore, $menu_item) =
X				split (/ /, $help_item, 3);
X			print TTYOUT "\t$mnemonic\t$menu_item\n";
X		}
X		print TTYOUT "\n\tyour choice >> "; &flush;
X		read (TTYIN, $ans, 1);
X		($mnemonic, $routine, $menu_item) =
X			split (/ /, $help_screens{$ans}, 3);
X		print TTYOUT "$menu_item\n";
X	}
X	
X	eval $routine;
X	print TTYOUT "\n";
X	1;
X}
X
X
Xsub help_main {
X        if (! defined ($help_main_str)) {
X		$help_main_str = <<"+++";
X
X
X		Main Menu Help and Overview
X
X	SoftList is used to manage simple lists.  You can use existing
Xsets of records, or generate new types of lists on the fly.  One example
Xis the "Current Versions of Software" list.
X
X	SoftList contains a few interactive menus with options for working
Xwith the list.  It also contains a Perl command line interpreter, and through
Xthe use of aliases, can run Unix commands.
X
X	The Main Menu currently looks like this:
X
X		SoftList Main Menu $init_message
X
X	?       help
X
X	a       add
X	b	batch in/out
X	s       search/edit
X
X	o	options
X	q       quit
X
X        your choice >>
X
X	The top line of every menu will sometimes show you a message such as
X"(initialising catalog)".  This shows that SoftList is gathering data that it
Xneeds.
X
X	Any menu can be accessed by a single keystroke.  To get back from
Xa menu, tap the spacebar.
X
X	Looking at the menus:
X
X	a       add
X
X	You'd type 'a' to get to the Add Menu.  This menu allows you to enter
Xnew list entries, one record at a time.
X
X	b       batch in/out
X
X	You can feed SoftList an entire file of entries, in order to add
Xrecords to your data directory.  You can also produce a sorted list of all 
Xof the records.
X
X	s       search/edit
X
X	This menu allows you to search for specific records, and to manipulate
Xthe ones that are found (edit, view, mail, print).
X
X	o	options
X
X	This menu will grow in future releases.  At the moment, it gives you
Xaccess to the man page and the Perl CLI.
X
X	More help about using the menus (they can be pushed and popped) can be
Xfound in the "Menu Keystrokes" item.
X+++
X	}
X	&pager (*help_main_str);
X	1;
X}
X
Xsub help_add {
X        if (! defined ($help_add_str)) {
X		$help_add_str = <<"+++";
X	
X
X		Add Menu Help
X
X	The Add Menu is used to enter new records, one at a time, to the
Xcurrent list.  It shows the current values for the main fileds of the list,
Xand whether the description has been edited.  It also displays whether or
Xnot this information has been saved.
X
X
X	The Add Menu currently looks like this:
X
X                Add Menu $init_message 
X
X        ?       help
X
X        current values: $saved_stat, $num_data_files data files $dir_menu_msg
X
X
X	[replace this with the Softlist version....]
X        p       package         "$package_name"
X        c       contact         "$contact_name"
X        l       location        "$package_location"
X        d       description     $descstat
X
X	b	batch input
X        r       reset variables
X        u       update
X
X
X        your choice >>
X
X	Looking at the fields:
X
X        p       package         "$package_name"
X        c       contact         "$contact_name"
X        l       location        "$package_location"
X
X	These three fields share a line editor that you use to enter
Xthe information (see the help item for "Line/Field Editing").  You can
Xscroll backwards or forwards through history to speed entry.  Contacts
Xwill usually be the email address or the author of the package, or the
Xmaintainer, or the name of a Usenet newsgroup where the package is discussed.
XThe location should the name of an ftp site, and the absolute pathname
Xof the package, or some sort of archiving info.
X
X        d       description     $descstat
X
X	When you enter 'd', you will be put into an editor where you can
Xenter a one or more line description.  You can type as much as you want.
XRemember though, that SoftList separates one record from another by a blank
Xline.
X
X	b	batch input
X
X	This is a shortcut to the Batch Menu.
X
X        r       reset variables
X
X	This clears the currently entered patterns.  It does not change the
Xstatus of the description.
X
X        u       update
X
X	This updates the data directory with your new record.
X	
X	To get back to the Main Menu from the Add Menu, tap the space bar.
X
X	More help about using the menus (they can be pushed and popped) can be
Xfound in the "Menu Keystrokes" item.
X+++
X	}
X	&pager (*help_add_str);
X	1;
X}
X
X
Xsub help_batch {
X        if (! defined ($help_batch_str)) {
X		$help_batch_str = <<"+++";
X	
X
X		Batch Menu Help
X
X
X	The Batch Menu is used to generate new records from existing files,
Xand to output files that represent some or all of your records.  Put another
Xway, someone could email you a file of lots of information on software packages,
Xand if it is in the right format, SoftList can grab the data right out of the
Xfile.  The "Right Format" looks like this:
X
Xpackage: gcc 1.40
Xcontact: gnu.gcc.bug
Xlocation: prep.ai.mit.edu:/pub/gnu
XGNU C Compiler
X
Xpackage: emacs 18.57
Xcontact: gnu.emacs.*
Xlocation: prep.ai.mit.edu:/pub/gnu
XThe GNU editor, written by Richard Stallman and a cast of thousands
X 
X	It is important to have a blank line between records.
X
X	The Batch Menu currently looks like this:
X
X                Batch Input/Output Menu $init_message
X 
X 
X        ?       help
X 
X        i       input new records from file
X        o       output all records to a file
X        O       output only recently found records to a file
X 
X        current in:     $current_batch_file_in
X        current out:    $current_batch_file_out
X 
X        your choice >>
X
X	Looking at the fields:
X
X	i       input new records from file
X
X	Upon pressing 'i', you will get a prompt for which file to use as
Xinput.  A default path is put there for you.  If that path is okay, just hit
Xthe return key, and processing will start.  In the case of duplicate records,
Xyou will be notified.  Making batches from standard input is currently not
Xsupported.
X
X        o       output all records to a file
X
X	This works pretty much the same as above.  The file prompt is for the
Xname of the file you want everything written out to.
X
X        O       output only recently found records to a file
X
X	This is like "output all records", except you are just working with
Xthe set of records found in the most recent search from the search menu.
X
X        current in:     $current_batch_file_in
X        current out:    $current_batch_file_out
X
X	These two lines show you the current input and output batch files.
X
X	To get back to the previous menu from the Batch Menu, tap the space bar.
X
X        More help about using the menus (they can be pushed and popped) can be
Xfound in the "Menu Keystrokes" item.
X+++
X	}
X	&pager (*help_batch_str);
X	1;
X}
X
X
X
Xsub help_search {
X        if (! defined ($help_search_str)) {
X		$help_search_str = <<"+++";
X	
X
X		Search Menu Help
X
X	The Search Menu is used to search for records.  It currently looks like:
X 
X                Search/Edit Menu $init_message
X 
X        $num_data_files data files total${last_found_str} $dir_menu_msg
X 
X        ?       help
X 
X
X	[replace this weith SoftList version.....]
X
X        Search by:              Actions:
X 
X        p       package         A       add
X        c       contact         E       edit
X        l       location        M       mail
X        g       globally        P       print
X                                R       reset patterns
X                                V       view
X                                $reference_option
X 
X        Current Search Pattern: "$search_pattern"
X
X        your choice >> 
X
X	Looking at the fields:
X
X        $num_data_files data files total${last_found_str} $dir_menu_msg
X
X	This line shows the total number of records, and can also show
Xthe number found from the last search.
X
X        Search by:              Actions:
X
X	From this point down in the menu, the things that you can do fall into
Xone of two categories:  you can search by package, contact, location, or
Xon entire records, or, on the Actions side, you can do something with the
Xsearch or perform other tasks.  Actions are invoked by capital (shifted)
Xletters, in order to free up lower case letters for the search fields.
X
X        p       package
X        c       contact
X        l       location
X        g       globally
X
X	These are different ways to search through records.  Searches by
X"package" (p) are the fastest, because each package name is already known
Xby SoftList.
X
X	The Actions are:
X
X	A       add
X
X	Go to the Add Menu
X
X	E       edit
X
X	Go into $ENV{'EDITOR'} to change the found records.
X
X	M       mail
X
X	Mail the found records to someone.
X
X	P       print
X
X	Print the found records.
X
X	R       reset patterns
X
X	Clear the search pattern
X
X	V       view
X
X	View the records in a pager ($ENV{'PAGER'})
X
X        To get back to the Main Menu from the Search Menu, tap the space bar.
X 
X        More help about using the menus (they can be pushed and popped) can be
Xfound in the "Menu Keystrokes" item.
X+++
X	}
X	&pager (*help_search_str);
X	1;
X}
X
X
X
Xsub help_options {
X        if (! defined ($help_options_str)) {
X		$help_options_str = <<"+++";
X	
X		Options Menu Help
X
X	The Options Menu is not very developed yet.  When SoftList becomes
X"SoftList" in a future version, there will be more to do here.
X
X	The Options Menu looks like:
X
X                Files, Configuration, and Options $init_message
X 
X        ?       help
X 
X        e       evaluate perl expressions
X        m       man page for SoftList
X 
X	If you type 'e', you will drop into the Perl Shell.  You can get back
Xfrom the Perl Shell by just pressing Return by itself on a line.  This option
Xis the same as pressing '@' from any menu, except here it happens to be a menu
Xitem.
X
X	'm' gives you a man page for SoftList.  It is very sparse at the moment,
Xbecause so much help for the program can be found in these help screens.
X
X
X        To get back to the Main Menu from the Search Menu, tap the space bar.
X 
X        More help about using the menus (they can be pushed and popped) can be
Xfound in the "Menu Keystrokes" item.
X
X        For more info about Line editing (helpful in the Perl Shell), see
Xthe "Editing Lines" item.  There is also help available on the Perl Shell.
X+++
X	}
X	&pager (*help_options_str);
X	1;
X}
X
X
X
Xsub help_shell {
X        if (! defined ($help_shell_str)) {
X		$help_shell_str = <<"+++";
X
X		The Perl Shell
X
X	The Perl Shell is a Command Line Interpreter.  It uses all of the
Xline/field editing and history that you find elsewhere in SoftList (see the
Xhelp item on "Editing Lines").  By editing your ~/.SoftListrc, you can
Xpermanently add aliases that enable you to mix Perl statements with Unix
Xcommands.  You can also cd and push and pop directories.
X
X	I'll explain a few aliases that I have defined:
X
X	rc - reconfigure the ~/.SoftListrc file from within SoftList.  This
Xis an easy way to add new aliases and other variables to an existing SoftList
Xsession.  Whatever is in the ~/.SoftListrc is eval'ed by Perl once you
Xexit the editor.  A note of caution: only add one thing at a time, and it
Xwill be much easier to solve possible problems.
X
X	alias - with no arguments, show all of the alias definitions.  With
Xone argument, show the definition for that alias.  You could define a new alias
Xby doing something like:
X
X	alias sq print "\\n", \$alias_args[1] * \$alias_args[1]
X
X	catalog - see the existing file that SoftList uses and constructs
Xthat maps package names to actual data file names.
X
X	cd - this is the same as the "cd" command in most shells.  You can edit
Xthe $cdpath array in ~/.SoftListrc to make getting around easier.
X
X	crc16 - run perl based crc on a file.  This calls a routine in SoftList.
XYou could also make an alias to run an external crc.  See the comments in
Xthe ~/.SoftListrc file.
X
X	dirs - examine directory stack
X
X	l & ll - aliases for the ls command.
X
X	m - view a file through a pager
X
X	pkeys - show the package names
X
X	p, pl, pp & ppl - push, push and list, pop, and pop and list.  These
Xall are for the directory stack.
X
X	prass - print an associative array.  This will show you any associative
Xarray that SoftList knows about, in a pager.  Try:
X
X	prass %all_packages
X
X	sha - set shell alias on the fly.  This is a shortcut way to define
Xan alias to run a Unix command when you really need to.  Let's say you
Xwant to run "cc", and get:
X
Xperl /files/home/users/dansmith>> cc foo.c
Xsyntax error in file (eval) at line 1, next 2 tokens "cc;"
X
X	Since "cc" isn't an alias, and it is not a perl keyword, SoftList
Xdoesn't recognize it.  You can then do:
X
Xperl /files/home/users/dansmith>> sha cc
Xperl /files/home/users/dansmith>> cc foo.c
X
X	and then it will work.
X
X	upcat - force an update to the current SoftList catalog file.  This
Xwould useful if you just added a lot of records, and then wanted to view the
Xcatalog file.  What SoftList usually does is rebuild the catalog file (if
Xneeded) upon startup; the theory being that you will use it more to look up
Xexisting records than to add to it.
X
X	To see the bindings of the edit commands, you can try:
X
X	prass  %edit_cmds
X
X	This will not work well in the "more" pager.  Try using "less", as
Xit can handle printing control characters correctly.
X+++
X	}
X	&pager (*help_shell_str);
X	1;
X}
X
X
X
Xsub help_editing {
X        if (! defined ($help_editing_str)) {
X		$help_editing_str = <<"+++";
X	
X
X		Editing Lines/Fields
X
X
X	SoftList has a built in line editor to help make entering information
Xeasy.  Also, for any field, you can retrieve lines you've previously entered.
XNotation: when I write "C-p", it means the keystroke "Control p".  "ESC"
Xmeans to press the "Escape" key. "BS" is "Backspace", and "DEL" means the
X"Delete" key.  Something like "ESC-b" would mean the sequence "Escape b"
X(no space is typed).
X
X	History:
X
X	Every field maintains its own copy of lines you've entered since
Xyou've started SoftList.  For example, the Add Menu has a field called
X"location".  For example, let's say you are entering information about a
Xfew software packages that are all stored at the site export.mit.edu.
XFor the first record, you would type out "export.mit.edu:/some/long/path".
XThe next time you come to the "location" field, you can enter the
Xkeystroke for previous-history, which is C-p (Control p), and edit the
Xfilename portion of the path, and save yourself much typing.
X
X	The keystrokes for history are:
X
X	C-p	previous_history
X	C-n	next_history
X
X	Line Editing:
X
X	SoftList has many of the same functions and keystrokes as the
Xcommand line interpreter, tcsh.  They are largely derived from Emacs:
X
X        C-a	beginning_of_line
X        C-b	backward_char
X        C-f	forward_delete_char
X        C-e	end_of_line
X        C-f	forward_char
X        C-k	kill_line (current point to the end)
SHAR_EOF
echo "End of SoftList 3.0 Beta part 3"
echo "File help.pl is continued in part 4"
echo "4" > s3_seq_.tmp
exit 0
-- 
     Daniel Smith, Autodesk, Sausalito, California, (415) 332-2344 x 2580
	      Disclaimer: written by a highly caffeinated mammal
	    dansmith@autodesk.com            dansmith@well.sf.ca.us


------------------------------

** FOR YOUR REFERENCE **

The service addresses, to which questions about the list itself and requests
to be added to or deleted from it should be directed, are as follows:

    Internet: Perl-Users-Request@fuggles.acc.Virginia.EDU
              Perl-Users-Request@uvaarpa.Virginia.EDU
    BITNET:   Perl-Req@Virginia
    UUCP:     ...!uunet!virginia!perl-users-request

You can send mail to the entire list (and comp.lang.perl) via one of these
addresses:

    Internet: Perl-Users@uvaarpa.Virginia.EDU
    BITNET:   Perl@Virginia
    UUCP:     ...!uunet!virginia!perl-users

End of Perl-Users Digest
******************************
--[1702]--
