home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / qtawk / more.exp < prev    next >
Text File  |  1990-10-09  |  20KB  |  535 lines

  1. # QTAwk "more" utility
  2. #
  3. # Display one screen of a file at a time
  4. #
  5. # Command Line Parameters Available: (Note: must precede on command line
  6. #   with "--" option to prevent QTAwk from trying to recognize)
  7. #   -ppath    --> use "path" to locate files to read
  8. #   +/r.e.[/] --> read first file until locate match to r.e. regular expression
  9. #
  10. #
  11. # "commands" allow user to:
  12. #   [Qq](uit)?       -> quit
  13. #   [Hh](elp)?       -> diplay help
  14. #   [Ff](ile)?       -> skip to next file
  15. #   [Rr](edraw)?   -> re-draw last screen
  16. #   [Nn](unmbers)? -> turn line numbers on/off
  17. #   [Tt](abs)?       -> turn tab substitution on/off
  18. #   {_d}+       -> go to {_d} line, {_d} > current line number
  19. #   {_d}*l       -> skip {_d} lines
  20. #   {_d}*s       -> skip {_d} screens
  21. #   {_d}*/r.e./    -> go to {_d} next match of r.e.
  22. #   {_d}*m       -> go to {_d} next match of last r.e. entered as above
  23. #   {_d}*p       -> set number of lines prior to match to display
  24. #   {_d}*d       -> set display line length to {_d}, default 79
  25. #   h{_d}/r.e./    -> Highlight text matching r.e.
  26. #     if optional {_d}* not entered - default to 1
  27. #
  28. # Use the getdir function to find files matching the patter(s) passed.
  29. # Patterns follow the wildcard syntax of DOS expanded to allow the use
  30. # of character classes, and to allow characters after the '*' wildcard.
  31. # Dos does not recognize characters following the '*'. Must also enclose
  32. # filename specifications in quotes, "fn", to prevent expansion by the QTAwk
  33. # wild card expansion routine. For example the DOS wildcard expression for
  34. # all file names starting with 'c' and ending with 't' or 'p' and with an
  35. # extension of "exp" would be:
  36. #   "c*[pt].exp"
  37. # this is translated into the regular expression syntax:
  38. #   /^C[!\X001-\X021."\/\\\[\]:|<>+=;,]*[PT]\.EXP$/
  39. #
  40. # Multiple patterns may also be specified:
  41. #   QTAwk -fmore.exp -- "[gdh]*.(hlp|txt)" "*(dir|bnc).exp"
  42. #
  43. #
  44. BEGIN {
  45.     local p_indx = 1;
  46.     local sub_dir = ""; # default to current sub-directory
  47.     local fnames;
  48.     local ipat;
  49.     local i, j;
  50.  
  51.     # set the standard error file
  52.     stderr = "stderr";
  53.  
  54.     # set displayed line length
  55.     display_length = 79;
  56.     def_display_length = 79;
  57.  
  58.     # flag for expanding tabs
  59.     sub_tabs = FALSE;
  60.  
  61.     if ( ARGC == 1 ) {
  62.     cmd_help;
  63.     exit 1;
  64.     }
  65.  
  66.     init_sre = FALSE;
  67.  
  68.     # set the regular expressions for recognizing "commands"
  69.     Quit       = /^{_w}*[Qq](uit)?{_w}*$/;
  70.     Help       = /^{_w}*[Hh](elp)?{_w}*$/;
  71.     Re_display = /^{_w}*[Rr](edraw)?{_w}*$/;
  72.     Next_file  = /^{_w}*[Ff](ile)?{_w}*$/;
  73.     Numbersl   = /^{_w}*[Nn](umbers)?{_w}*$/;
  74.     Sub_Tabs   = /^{_w}*[Tt](abs)?{_w}*$/;
  75.     Review_P   = /^{_w}*[Cc](ontext)?{_w}*$/;
  76.     GoTo_line  = /^{_w}*{_d}+{_w}*$/;
  77.     Skip_lines = /^{_w}*{_d}*l{_w}*$/;
  78.     Skip_scrn  = /^{_w}*{_d}*s{_w}*$/;
  79.     Match_RE   = /^{_w}*{_d}*\/.*\/{_w}*$/;
  80.     RE_reset   = /^{_w}*{_d}*m{_w}*$/;
  81.     Prior_cmd  = /^{_w}*{_d}*p{_w}*$/;
  82.     Display_L  = /^{_w}*{_d}*d{_w}*$/;
  83.     High_RE    = /^{_w}*h{_w}*{_d}*{_w}*\/.*\/{_w}*$/;
  84.  
  85.     # set regular expressions for command line options
  86.     # must precede these on the command line to QTAwk with "--"
  87.     # to prevent QTAwk from recognizing
  88.     Set_path = /^-[Pp]/;
  89.     RE_cmd   = /^\+\//;
  90.  
  91.     # set regular expression for recognizing leading digits in a command
  92.     ldg_digits = /^{_w}*{_d}+/;
  93.  
  94.     # DOS filename wild card search pattern
  95.     wild_cards = /[\*\?\.]/;
  96.  
  97.     # specify legal filename characters by excluding those which are illegal
  98.     legal_chars = /[!\x001-\x021."\/\\\[\]:|<>+=;,]/;
  99.  
  100.     for ( i = 1 ; i < ARGC ; i++ ) {
  101.     ipat = ARGV[i];
  102.     switch ( ipat ) {
  103.         case Set_path:
  104.         sub(Set_path,"",ipat);
  105.         if ( length(ipat) == 0 ) ipat = ARGV[++i];
  106.         sub_dir ∩= ipat;
  107.         # check for trailing back-slash on path
  108.         if ( sub_dir !~ /\\$/ ) sub_dir ∩= '\\';
  109. #         print "Sub-directory to Search: " ∩ sub_dir;
  110.         break;
  111.         case RE_cmd:
  112.         sub(/^\+/,"",ipat);
  113.         execute_cmd(ipat);
  114.         init_sre = TRUE;
  115.         break;
  116.         default:
  117.         #
  118.         # convert DOS filename wild card characters to appropriate regular
  119.         # expression operators and escape extension period to prevent
  120.         # interpretation as r.e. "any character" operator - other r.e.
  121.         # operators allowed.
  122.         #
  123.         ipat = strupr(ipat);
  124.         if ( ipat ~~ wild_cards ) {
  125.         gsub(/\./,"\\.",ipat);
  126.         gsub(/\*/,"{legal_chars}*",ipat);
  127.         gsub(/\?/,"{legal_chars}?",ipat);
  128.         }
  129.         #
  130.         # the following line will convert the command line strings
  131.         # into regular expressions. This is to prevent the constant
  132.         # conversion of a string into a regular expression in the
  133.         # "getdir" function.
  134.         #
  135.         execute("pattern[" ∩ p_indx++ ∩ "] = /^" ∩ ipat ∩ "$/;");
  136.         break;
  137.     }
  138.     }
  139.     # if you want to see the r.e. for the files un-comment the following line
  140. #    for ( i in pattern ) print "Searching For: " ∩ replace(pattern[i]);
  141.     # delete command line arguments - will replace with directory search below
  142.     while ( 1 in ARGV ) delete ARGV[1];
  143.     i = 1;
  144.     fsize_indx = 1;    # initialize index into file size array
  145.     #
  146.     # go find matching files and print names
  147.     #
  148.     fnames = getdir(sub_dir,pattern);
  149.     for ( j in fnames ) {
  150.     ARGV[i++] = sub_dir ∩ fnames[j];
  151.     }
  152.  
  153.     # check for NO directory entries which match - exit
  154.     # If do not exit, then QTAwk will read from Standard Input - with no
  155.     # prompt - it will appear as if the machine has hung. a Ctrl-Z will
  156.     # input an end-of-file and terminate, but user probably not expecting
  157.     # to have to do that
  158.     if ( i == 1 ) {
  159.     print "No Directory Entries Match filename Specifications";
  160.     exit;
  161.     }
  162.  
  163.     # set the number of command arguments
  164.     ARGC = i;
  165.  
  166.     # initialize index into file size array
  167.     fsize_indx = 1;
  168.  
  169.     # set number of lines on screen
  170.     screen_size = 25;
  171.  
  172.     # set number of lines to display prior to line matching r.e.
  173.     prior_lines = dprior_lines = 2;
  174.  
  175.     # NOTE: use '\x0ff' in ANSI sequences below. The '\x0ff' will get
  176.     # translated to '[' before being printed. Use '\x0ff' character
  177.     # so that '[' may be used in search and hihgh lighted text regular
  178.     # expressions without being substituted for. This assumes that
  179.     # the '\x0ff' character will probably not be in a search pattern
  180.     # or high lighted text pattern.
  181.     # set ANSI strings for text highlighting
  182.     High_Text[1] = Red_on_Black    = "\x01b\x0ff1;31;40m";
  183.     High_Text[2] = Green_on_Black  = "\x01b\x0ff1;32;40m";
  184.     High_Text[3] = Yellow_on_Black = "\x01b\x0ff1;33;40m";
  185.     High_Text[4] = Blue_on_Black   = "\x01b\x0ff1;34;40m";
  186.     High_Text[5] = Magenta_Black   = "\x01b\x0ff1;35;40m";
  187.     High_Text[6] = Cyan_Black       = "\x01b\x0ff1;36;40m";
  188.     High_Text[7] = White_Black       = "\x01b\x0ff1;37;40m";
  189.     High_Text[8] = Black_on_Red    = "\x01b\x0ff1;30;41m";
  190.     High_Text[9] = Green_on_Red    = "\x01b\x0ff1;32;41m";
  191.  
  192.     # set ANSI sequence for normal text
  193.     Normal = "\x01b\x0ff1;31;44m";
  194. }
  195.  
  196. INITIAL {
  197.     line_count = 1;
  198. #    matching_re_start = matching_re_length = 0;
  199.     searching_re = init_sre;
  200.     exit_endfile = init_sre = FALSE;
  201.     file_size = file_sizea[fsize_indx++];
  202.     amt_read = 0;
  203.     cls;
  204.     print "=====> " ∩ FILENAME ∩ " : " ∩ file_size ∩ " <=====";
  205. }
  206.  
  207.     {
  208.     local i;
  209.     local inp;
  210.     local hdr = line_numbers ? FNR ∩ ": " : "";
  211.     local ol = length;    # set to length of input line
  212.     local dl;
  213.  
  214.     amt_read += ol + 2; # added 2 to size read to account for CR/LF
  215.     dl = hdr ∩ $0;
  216.     ol += length(dl);  # reset length of displayed line
  217.     # set line to be displayed, truncate to keep from overflowing display line
  218.     # will still overflow on some lines since tabs are counted as a single
  219.     # character here, but expanded by DOS on output to display. Could replace
  220.     # tabs with a single blank to prevent this from happening
  221.     if ( length(dl) > display_length ) dl = substr(dl,1,display_length);
  222.     if ( !searching_re ) {
  223.       # here when not searching for regular expression or have found
  224.       #
  225.       # check if translating horizontal tabs to blanks - do if TRUE
  226.     if ( sub_tabs ) dl = stran(dl,' ','\t');
  227.       # If a search pattern exists - high-light
  228.     if ( Search_pat ) gsub(Search_pat,Red_on_Black ∩ "$$0" ∩ Normal,dl);
  229.       # put in high light ansi sequences for high lighted text
  230.     for ( i in High_pat ) gsub(High_pat[i],High_Text[i] ∩ "$$0" ∩ Normal,dl);
  231.       # translate '\x0ff' character to '[' for ANSI sequences
  232.     dl = stran(dl,'[','\x0ff');
  233.     print dl;
  234.     # store display line
  235.     last_screen[row++] = $0;
  236.     # check if last line on screen
  237.     if ( ++line_count >= screen_size ) {
  238.         percent_rd = (int((1000.0 * amt_read)/file_size) + 5)/ 10;
  239.         while ( TRUE ) {
  240.         printf("%s : %u%%/%lu/%u <-> (Command)? ─┘",FILENAME,percent_rd,file_size,FNR);
  241.         fgetline("stdin",inp);
  242.         if ( length(inp) > 0 ) {
  243.             execute_cmd(inp);
  244.             if ( break_loop ) {
  245.             break_loop = FALSE;
  246.             break;
  247.             }
  248.         } else break;
  249.         }
  250.         cls;
  251.         line_count = 1;
  252.         deletea last_screen;
  253.         row = 0;
  254.     }
  255.       } else if ( $0 ~~ Search_pat ) {
  256.     # here if found match in r.e. search
  257.     match_found++;
  258.     if ( !--searching_re ) {
  259.         printf("                          \r");
  260.         row += line_count += re_draw(match_last);
  261.         last_screen = match_last;
  262.         cycle;
  263.       } else {
  264.         printf("%u : Match: %u/%u\r",FNR,match_found,searching_re);
  265.         next;
  266.     }
  267.       } else {
  268.     # here if searching for r.e., but current line does not match
  269.     # 'rotate' storage array an tack current line on end
  270.     printf("%u\r",FNR);
  271.     match_last[1] = $0;
  272.     rotate(match_last);
  273.     }
  274. }
  275.  
  276. FINAL {
  277.     for ( ++line_count ; ++line_count < screen_size ; ) print "";
  278.     print "=====> " ∩ FILENAME ∩ " <=====";
  279.     if ( !exit_endfile ) {
  280.     printf("%s <-> Press Enter",FILENAME);
  281.     fgetline("stdin",inp);
  282.     }
  283.     exit_endfile = FALSE;
  284. }
  285.  
  286. # function to check for valid command and execute
  287. function execute_cmd(cmd_str) {
  288.     local i, j;
  289.     local scrn_m = 1;
  290.     local digits = FALSE;
  291.  
  292.     # NOTE: If leading digits on command, find
  293.     #        add 0 to digits to convert to integer. Otherwise if only one
  294.     #        digit, "substr" function returns a character value. Incrementing
  295.     #        a character value with '++' operator gives next character in ASCII
  296.     #        sequence, decrementing with '--' gives previous character.
  297.     if ( cmd_str ~~ ldg_digits ) {
  298.     digits = substr(cmd_str,MSTART,MLENGTH) + 0;
  299.     cmd_str = strim(deletec(cmd_str,MSTART,MLENGTH));
  300.     }
  301.     switch ( cmd_str ) {
  302.     case Numbersl:
  303.         # toggle line numbering on/off
  304.         line_numbers = !line_numbers;
  305.         break;
  306.     case Help:
  307.         help;
  308.         break;
  309.     case GoTo_line:
  310.         if ( digits > FNR ) skip_ahead(digits - FNR - 1);
  311.         break_loop = TRUE;
  312.         break;
  313.     case Quit:
  314.         exit_endfile = TRUE;
  315.         exit;
  316.         break;
  317.     case Re_display:
  318.         cls;
  319.         re_draw(last_screen);
  320.         break;
  321.     case Next_file:
  322.         deletea last_screen;
  323.         exit_endfile = TRUE;
  324.         endfile;
  325.         break;
  326.     case Prior_cmd:
  327.         prior_lines = digits ? digits : dprior_lines;
  328.         deletea match_last;
  329.         break;
  330.     case Skip_scrn:
  331.         scrn_m = screen_size;
  332.     case Skip_lines:
  333.         skip_cnt = 1;
  334.         if ( digits ) skip_cnt = digits;
  335.         skip_ahead(skip_cnt * scrn_m);
  336.         break_loop = TRUE;
  337.         break;
  338.     case Match_RE:
  339.         if ( cmd_str !~ /\/$/ ) cmd_str ∩= '/';
  340.         execute("Search_pat = " ∩ cmd_str ∩ ";");
  341.     case RE_reset:
  342.         if ( Search_pat ) {
  343.         searching_re = digits ? digits : TRUE;
  344.         match_found = 0;
  345.         for ( j = prior_lines , i = 1 ; j ; i++ , j-- )
  346.           match_last[i] = last_screen[screen_size - j];
  347.         }
  348.         break_loop = TRUE;
  349.         break;
  350.     case High_RE:
  351.         cmd_str = deletec(cmd_str,1,1);
  352.         if ( cmd_str ~~ ldg_digits ) {
  353.         digits = substr(cmd_str,MSTART,MLENGTH) + 0;
  354.         cmd_str = strim(deletec(cmd_str,MSTART,MLENGTH));
  355.         if ( !digits ) digits = 1;
  356.         } else digits = 1;
  357.         if ( digits < 10 ) {
  358.         if ( cmd_str !~ /\/$/ ) cmd_str ∩= '/';
  359.         execute("High_pat[digits] = " ∩ cmd_str ∩ ";");
  360.         }
  361.         break;
  362.     case Review_P:
  363.         if ( Search_pat ) print "Search Pattern: /" ∩ Search_pat ∩ '/';
  364.         for ( i in High_pat ) print "High Lighted Pattern (" ∩ i ∩ "): /" ∩ High_pat[i] ∩ '/';
  365.         break;
  366.     case Display_L:
  367.         if ( digits ) display_length = digits;
  368.           else display_length = def_display_length;
  369.         break;
  370.     case Sub_Tabs:
  371.         sub_tabs = !sub_tabs;
  372.         break;
  373.     }
  374. }
  375.  
  376. # function to redraw screen
  377. function re_draw(screen) {
  378.     local j = 0;
  379.     local k = 0;
  380.     local i,n;
  381.     local cl;
  382.  
  383.     for ( i in screen ) k++;
  384.     j = FNR - k + 1;
  385.     for ( i in screen ) {
  386.     cl = (line_numbers ? j++ ∩ ": " : "") ∩ screen[i];
  387.     if ( sub_tabs ) cl = stran(cl," ","\t");
  388.     if ( length(cl) > display_length ) cl = substr(cl,1,display_length);
  389.     if ( Search_pat ) gsub(Search_pat,Red_on_Black ∩ "$$0" ∩ Normal,cl);
  390.     for ( n in High_pat ) gsub(High_pat[n],High_Text[n] ∩ "$$0" ∩ Normal,cl);
  391.     cl = stran(cl,'[','\x0ff');
  392.     print cl;
  393.     }
  394.     return k;
  395. }
  396.  
  397. # function to skip ahead number of lines in current file specified
  398. function skip_ahead(lines) {
  399.     local dummy;
  400.  
  401.     cls;
  402.     while ( lines-- ) {
  403.     # read next line, check for input and not EOF
  404.     if ( getline(dummy) <= 0 ) {
  405.         exit_endfile = TRUE;
  406.         break;
  407.     }
  408.     # added 2 to size read to account for CR/LF
  409.     amt_read += length(dummy) + 2;
  410.     printf("%u\r",FNR);
  411.     }
  412. }
  413.  
  414. function help() {
  415.     local tabs = sub_tabs ? "ON" : "OFF";
  416.  
  417.     cls;
  418.     print "\x01b[1;32;40mMORE\x01b[1;31;44m File Function Commands";
  419.     print "Commands:";
  420.     print "i below stands for an integer matched by {_d}.";
  421.     print "i* means the integer is optional  (match {_d}*) - 1 defaults.";
  422.     print "i+ means the integer is mandatory (match {_d}+) - no default.\n";
  423.     print "[\x01b[1;32;40mQq\x01b[1;31;44m](uit}?    -> exit to DOS.";
  424.     print "[\x01b[1;32;40mRr\x01b[1;31;44m](edraw)?  -> re-display last screen.";
  425.     print "[\x01b[1;32;40mFf\x01b[1;31;44m](ile)?    -> proceed to next file.";
  426.     print "[\x01b[1;32;40mNn\x01b[1;31;44m](umbers)? -> turn line numbers on/off.";
  427.     print "[\x01b[1;32;40mTt\x01b[1;31;44m](abs)?    -> Sub. Tabs - toggle on/off, starts off, currently:" ∩ tabs;
  428.     print "                 if on, replace tabs with blank";
  429.     print "\x01b[1;32;40mi+\x01b[1;31;44m            -> Go To Line number i, if i > current line number.";
  430.     print "\x01b[1;32;40mi*l\x01b[1;31;44m           -> skip forward i Lines.";
  431.     print "\x01b[1;32;40mi*s\x01b[1;31;44m           -> skip forward i Screens.";
  432.     print "\x01b[1;32;40mi*/r.e./\x01b[1;31;44m      -> search for ith expression. If found begin";
  433.     print "                 display starting 'p' lines before matching line.";
  434.     print "\x01b[1;32;40mi*m\x01b[1;31;44m           -> search for next ith Match to previous";
  435.     print "                 regular expression.";
  436.     print "\x01b[1;32;40mi*p\x01b[1;31;44m           -> set number of lines prior to match to display";
  437.     print "                 defaults to 2 if i not specified.";
  438.     print "\x01b[1;32;40mi*d\x01b[1;31;44m           -> set display line length to i, 79 default";
  439.     print "\x01b[1;32;40mhi*/r.e./\x01b[1;31;44m     -> High-light text matching ith expression";
  440.     print "[\x01b[1;32;40mCc\x01b[1;31;44m](ontext)? -> Review Search and High Lighted Text Patterns";
  441. }
  442.  
  443. # function to clear screen and home cursor
  444. # NOTE: MUST have ANSI.SYS device driver installed to work
  445. function cls() {
  446.       # clear screen and home cursor string
  447.     local _cls_ = "\x01b[2J";
  448.  
  449.     fprintf(stderr,_cls_);
  450. }
  451.  
  452. # Function to get desired file names and print
  453. # Use DOS "dir" command to list all files to a temporary file
  454. # read temporary file picking up:
  455. # 1) path from third line
  456. # 2) filenames from remainder of lines
  457. # 3) match filenames against filepattern for desired files and print if match
  458. # Could also get file sizes, dates and times if desired
  459. #
  460. # Arguments passed:
  461. #   dir ==> path of desired files
  462. #   file_template ==> array of string or regular expression patterns
  463. #              for filenames
  464. #
  465. function getdir(dir,file_template) {
  466.     local tmp_file = "$tmptmp$.dir";
  467.     local gdir = "dir " ∩ dir ∩ "*.* > " ∩ tmp_file;
  468.     local ddir = "del " ∩ tmp_file;
  469.     local tmparr, inline, filename;
  470.     local f_indx = 1, f_list;
  471.     local i;
  472.  
  473.     system(gdir);
  474.     fgetline(tmp_file,inline);    # read and discard header lines
  475.     fgetline(tmp_file,inline);    # read and discard header lines
  476.     fgetline(tmp_file,inline);    # read and discard header lines
  477.     split(inline,tmparr);    # split out to get path
  478.     drive = substr(tmparr[3],1,2);   # set disk drive
  479.     path = sustr(tmparr[3],3) ∩ '\\';   # delete drive and set path
  480. #    print drive ∩ path;     # un-comment to print path
  481.     fgetline(tmp_file,inline);    # read and discard header lines
  482.     while ( fgetline(tmp_file,inline) > 0 ) {
  483.       # discard if not a filename line
  484.     if ( inline !~ /^[A-Z]/ ) continue;
  485.       # discard if a directory name line
  486.     if ( inline ~~ /{_w}+<DIR>{_w}+/ ) continue;
  487.       # split out file information
  488.     nf = split(inline,tmparr);
  489.       # form "filename.ext"
  490.     filename = tmparr[1] ∩ '.' ∩ tmparr[2];
  491.     for ( i in file_template ) {
  492.         if ( filename ~~ file_template[i] ) {
  493.         f_list[f_indx++] = filename;
  494.         # store file size as integer
  495.         file_sizea[fsize_indx++] = tmparr[3] + 0;
  496.         break;
  497.         }
  498.     }
  499.     }
  500.       # delete temporary directory file
  501.     close(tmp_file);
  502.     system(ddir);
  503.     return f_list;
  504. }
  505.  
  506. #function to display command line help
  507. function cmd_help() {
  508.     cls;
  509.     print "Usage:";
  510.     print "\x01b[1;32;40mQTAwk -fmore.exp -- [-ppath] [+/r.e.[/]] file1 file2 ...\x01b[1;31;44m";
  511.     print "Options:";
  512.     print " ppath - specifiy path to find files";
  513.     print " +/r.e./ - specify regular expression for starting search";
  514.     print "Commands:";
  515.     print "i below stands for an integer matched by {_d}.";
  516.     print "i* means the integer is optional  (match {_d}*) - 1 defaults.";
  517.     print "i+ means the integer is mandatory (match {_d}+) - no default.";
  518.     print "[\x01b[1;32;40mQq\x01b[1;31;44m](uit}?    -> exit to DOS.";
  519.     print "[\x01b[1;32;40mRr\x01b[1;31;44m](edraw)?  -> re-display last screen.";
  520.     print "[\x01b[1;32;40mFf\x01b[1;31;44m](ile)?    -> proceed to next file.";
  521.     print "[\x01b[1;32;40mNn\x01b[1;31;44m](umbers)? -> turn line numbers on/off.";
  522.     print "\x01b[1;32;40mi+\x01b[1;31;44m            -> Go To Line number i, if i > current line number.";
  523.     print "\x01b[1;32;40mi*l\x01b[1;31;44m           -> skip forward i Lines.";
  524.     print "\x01b[1;32;40mi*s\x01b[1;31;44m           -> skip forward i Screens.";
  525.     print "\x01b[1;32;40mi*/r.e./\x01b[1;31;44m      -> search for ith expression. If found begin";
  526.     print "                 display starting 'p' lines before matching line.";
  527.     print "\x01b[1;32;40mi*m\x01b[1;31;44m           -> search for next ith Match to previous";
  528.     print "                 regular expression.";
  529.     print "\x01b[1;32;40mi*p\x01b[1;31;44m           -> set number of lines prior to match to display";
  530.     print "                 defaults to 2 if i not specified.";
  531.     print "\x01b[1;32;40mi*d\x01b[1;31;44m           -> set display line length to i, 79 default";
  532.     print "\x01b[1;32;40mhi*/r.e./\x01b[1;31;44m     -> High-light text matching ith expression";
  533.     print "[\x01b[1;32;40mCc\x01b[1;31;44m](ontext)? -> Review Search and High Lighted Text Patterns";
  534. }
  535.