home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 11 Util
/
11-Util.zip
/
qtawkos2.zip
/
QTAUTL.ZIP
/
more.exp
< prev
next >
Wrap
Text File
|
1993-10-19
|
23KB
|
633 lines
# QTAwk "more" utility
#
# Display one screen of a file at a time
#
# Command Line Parameters Available: (Note: must precede on command line
# with "--" option to prevent QTAwk from trying to recognize)
# ansi = FALSE --> turn off use of ANSI.SYS display driver
# -ppath --> use "path" to locate files to read
# +/r.e.[/] --> read first file until locate match to r.e. regular expression
# -ffilename --> filename specifies file name for replacement/highlight
# commands
#
#
# "commands" allow user to:
# [Qq](uit)? -> quit
# [Hh](elp)? -> diplay help
# [Ff](ile)? -> skip to next file
# [Rr](edraw)? -> re-draw last screen
# [Nn](umbers)? -> turn line numbers on/off
# [Tt](abs)? -> turn tab substitution on/off
# [Cc](ontext)? -> display search/match/highlight r.e.
# {_d}+ -> go to {_d} line, {_d} > current line number
# {_d}*l -> skip {_d} lines
# {_d}*s -> skip {_d} screens
# {_d}*/r/ -> go to {_d} next match of r.e.
# {_d}*m -> go to {_d} next match of last r.e. entered as above
# {_d}*p -> set number of lines prior to match to display
# {_d}*d -> set display line length to {_d}, default 79
# h{_d}/r/ -> Highlight text matching r.e.
# a{_d}/r/s/ -> replace matching string
# [Ii](nit)? -> re-initialize
# - line numbering
# - tab expansion
# - display line length
# - prior lines (to match)
# - search/highlight/replace patterns
# if optional {_d}* not entered - default to 1
#
# Use the getdir function to find files matching the pattern(s) passed.
# Patterns follow the wildcard syntax of DOS expanded to allow the use
# of character classes, and to allow characters after the '*' wildcard.
# DOS does not recognize characters following the '*'. Must also enclose
# filename specifications in quotes, "fn", to prevent expansion by the QTAwk
# wild card expansion routine. For example the DOS wildcard expression for
# all file names starting with 'c' and ending with 't' or 'p' and with an
# extension of "exp" would be:
# "c*[pt].exp"
# this is translated into the regular expression syntax:
# /^C[!\X001-\X021."\/\\\[\]:|<>+=;,]*[PT]\.EXP$/
#
# Multiple patterns may also be specified:
# QTAwk -fmore.exp -- "[gdh]*.(hlp|txt)" "*(dir|bnc).exp"
#
#
BEGIN {
local p_indx = 0;
local sub_dir = ""; # default to current sub-directory
local fnames;
local files_found;
local cnames, cindex = 0;
local ipat;
local i, j, cmd_line;
# Set The Standard Error File
stderr = "stderr";
# NOTE: Use '\x0ff' In ANSI Sequences Below. The '\x0ff' Will Get
# Translated To '[' Before Being Printed. Use '\x0ff' Character
# So That '[' May Be Used In Search And High Lighted Text Regular
# Expressions Without Being Substituted For. This Assumes That
# The '\x0ff' Character Will Probably Not Be In A Search Pattern
# Or High Lighted Text Pattern.
# Set ANSI Strings For Text Highlighting
### Turn On Use Of ANSI.SYS Display Driver
ansi = TRUE;
Red_on_Black = "\x01b\x0ff0;31;40m";
Green_on_Black = "\x01b\x0ff0;32;40m";
Yellow_on_Black = "\x01b\x0ff0;33;40m";
Blue_on_Black = "\x01b\x0ff0;34;40m";
Magenta_Black = "\x01b\x0ff0;35;40m";
Cyan_on_Black = "\x01b\x0ff0;36;40m";
White_Black = "\x01b\x0ff0;37;40m";
Black_on_Red = "\x01b\x0ff0;30;41m";
Green_on_Red = "\x01b\x0ff0;32;41m";
# Set ANSI Strings For Text Highlighting - Bold Text
Red_on_Blackh = "\x01b\x0ff1;31;40m";
Green_on_Blackh = "\x01b\x0ff1;32;40m";
Yellow_on_Blackh= "\x01b\x0ff1;33;40m";
Blue_on_Blackh = "\x01b\x0ff1;34;40m";
Magenta_Blackh = "\x01b\x0ff1;35;40m";
Cyan_on_Blackh = "\x01b\x0ff1;36;40m";
White_Blackh = "\x01b\x0ff1;37;40m";
Black_on_Redh = "\x01b\x0ff1;30;41m";
Green_on_Redh = "\x01b\x0ff1;32;41m";
# Echo Input
# ECHO_INPUT = TRUE;
# Set Displayed Line Length
display_length = def_display_length = 79;
# Flag For Expanding Tabs
sub_tabs = FALSE;
# Set Number Of Lines On Screen
screen_size = 25;
# Set Number Of Lines To Display Prior To Line Matching R.E.
prior_lines = dprior_lines = 2;
# Set Array Members For Highlighting Phrases
High_Text[1] = Red_on_Blackh;
High_Text[2] = Green_on_Blackh;
High_Text[3] = Yellow_on_Blackh;
High_Text[4] = Blue_on_Blackh;
High_Text[5] = Magenta_Blackh;
High_Text[6] = Cyan_Blackh;
High_Text[7] = White_Blackh;
High_Text[8] = Black_on_Redh;
High_Text[9] = Green_on_Redh;
# Set ANSI Sequence For Normal Text
Normal = White_on_Blue = "\x01b\x0ff0;37;44m";
blank_line = /^\f?{_w}*$/;
skipping_blank = FALSE;
if ( ARGC == 1 ) {
cmd_help;
exit 1;
}
init_sre = FALSE;
# Set The Regular Expressions For Recognizing "Commands"
ANSI = /^[Aa]([Nn][Ss][Ii])?$/;
Quit = /^[Qq](uit)?$/;
Help = /^[Hh](elp)?$/;
Re_display = /^[Rr](edraw)?$/;
Next_file = /^[Ff](ile)?$/;
Numbersl = /^[Nn](umbers)?$/;
Sub_Tabs = /^[Tt](abs)?$/;
Review_P = /^[Cc](ontext)?$/;
Skip_blank = /^[Bb](lank)?$/;
GoTo_line = /^{_d}+$/;
Skip_lines = /^{_d}*l$/;
Skip_scrn = /^{_d}*s$/;
Match_RE = /^{_d}*\//;
RE_reset = /^{_d}*m$/;
Prior_cmd = /^{_d}*p$/;
Display_L = /^{_d}*d$/;
High_RE = /^h{_w}*{_d}*{_w}*\//;
Replace_RE = /^r{_w}*{_d}*{_w}*\//;
Init_RE = /^[Ii](nit)?$/;
highlight = FALSE;
replace_txt = FALSE;
# Set Regular Expressions For Command Line Options
# Must Precede These On The Command Line To Qtawk With "--"
# To Prevent Qtawk From Recognizing
Set_path = /^[-\/][Pp]/;
Red_cmds = /^[-\/][Ff]/;
RE_cmd = /^\+\//;
# Set Regular Expression For Recognizing Leading Digits In A Command
ldg_digits = /^{_w}*{_d}+/;
# DOS Filename Wild Card Search Pattern
wild_cards = /[\*\?]/;
# Specify Legal Filename Characters By Excluding Those Which Are Illegal
legal_chars = /[!\x001-\x021."\/\\\[\]:|<>+=;,]/;
for ( i = 1 ; i < ARGC ; i++ ) {
ipat = ARGV[i];
switch ( ipat ) {
case Set_path:
sub(Set_path,"",ipat);
if ( length(ipat) == 0 ) ipat = ARGV[++i];
sub_dir ∩= ipat;
# check for trailing back-slash on path
if ( sub_dir !~ /\\$/ ) sub_dir ∩= '\\';
break;
case RE_cmd:
sub(/^\+/,"",ipat);
execute_cmd(ipat);
init_sre = TRUE;
break;
case Red_cmds:
sub(Red_cmds,"",ipat);
if ( length(ipat) == 0 ) ipat = ARGV[++i];
while ( fgetline(ipat,cmd_line) > 0 )
if ( cmd_line !~ /^{_w}*#/ ) execute_cmd(replace(cmd_line));
close(ipat);
break;
default:
#
# Convert DOS Filename Wild Card Characters To Appropriate Regular
# Expression Operators And Escape Extension Period To Prevent
# Interpretation As R.E. "Any Character" Operator - Other R.E.
# Operators Allowed.
#
ipat = strupr(ipat);
if ( ipat ~~ wild_cards ) {
gsub(/\./,"\\.",ipat);
gsub(/\*/,"{legal_chars}*",ipat);
gsub(/\?/,"{legal_chars}?",ipat);
#
# the following line will convert the command line strings
# into regular expressions. This is to prevent the constant
# conversion of a string into a regular expression in the
# "getdir" function.
#
execute("pattern[" ∩ ++p_indx ∩ "] = /^" ∩ ipat ∩ "$/;");
} else cnames[++cindex] = ARGV[i];
break;
}
}
# If You Want To See The R.E. For The Files Un-comment The Following Line
# for ( i in pattern ) print "Searching For: " ∩ replace(pattern[i]);
# Delete Command Line Arguments - Will Replace With Directory Search Below
while ( 1 in ARGV ) delete ARGV[1];
i = 1;
if ( cindex )
for ( cindex in cnames )
if ( j = findfile(files_found,cnames[cindex]) ) {
# ARGV[i++] = "file_size=" ∩ files_found[1]["size"];
# ARGV[i++] = "file_date=" ∩ files_found[1]["date"];
# ARGV[i++] = "file_time=" ∩ files_found[1]["time"];
ARGV[i++] = cnames[cindex];
}
if ( p_indx ) {
#
# Go Find Matching Files And Print Names
#
for ( j in pattern ) print pattern[j];
fnames = getdir(sub_dir,pattern);
for ( j in fnames ) {
# use command line assignment to set file size for each file
# ARGV[i++] = "file_size=" ∩ fnames[j]["size"];
# ARGV[i++] = "file_date=" ∩ fnames[j]["date"];
# ARGV[i++] = "file_time=" ∩ fnames[j]["time"];
ARGV[i++] = sub_dir ∩ fnames[j]["name"];
# print fnames[j]["name"],fnames[j]["size"],fnames[j]["date"],fnames[j]["time"];
}
}
# Check For NO Directory Entries Which Match - Exit
# If Do Not Exit, Then QTAwk Will Read From Standard Input - With No
# Prompt - It Will Appear As If The Machine Has Hung. A Ctrl-Z Will
# Input An End-Of-File And Terminate, But User Probably Not Expecting
# To Have To Do That
if ( i == 1 ) {
print "No Directory Entries Match filename Specifications";
exit;
}
# Set The Number Of Command Arguments
ARGC = i;
}
INITIAL {
line_count = 1;
searching_re = init_sre;
exit_endfile = init_sre = FALSE;
amt_read = 0;
cls;
FILEDATE = sdate("%m/%d/%y",FILEDATE);
FILETIME = stime("%H:%M",FILETIME);
print "=====> " ∩ FILENAME ∩ " : " ∩ FILESIZE ∩ " : " ∩ FILEDATE ∩ " : " ∩ FILETIME ∩ " <=====";
}
skipping_blank && blank_line {
if ( !searching_re && !print_blank ) print_blank = TRUE;
last_screen[row++] = "";
next;
}
searching_re {
if ( $0 ~~ Search_pat ) {
# Here If Found Match In R.E. Search
match_found++;
if ( !--searching_re ) {
printf(" \r");
row += line_count += re_draw(match_last);
last_screen = match_last;
cycle;
} else printf("%6u : Match: %3u/%3u\r",FNR,match_found,searching_re);
} else {
# here if searching for r.e., but current line does not match
# 'rotate' storage array an tack current line on end
printf("%6u\r",FNR);
match_last[1] = $0;
rotate(match_last);
}
next;
}
{
local i;
local inp;
local hdr = line_numbers ? FNR ∩ ": " : "";
local dl;
print_blank = FALSE;
amt_read += length + 2; # added 2 to size read to account for CR/LF
dl = hdr ∩ $0;
# Set Line To Be Displayed, Truncate To Keep From Overflowing Display Line
# Will Still Overflow On Some Lines Since Tabs Are Counted As A Single
# Character Here, But Expanded By DOS On Output To Display. Could Replace
# Tabs With A Single Blank To Prevent This From Happening
if ( length(dl) > display_length ) dl = substr(dl,1,display_length);
if ( !searching_re ) {
# Here When Not Searching For Regular Expression Or Have Found
#
# Check If Translating Horizontal Tabs To Blanks - Do If TRUE
if ( sub_tabs ) dl = stran(dl,' ','\t');
# Check If ANSI.SYS Display Driver Being Used
if ( ansi ) {
# If A Search Pattern Exists - High-light
if ( Search_pat ) gsub(Search_pat,Red_on_Black ∩ "$$0" ∩ Normal,dl);
# Put In High Light ANSI Sequences For High Lighted Text
if ( highlight ) gsub(High_pat,High_Text[MATCH_INDEX + 0] ∩ "$$0" ∩ Normal,dl);
# Replace Matching Strings
if ( replace_txt ) gsub(Replace_pat,Replace_par[MATCH_INDEX + 0],dl);
# Translate '\x0ff' Character To '[' For ANSI Sequences
dl = stran(dl,'[','\x0ff');
}
print dl;
# Store Display Line
last_screen[row++] = $0;
# Check If Last Line On Screen
if ( ++line_count >= screen_size ) {
percent_rd = (int((1000.0 * amt_read)/FILESIZE) + 5)/ 10;
while ( TRUE ) {
printf("%s : %u%% : %lu : %s : %s : %u <-> Command (h for help)─┘",FILENAME,percent_rd,FILESIZE,FILEDATE,FILETIME,FNR);
fgetline("stdin",inp);
if ( length(inp) > 0 ) {
execute_cmd(inp);
if ( break_loop ) {
break_loop = FALSE;
break;
}
} else break;
}
cls;
line_count = 1;
deletea last_screen;
row = 0;
}
}
}
FINAL {
for ( ++line_count ; ++line_count < screen_size ; ) print "";
print "=====> " ∩ FILENAME ∩ " <=====";
if ( !exit_endfile ) {
printf("%s <-> Press Enter",FILENAME);
fgetline("stdin",inp);
}
exit_endfile = FALSE;
}
# Function To Check For Valid Command And Execute
function execute_cmd(cmd_str) {
local i, j;
local scrn_m = 1;
local digits = FALSE;
# Delete Leading/Trailing White Space From Command String
cmd_str = strim(cmd_str);
# NOTE: If Leading Digits On Command, Find
# Add 0 To Digits To Convert To Integer. Otherwise If Only One
# Digit, "substr" Function Returns A Character Value. Incrementing
# A Character Value With '++' Operator Gives Next Character In ASCII
# Sequence, Decrementing With '--' Gives Previous Character.
if ( cmd_str ~~ ldg_digits ) {
digits = substr(cmd_str,MSTART,MLENGTH) + 0;
cmd_str = strim(deletec(cmd_str,MSTART,MLENGTH));
}
if ( cmd_str ) {
switch ( cmd_str ) {
case ANSI:
ansi = !ansi;
break;
case Skip_blank:
skipping_blank = !skipping_blank;
break;
case Numbersl:
# toggle line numbering on/off
line_numbers = !line_numbers;
break;
case Help:
help;
break;
case GoTo_line:
if ( digits > FNR ) skip_ahead(digits - FNR - 1);
break_loop = TRUE;
break;
case Quit:
exit_endfile = TRUE;
exit;
break;
case Re_display:
cls;
re_draw(last_screen);
break;
case Next_file:
deletea last_screen;
exit_endfile = TRUE;
endfile;
break;
case Prior_cmd:
prior_lines = digits ? digits : dprior_lines;
deletea match_last;
break;
case Skip_scrn:
scrn_m = screen_size;
case Skip_lines:
skip_cnt = 1;
if ( digits ) skip_cnt = digits;
skip_ahead(skip_cnt * scrn_m);
break_loop = TRUE;
break;
case Match_RE:
if ( cmd_str !~ /\/$/ ) cmd_str ∩= '/';
execute("Search_pat = " ∩ cmd_str ∩ ";");
case RE_reset:
if ( Search_pat ) {
searching_re = digits ? digits : TRUE;
match_found = 0;
for ( j = prior_lines , i = 1 ; j ; i++ , j-- )
match_last[i] = last_screen[screen_size - j];
}
break_loop = TRUE;
break;
case High_RE:
cmd_str = deletec(cmd_str,1,1);
if ( cmd_str ~~ ldg_digits ) {
digits = substr(cmd_str,MSTART,MLENGTH) + 0;
cmd_str = strim(deletec(cmd_str,MSTART,MLENGTH));
if ( !digits ) digits = 1;
} else digits = 1;
if ( digits < 10 ) {
if ( cmd_str !~ /\/$/ ) cmd_str ∩= '/';
execute("High_pat[digits] = " ∩ cmd_str ∩ ";");
} else {
cmd_str ~~ /\/[!\/]+\//; # set MSTART/MLENGTH
i = substr(cmd_str,MSTART,MLENGTH);
cmd_str = substr(cmd_str,MSTART + MLENGTH);
sub(/\/$/,"",cmd_str);
execute("High_pat[digits] = " ∩ i ∩ ";");
execute("High_Text[digits] = \"" ∩ cmd_str ∩ "\";");
}
highlight = TRUE;
break;
case Review_P:
if ( Search_pat ) print "Search Pattern: /" ∩ Search_pat ∩ '/';
if ( highlight ) for ( i in High_pat ) print "High Lighted Pattern (" ∩ i ∩ "): /" ∩ High_pat[i] ∩ '/';
if ( replace_txt )
for ( i in Replace_pat ) {
print "Replace Pattern (" ∩ i ∩ "): /" ∩ Replace_pat[i] ∩ '/';
print "Replace String (" ∩ i ∩ "): \"" ∩ Replace_par[i] ∩ '"';
}
break;
case Display_L:
if ( digits ) display_length = digits;
else display_length = def_display_length;
break;
case Sub_Tabs:
sub_tabs = !sub_tabs;
break;
case Replace_RE:
cmd_str = deletec(cmd_str,1,1);
if ( cmd_str ~~ ldg_digits ) {
digits = substr(cmd_str,MSTART,MLENGTH) + 0;
cmd_str = strim(deletec(cmd_str,MSTART,MLENGTH));
if ( !digits ) digits = 1;
} else digits = 1;
if ( cmd_str ~~ /\/[!\/]+\// ) {
i = substr(cmd_str,MSTART,MLENGTH);
cmd_str = substr(cmd_str,MSTART + MLENGTH);
sub(/\/$/,"",cmd_str);
execute("Replace_pat[digits] = " ∩ i ∩ ";");
execute("Replace_par[digits] = \"" ∩ cmd_str ∩ "\";");
}
replace_txt = TRUE;
break;
case Init_RE:
deletea(High_pat);
deletea(Replace_pat);
deletea(Replace_par);
highlight = FALSE;
replace_txt = FALSE;
display_length = def_display_length;
prior_lines = dprior_lines;
searching_re = line_numbers = sub_tabs = Search_pat = FALSE;
break;
}
} else if ( digits > FNR ) {
skip_ahead(digits - FNR - 1);
break_loop = TRUE;
}
}
# Function To Redraw Screen
function re_draw(screen) {
local j = 0;
local k = 0;
local i, n;
local cl;
for ( i in screen ) k++;
j = FNR - k + 1;
for ( i in screen ) {
if ( skipping_blank && (screen[i] ~~ blank_line) ) {
j++;
continue;
}
cl = (line_numbers ? j++ ∩ ": " : "") ∩ screen[i];
if ( sub_tabs ) cl = stran(cl," ","\t");
if ( length(cl) > display_length ) cl = substr(cl,1,display_length);
# Check If ANSI.SYS Display Driver Being Used
if ( ansi ) {
if ( Search_pat ) gsub(Search_pat,Red_on_Black ∩ "$$0" ∩ Normal,cl);
gsub(High_pat,High_Text[MATCH_INDEX + 0] ∩ "$$0" ∩ Normal,cl);
gsub(Replace_pat,Replace_par[MATCH_INDEX + 0],cl);
cl = stran(cl,'[','\x0ff');
}
print cl;
}
return k;
}
# Function To Skip Ahead Number Of Lines In Current File Specified
function skip_ahead(lines) {
local dummy;
local gl;
cls;
while ( lines-- ) {
# Read Next Line, Check For Input And Not EOF
if ( (gl = getline(dummy)) <= 0 ) {
exit_endfile = TRUE;
break;
}
# Added 2 To Size Read To Account For CR/LF
amt_read += length(dummy) + 2;
printf("%u\r",FNR);
}
}
function help() {
local tabs = sub_tabs ? "ON" : "OFF";
cls;
print "\x01b[1;32;40mMORE\x01b[0;37;44m File Function Commands";
print "Commands: (i stands for an integer matched by {_d}.)";
print "i* means the integer is optional (match {_d}*) - 1 defaults.";
print "i+ means the integer is mandatory (match {_d}+) - no default.";
print "[\x01b[1;32;40mAa\x01b[0;37;44m](ansi)? -> Toggle Text Highlighting.";
print "[\x01b[1;32;40mQq\x01b[0;37;44m](uit)? -> exit to DOS.";
print "[\x01b[1;32;40mBb\x01b[0;37;44m](lank)? -> toggle skip blank line flag. Currently: " ∩ (skipping_blank ? "TRUE" : "FALSE");
print "[\x01b[1;32;40mRr\x01b[0;37;44m](edraw)? -> re-display last screen.";
print "[\x01b[1;32;40mFf\x01b[0;37;44m](ile)? -> proceed to next file.";
print "[\x01b[1;32;40mNn\x01b[0;37;44m](umbers)? -> turn line numbers on/off.";
print "[\x01b[1;32;40mTt\x01b[0;37;44m](abs)? -> Sub. Tabs - toggle on/off, starts off. Currently: " ∩ tabs;
print " if on, replace tabs with blank";
print "[\x01b[1;32;40mCc\x01b[0;37;44m](ontext)? -> Review Search and High Lighted Text Patterns";
print "[\x01b[1;32;40mIi\x01b[0;37;44m](nit)? -> re-Initialize";
print "\x01b[1;32;40mi+\x01b[0;37;44m -> Go To Line number i, if i > current line number.";
print "\x01b[1;32;40mi*l\x01b[0;37;44m -> skip forward i Lines.";
print "\x01b[1;32;40mi*s\x01b[0;37;44m -> skip forward i Screens.";
print "\x01b[1;32;40mi*/r/\x01b[0;37;44m -> search for ith expression. If found begin";
print " display starting 'p' lines before matching line.";
print "\x01b[1;32;40mi*m\x01b[0;37;44m -> search for next ith Match to previous";
print " regular expression.";
print "\x01b[1;32;40mi*p\x01b[0;37;44m -> set number of lines prior to match to display";
print " defaults to 2 if i not specified.";
print "\x01b[1;32;40mi*d\x01b[0;37;44m -> set display line length to i, 79 default";
print "\x01b[1;32;40mhi*/r/\x01b[0;37;44m -> High-light text matching ith expression";
print "\x01b[1;32;40mri*/r/s/\x01b[0;37;44m -> Replace r with string s";
}
# Function To Clear Screen And Home Cursor
# NOTE: MUST Have ANSI.SYS Device Driver Installed To Work
function cls() {
# Clear Screen And Home Cursor String
local _cls_ = "\x01b[2J";
fprintf(stderr,_cls_);
}
# Include Directory Searching Functions
#include <dirsrch.exp>
# Function To Display Command Line Help
function cmd_help() {
cls;
print "Usage:";
print "\x01b[1;32;40mQTAwk -fmore.exp -- [-ppath] [+/r.e.[/]] file1 file2 ...\x01b[0;37;44m";
print "Options:";
print " ppath - specifiy path to find files";
print " +/r.e./ - specify regular expression for starting search";
print "Commands:";
print "i below stands for an integer matched by {_d}.";
print "i* means the integer is optional (match {_d}*) - 1 defaults.";
print "i+ means the integer is mandatory (match {_d}+) - no default.";
print "[\x01b[1;32;40mAa\x01b[0;37;44m](ansi)? -> Toggle Text Highlighting.";
print "[\x01b[1;32;40mQq\x01b[0;37;44m](uit)? -> exit to DOS.";
print "[\x01b[1;32;40mRr\x01b[0;37;44m](edraw)? -> re-display last screen.";
print "[\x01b[1;32;40mFf\x01b[0;37;44m](ile)? -> proceed to next file.";
print "[\x01b[1;32;40mNn\x01b[0;37;44m](umbers)? -> turn line numbers on/off.";
print "[\x01b[1;32;40mTt\x01b[0;37;44m](abs)? -> Sub. Tabs - toggle on/off, starts off, currently:" ∩ tabs;
print " if on, replace tabs with blank";
print "[\x01b[1;32;40mCc\x01b[0;37;44m](ontext)? -> Review Search and High Lighted Text Patterns";
print "[\x01b[1;32;40mIi\x01b[0;37;44m](nit)? -> re-Initialize";
print "\x01b[1;32;40mi+\x01b[0;37;44m -> Go To Line number i, if i > current line number.";
print "\x01b[1;32;40mi*l\x01b[0;37;44m -> skip forward i Lines.";
print "\x01b[1;32;40mi*s\x01b[0;37;44m -> skip forward i Screens.";
print "\x01b[1;32;40mi*/r/\x01b[0;37;44m -> search for ith expression. If found begin";
print " display starting 'p' lines before matching line.";
print "\x01b[1;32;40mi*m\x01b[0;37;44m -> search for next ith Match to previous";
print " regular expression.";
print "\x01b[1;32;40mi*p\x01b[0;37;44m -> set number of lines prior to match to display";
print " defaults to 2 if i not specified.";
print "\x01b[1;32;40mi*d\x01b[0;37;44m -> set display line length to i, 79 default";
print "\x01b[1;32;40mhi*/r/\x01b[0;37;44m -> High-light text matching ith expression";
print "\x01b[1;32;40mri*/r/s/\x01b[0;37;44m -> Replace r with string s";
}