home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume4 / vms-vi-2 / part11 < prev    next >
Internet Message Format  |  1989-02-03  |  38KB

  1. Path: xanth!mcnc!gatech!bloom-beacon!bu-cs!mirror!necntc!ncoast!allbery
  2. From: gregg@a.cs.okstate.edu (Gregg Wonderly)
  3. Newsgroups: comp.sources.misc
  4. Subject: v04i102: TPUVI for VMS part 11 of 17
  5. Message-ID: <8809212110.AA10844@uunet.UU.NET>
  6. Date: 27 Sep 88 01:56:36 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: gregg@a.cs.okstate.edu (Gregg Wonderly)
  9. Lines: 1504
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 4, Issue 102
  13. Submitted-by: "Gregg Wonderly" <gregg@a.cs.okstate.edu>
  14. Archive-name: vms-vi-2/Part11
  15.  
  16. $ WRITE SYS$OUTPUT "Creating ""VI.7"""
  17. $ CREATE VI.7
  18. $ DECK/DOLLARS=$$EOD$$
  19.     vi$info ("Press key to bind sequence to: ");
  20.     keyn := vi$read_a_key;
  21.  
  22.     IF (keyn = F11) OR (ASCII (27) = ASCII (keyn)) THEN
  23.         vi$info ("LEARN aborted!");
  24.         com := LEARN_END;
  25.         vi$in_learn := 0;
  26.         RETURN (1);
  27.     ENDIF;
  28.  
  29.     com := LOOKUP_KEY (keyn, COMMENT, vi$cmd_keys);
  30.     IF (com = "active_macro") THEN
  31.         vi$info ("That key is a mapped key, you must unmap it first");
  32.         RETURN (1);
  33.     ENDIF;
  34.  
  35.     key := "vi$ls_"+vi$key_map_name (keyn);
  36.     EXECUTE (COMPILE (key+":=LEARN_END"));
  37.     vi$in_learn := 0;
  38.     DEFINE_KEY ("vi$play_back("+key+")", keyn, "learn_sequence", vi$cmd_keys);
  39.     vi$info ("Sequence bound to key");
  40.     RETURN (1);
  41. ENDPROCEDURE;
  42.  
  43. !
  44. !
  45. !
  46. PROCEDURE vi$play_back (prog)
  47.     LOCAL
  48.         old_play_back,
  49.         old_global;
  50.  
  51.     IF (vi$m_level > 30) THEN
  52.         vi$info ("Infinite loop detected in key macro sequence!");
  53.         RETURN;
  54.     ENDIF;
  55.     vi$m_level := vi$m_level + 1;
  56.  
  57.     IF vi$undo_map THEN
  58.         old_global := vi$in_global;
  59.         vi$in_global := 0;
  60.         IF (NOT old_global) THEN
  61.             vi$save_for_undo (CURRENT_BUFFER, VI$LINE_MODE, 1);
  62.             vi$in_global := 1;
  63.         ENDIF;
  64.     ENDIF;
  65.  
  66.     old_play_back := vi$playing_back;
  67.     vi$playing_back := 1;
  68.     EXECUTE (prog);
  69.     vi$playing_back := old_play_back;
  70.     vi$m_level := vi$m_level - 1;
  71.  
  72.     vi$in_global := old_global;
  73. ENDPROCEDURE;
  74.  
  75. !
  76. !   Remove an abbreviation
  77. !
  78. PROCEDURE vi$do_unabbr (cmd, i)
  79.     LOCAL
  80.         separ,
  81.         junk,
  82.         idx,
  83.         ch,
  84.         abbr,
  85.         abbrn;
  86.  
  87.     abbr := "";
  88.     abbrn := "";
  89.  
  90.     junk := vi$skip_separ (cmd, i, vi$_space_tab, separ);
  91.     IF (LENGTH (junk) = 0) THEN
  92.         vi$info ("Abbreviation name required!");
  93.         RETURN (1);
  94.     ENDIF;
  95.  
  96.     idx := 1;
  97.     LOOP
  98.         EXITIF idx > LENGTH (junk);
  99.         ch := SUBSTR (junk, idx, 1);
  100.         IF (INDEX (vi$_alpha_chars, ch) = 0) THEN
  101.             vi$info ("Invalid character in UNABBR name, '"+ch+
  102.                                                         "', is not valid.");
  103.             RETURN (1);
  104.         ENDIF;
  105.         IF (INDEX (vi$_upper_chars, ch) <> 0) THEN
  106.             abbrn := abbrn + "_";
  107.         ENDIF;
  108.         abbrn := abbrn + ch;
  109.         idx := idx + 1;
  110.     ENDLOOP;
  111.     EXECUTE (COMPILE ("VI$ABBR_"+abbrn+":=0;"));
  112.     RETURN (0);
  113. ENDPROCEDURE;
  114.  
  115. !
  116. !   Create an abbreviation
  117. !
  118. PROCEDURE vi$do_abbr (cmd, i)
  119.     LOCAL
  120.         separ,
  121.         abbr,
  122.         nabbr,
  123.         junk,
  124.         idx,
  125.         ch,
  126.         abbrn;
  127.  
  128.     abbr := "";
  129.     abbrn := "";
  130.  
  131.     ! Check for query.
  132.  
  133.     junk := vi$skip_separ (cmd, i, vi$_space_tab, separ);
  134.     IF (LENGTH (junk) = 0) THEN
  135.         vi$show_abbrevs;
  136.         RETURN (0);
  137.     ENDIF;
  138.  
  139.     !  Check that the abbrievation name can be part of a variable name
  140.  
  141.     idx := 1;
  142.     LOOP
  143.         EXITIF idx > LENGTH (junk);
  144.         ch := SUBSTR (junk, idx, 1);
  145.         IF (INDEX (vi$_alpha_chars, ch) = 0) THEN
  146.             vi$info ("Invalid character in ABBR name, '"+ch+"', is not valid.");
  147.             RETURN (1);
  148.         ENDIF;
  149.         IF (INDEX (vi$_upper_chars+"_", ch) <> 0) THEN
  150.             abbrn := abbrn + "_";
  151.         ENDIF;
  152.         abbrn := abbrn + ch;
  153.         idx := idx + 1;
  154.     ENDLOOP;
  155.  
  156.     abbr := vi$rest_of_line (cmd, i);
  157.  
  158.     nabbr := vi$dbl_chars ('"', abbr);
  159.     EXECUTE (COMPILE ("VI$ABBR_"+abbrn+":="""+nabbr+""""));
  160.     RETURN (0);
  161. ENDPROCEDURE;
  162.  
  163. PROCEDURE vi$dbl_chars (dch, line)
  164.  
  165.     LOCAL
  166.         ch,
  167.         idx,
  168.         nstr;
  169.  
  170.     !  Double all '"' quotes.
  171.  
  172.     idx := 1;
  173.     nstr := "";
  174.     LOOP
  175.  
  176.         EXITIF idx > LENGTH (line);
  177.         ch := SUBSTR (line, idx, 1);
  178.         IF (ch = dch) THEN
  179.             ch := dch+dch;
  180.         ENDIF;
  181.         nstr := nstr + ch;
  182.         idx := idx + 1;
  183.     ENDLOOP;
  184.  
  185.     RETURN (nstr);
  186. ENDPROCEDURE;
  187. !
  188. !   Execute the contents of the buffers named following an '@'.
  189. !
  190. PROCEDURE vi$do_macro_buffer (cmd, i)
  191.     LOCAL
  192.         line,
  193.         mode,
  194.         buf_name,
  195.         pos,
  196.         buf,
  197.         ch;
  198.  
  199.     ON_ERROR
  200.     ENDON_ERROR;
  201.  
  202.     vi$skip_white (cmd, i);
  203.  
  204.     LOOP
  205.         ch := vi$next_char (cmd, i);
  206.         EXITIF (ch = "");
  207.  
  208.         IF (INDEX ("123456789", ch) <> 0) THEN
  209.  
  210.             ! Selected a deletion buffer.
  211.  
  212.             buf_name := "vi$del_buf_" + ch;
  213.         ELSE
  214.             IF (INDEX (vi$_letter_chars, ch) <> 0) THEN
  215.  
  216.                 ! Selected a named buffer.
  217.  
  218.                 CHANGE_CASE (ch, LOWER);
  219.  
  220.                 buf_name := "vi$ins_buf_" + ch;
  221.             ELSE
  222.                 vi$info ("Invalid buffer!");
  223.                 RETURN;
  224.             ENDIF;
  225.         ENDIF;
  226.  
  227.         vi$global_var := 0;
  228.         EXECUTE (COMPILE ("vi$global_var := "+buf_name+";"));
  229.         buf := vi$global_var;
  230.         IF (buf = 0) THEN
  231.             vi$info ("There is no text in that buffer!");
  232.             RETURN;
  233.         ENDIF;
  234.  
  235.         pos := MARK (NONE);
  236.         POSITION (BEGINNING_OF (buf));
  237.  
  238.         !  Skip the buffer mode indicator.
  239.  
  240.         mode := INT (vi$current_line);
  241.         MOVE_VERTICAL (1);
  242.         line := vi$current_line;
  243.  
  244.         IF mode = VI$LINE_MODE THEN
  245.             line := line + ASCII (13);
  246.         ENDIF;
  247.  
  248.         POSITION (pos);
  249.         vi$do_macro (line, 1);
  250.     ENDLOOP;
  251.  
  252. ENDPROCEDURE;
  253.  
  254. !
  255. !   Do the ex mode 'g' and 'v' commands
  256. !
  257. PROCEDURE vi$do_global (cmd, i, cmd_ch)
  258.     LOCAL
  259.         pwin,
  260.         pbuf,
  261.         obuf,
  262.         cmd_str,
  263.         sch_str,
  264.         subs_str,
  265.         sch,
  266.         separ,
  267.         ch,
  268.         nsubs,
  269.         lpos,
  270.         opos,
  271.         olen,
  272.         fpos;
  273.  
  274.     opos := MARK (NONE);
  275.     olen := GET_INFO (CURRENT_BUFFER, "RECORD_COUNT");
  276.     vi$skip_white (cmd, i);
  277.     IF NOT vi$parse_next_ch (i, cmd, "/") THEN
  278.         vi$info ("/ Search string must follow global!");
  279.         RETURN (1);
  280.     ENDIF;
  281.  
  282.     sch := SUBSTR (cmd, i-1, 1);
  283.     sch_str := "";
  284.     LOOP
  285.         EXITIF (vi$parse_next_ch (i, cmd, sch));
  286.         EXITIF (LENGTH (cmd) < i);
  287.         ch := SUBSTR (cmd, i, 1);
  288.         IF (ch = "\") THEN
  289.             sch_str := sch_str + SUBSTR (cmd, i, 2);
  290.             i := i + 1;
  291.         ELSE
  292.             sch_str := sch_str + ch;
  293.         ENDIF;
  294.         i := i + 1;
  295.     ENDLOOP;
  296.  
  297.     IF (LENGTH (cmd) < i) THEN
  298.         vi$info ("Incomplete command! ("+cmd+")");
  299.         RETURN (1);
  300.     ENDIF;
  301.  
  302.     vi$save_for_undo (CURRENT_BUFFER, VI$LINE_MODE, 1);
  303.     cmd_str := vi$rest_of_line (cmd, i);
  304.  
  305.     SET (FORWARD, CURRENT_BUFFER);
  306.     POSITION (BEGINNING_OF (CURRENT_BUFFER));
  307.  
  308.     subs := SUBSTR (cmd_str, 1, 1) = "s";
  309.     dell := cmd_str = "d";
  310.     prt := cmd_str = "p";
  311.  
  312.     IF subs THEN
  313.         nsubs := 0;
  314.         subs_str := SUBSTR (cmd_str, 2, 255);
  315.         separ := SUBSTR (subs_str, 2, 1);
  316.         IF (SUBSTR (cmd_str,1,1)+SUBSTR (subs_str, 1, 2) = "s"+separ+separ) THEN
  317.             subs_str := separ+sch_str+separ+SUBSTR (subs_str, 3, 255);
  318.         ENDIF;
  319.     ENDIF;
  320.  
  321.     IF prt THEN
  322.         pwin := CURRENT_WINDOW;
  323.         obuf := CURRENT_BUFFER;
  324.         pbuf := vi$init_buffer ("$$prt_temp$$", "");
  325.         MAP (pwin, pbuf);
  326.         UPDATE (pwin);
  327.         POSITION (BEGINNING_OF (obuf));
  328.     ENDIF;
  329.  
  330.     LOOP
  331.         fpos := vi$find_str (sch_str, 1, 0);
  332.         EXITIF (fpos = 0) AND (cmd_ch = "g");
  333.         EXITIF (MARK (NONE) = END_OF (CURRENT_BUFFER));
  334.  
  335.         IF cmd_ch = "g" THEN
  336.             POSITION (fpos);
  337.             IF dell THEN
  338.                 ERASE_LINE;
  339.             ELSE
  340.                 IF subs THEN
  341.                     lpos := vi$global_subs (subs_str, nsubs);
  342.                     POSITION (LINE_BEGIN);
  343.                     MOVE_VERTICAL (1);
  344.                 ELSE
  345.                     IF prt THEN
  346.                         vi$prt_line (fpos, CURRENT_LINE, pbuf, pwin);
  347.                         MOVE_VERTICAL (1);
  348.                     ELSE
  349.                         vi$info ("Bad command for global! ("+cmd_str+")");
  350.                         vi$kill_undo;
  351.                         vi$undo_end := 0;
  352.                         RETURN (1);
  353.                     ENDIF;
  354.                 ENDIF;
  355.             ENDIF;
  356.         ELSE
  357.             IF cmd_ch = "v" THEN
  358.                 IF (fpos = 0) THEN
  359.                     fpos := END_OF (CURRENT_BUFFER);
  360.                 ENDIF;
  361.                 POSITION (fpos);
  362.                 POSITION (LINE_BEGIN);
  363.                 fpos := MARK (NONE);
  364.                 POSITION (opos);
  365.                 LOOP
  366.                     EXITIF (fpos = MARK(NONE));
  367.                     EXITIF (MARK (NONE) = END_OF (CURRENT_BUFFER));
  368.                     IF dell THEN
  369.                         ERASE_LINE;
  370.                     ELSE
  371.                         IF subs THEN
  372.                             lpos := vi$global_subs (subs_str, nsubs);
  373.                             POSITION (LINE_BEGIN);
  374.                             MOVE_VERTICAL (1);
  375.                         ELSE
  376.                             IF prt THEN
  377.                                 POSITION (fpos);
  378.                                 vi$prt_line (fpos, CURRENT_LINE, pbuf, pwin);
  379.                                 MOVE_VERTICAL (1);
  380.                             ELSE
  381.                                 vi$info
  382.                                     ("Bad command for global! ("+cmd_str+")");
  383.                                 vi$kill_undo;
  384.                                 vi$undo_end := 0;
  385.                                 RETURN (1);
  386.                             ENDIF;
  387.                         ENDIF;
  388.                     ENDIF;
  389.                 ENDLOOP;
  390.                 IF (MARK (NONE) <> END_OF (CURRENT_BUFFER)) THEN
  391.                     MOVE_VERTICAL (1);
  392.                 ENDIF;
  393.                 opos := MARK (NONE);
  394.             ENDIF;
  395.         ENDIF;
  396.     ENDLOOP;
  397.  
  398.     IF prt THEN
  399.         MESSAGE ("[Hit ENTER to continue]");
  400.         LOOP
  401.             EXITIF (vi$read_a_key = RET_KEY);
  402.         ENDLOOP;
  403.         MESSAGE (" ");
  404.         MAP (pwin, obuf);
  405.         DELETE (pbuf);
  406.         POSITION (opos);
  407.     ENDIF;
  408.  
  409.     IF subs THEN
  410.         vi$info (STR (nsubs) + " substitutions.");
  411.     ENDIF;
  412.  
  413.     IF (subs OR dell) THEN
  414.         POSITION (lpos);
  415.         vi$undo_end := END_OF (CURRENT_BUFFER);
  416.         vi$undo_start := BEGINNING_OF (CURRENT_BUFFER);
  417.         vi$check_length (olen);
  418.     ENDIF;
  419.  
  420.     RETURN (1);
  421. ENDPROCEDURE;
  422.  
  423. !
  424. !   Do print line for g and v EX-mode commands.
  425. !
  426. PROCEDURE vi$prt_line (opos, pline, pbuf, pwin)
  427.     POSITION (pbuf);
  428.     COPY_TEXT (pline);
  429.     SPLIT_LINE;
  430.     UPDATE (pwin);
  431.     POSITION (opos);
  432. ENDPROCEDURE;
  433.  
  434. !
  435. !   Print the range of lines indicated, in the current window.
  436. !
  437. PROCEDURE vi$do_print (where, startl, endl)
  438.  
  439.     ON_ERROR
  440.         RETURN;
  441.     ENDON_ERROR;
  442.  
  443.     POSITION (where);
  444.  
  445.     SET (FORWARD, CURRENT_BUFFER);
  446.     POSITION (LINE_BEGIN);
  447.     SCROLL (CURRENT_WINDOW, endl-startl);
  448.     vi$info ("[Hit ENTER to continue]");
  449.     LOOP
  450.         EXITIF vi$read_a_key = RET_KEY;
  451.     ENDLOOP;
  452.     vi$pos_in_middle (MARK (NONE));
  453.  
  454.     RETURN (0);
  455. ENDPROCEDURE;
  456.  
  457. !
  458. !   Change the current working directory to the string given.  A simple
  459. !   effort is made to translate the string given, but no other effort is
  460. !   made to decode the actual logicals emmbeded in the string.
  461. !
  462. PROCEDURE vi$do_cd (cmd, i)
  463.  
  464.     LOCAL
  465.         old_dir,
  466.         sysdisk,
  467.         retval,
  468.         orig_nam,
  469.         colon,
  470.         directory_name;
  471.  
  472.     ON_ERROR
  473.     ENDON_ERROR;
  474.  
  475.  
  476.     vi$skip_white (cmd, i);
  477.     directory_name := vi$rest_of_line (cmd, i);
  478.  
  479.     orig_nam := directory_name;
  480.     directory_name := CALL_USER (vi$cu_trnlnm_proc, orig_nam);
  481.     IF (directory_name = "") THEN
  482.         directory_name := CALL_USER (vi$cu_trnlnm_job, orig_nam);
  483.         IF (directory_name = "") THEN
  484.             directory_name := CALL_USER (vi$cu_trnlnm_group, orig_nam);
  485.             IF (directory_name = "") THEN
  486.                 directory_name := CALL_USER (vi$cu_trnlnm_sys, orig_nam);
  487.             ENDIF;
  488.         ENDIF;
  489.     ENDIF;
  490.  
  491.     IF (directory_name = "") THEN
  492.         directory_name := orig_nam;
  493.     ENDIF;
  494.  
  495.     colon := INDEX (directory_name, ":");
  496.     sysdisk := CALL_USER (vi$cu_trnlnm_proc, "SYS$DISK");
  497.  
  498.     IF (colon <> 0) THEN
  499.         sysdisk := SUBSTR (directory_name, 1, colon);
  500.         directory_name := SUBSTR (directory_name, colon+1, 255);
  501.         EDIT (sysdisk, UPPER,COLLAPSE);
  502.         retval := CALL_USER (vi$cu_set_sysdisk, sysdisk);
  503.     ENDIF;
  504.  
  505.     TRANSLATE (directory_name, "  ", "[]");
  506.     EDIT (directory_name, UPPER,COLLAPSE);
  507.     directory_name := '[' + directory_name + ']';
  508.     old_dir := CALL_USER (vi$cu_cwd, directory_name);
  509.     vi$info ("New directory is " + CALL_USER (vi$cu_trnlnm_proc, "SYS$DISK") +
  510.             CALL_USER (vi$cu_cwd, ""));
  511.  
  512.     RETURN (1);
  513. ENDPROCEDURE;
  514.  
  515. !
  516. !   The show command...
  517. !
  518. PROCEDURE vi$do_show (cmd, i)
  519.  
  520.     LOCAL
  521.         act;
  522.  
  523.     vi$skip_white (cmd, i);
  524.     act := vi$rest_of_line (cmd, i);
  525.     CHANGE_CASE (act, LOWER);
  526.     IF (vi$leading_str (act, "files")) THEN
  527.         vi$_show_files;
  528.     ELSE
  529.         IF (vi$leading_str (act, "buffers")) THEN
  530.             vi$_show_buffers;
  531.         ELSE
  532.             IF (vi$leading_str (act, "tags")) THEN
  533.                 vi$_show_tags;
  534.             ENDIF;
  535.         ENDIF;
  536.     ENDIF;
  537.     RETURN (0);
  538. ENDPROCEDURE;
  539.  
  540. !
  541. !   Show the current list of abbreviations that are known
  542. !
  543. PROCEDURE vi$show_abbrevs
  544.     LOCAL
  545.         buf,
  546.         loc,
  547.         varn,
  548.         rvar,
  549.         i,
  550.         idx,
  551.         ch,
  552.         strg,
  553.         vars,
  554.         errno,
  555.         pos;
  556.  
  557.     ON_ERROR
  558.         errno := ERROR;
  559.         IF (errno <> TPU$_MULTIPLENAMES) AND
  560.                                             (errno <> TPU$_STRNOTFOUND) THEN
  561.             vi$info (CALL_USER (vi$cu_getmsg, STR(errno)));
  562.             POSITION (pos);
  563.             RETURN;
  564.         ENDIF;
  565.     ENDON_ERROR;
  566.  
  567.     pos := MARK (NONE);
  568.     buf := choice_buffer;
  569.  
  570.     ERASE (buf);
  571.     vars := EXPAND_NAME ("VI$ABBR_", VARIABLES);
  572.     IF (vars = "") THEN
  573.         vi$info ("Humm, there are not any abbreviations!");
  574.         RETURN (1);
  575.     ENDIF;
  576.     POSITION (buf);
  577.     COPY_TEXT (vars);
  578.     POSITION (BEGINNING_OF (buf));
  579.     LOOP
  580.         loc := SEARCH (" ", FORWARD, EXACT);
  581.         EXITIF loc = 0;
  582.         POSITION (BEGINNING_OF (loc));
  583.         ERASE_CHARACTER (1);
  584.         SPLIT_LINE;
  585.     ENDLOOP;
  586.  
  587.     POSITION (BEGINNING_OF (buf));
  588.  
  589.     LOOP
  590.         EXITIF (MARK (NONE) = END_OF (CURRENT_BUFFER));
  591.  
  592.         IF (CURRENT_LINE = "VI$ABBR_") THEN
  593.             ERASE_LINE;
  594.         ELSE
  595.             vi$global_var := 0;
  596.             EXECUTE (COMPILE ("vi$global_var := "+CURRENT_LINE));
  597.             varn := SUBSTR (CURRENT_LINE, 9, 500);
  598.             rvar := "";
  599.             idx := 1;
  600.             LOOP
  601.                 EXITIF (vi$global_var = 0);
  602.                 EXITIF (idx > LENGTH (VARN));
  603.                 ch := SUBSTR (VARN, idx, 1);
  604.                 IF (ch = "_") THEN
  605.                     ch := SUBSTR (VARN, idx+1, 1);
  606.                     IF (INDEX (vi$_upper_chars+"_", ch) <> 0) THEN
  607.                         rvar := rvar + ch;
  608.                     ELSE
  609.                         EDIT (ch, LOWER);
  610.                         rvar := rvar + ch;
  611.                     ENDIF;
  612.                     idx := idx + 1;
  613.                 ELSE
  614.                     EDIT (ch, LOWER);
  615.                     rvar := rvar + ch;
  616.                 ENDIF;
  617.                 idx := idx + 1;
  618.             ENDLOOP;
  619.             ERASE_LINE;
  620.             IF (vi$global_var <> 0) THEN
  621.                 strg := FAO ("!20AS = >!AS<", rvar, vi$global_var);
  622.                 COPY_TEXT (strg);
  623.                 SPLIT_LINE;
  624.             ENDIF;
  625.         ENDIF;
  626.     ENDLOOP;
  627.     POSITION (BEGINNING_OF (buf));
  628.     POSITION (pos);
  629.     vi$show_list (buf,
  630.         "                              Current Abbreviations" +
  631.         "                           ",
  632.         info_window);
  633.     RETURN (0);
  634. ENDPROCEDURE;
  635.  
  636. !
  637. !   Show the current buffers and their attributes
  638. !
  639. PROCEDURE vi$_show_buffers
  640.     LOCAL
  641.         mod,
  642.         nr,
  643.         sys,
  644.         pos,
  645.         buf,
  646.         bn;
  647.  
  648.     buf := GET_INFO (BUFFERS, "FIRST");
  649.     ERASE (choice_buffer);
  650.     pos := MARK (NONE);
  651.     POSITION (choice_buffer);
  652.     LOOP
  653.         LOOP
  654.             EXITIF (buf = 0);
  655.             EXITIF (GET_INFO (buf, "SYSTEM") = 0);
  656.             buf := GET_INFO (BUFFERS, "NEXT");
  657.         ENDLOOP;
  658.         EXITIF (buf = 0);
  659.  
  660.         mod := "Not ";
  661.         IF GET_INFO (buf, "MODIFIED") THEN
  662.             mod := "";
  663.         ENDIF;
  664.  
  665.         nr := "";
  666.         IF GET_INFO (buf, "NO_WRITE") THEN
  667.             nr := "  No Write";
  668.         ENDIF;
  669.  
  670.         COPY_TEXT (FAO ("Name: !20AS   Lines: !5UL   !ASModified!AS",
  671.             GET_INFO (buf, "NAME"), GET_INFO (buf, "RECORD_COUNT"),
  672.             mod, nr));
  673.  
  674.         SPLIT_LINE;
  675.  
  676.         IF GET_INFO (buf, "OUTPUT_FILE") = 0 THEN
  677.             COPY_TEXT ("[No output file]");
  678.         ELSE
  679.             COPY_TEXT (FAO ("Output file: !AS",GET_INFO (buf, "OUTPUT_FILE")));
  680.         ENDIF;
  681.  
  682.         SPLIT_LINE;
  683.         SPLIT_LINE;
  684.         buf := GET_INFO (BUFFERS, "NEXT");
  685.     ENDLOOP;
  686.  
  687.     POSITION (BEGINNING_OF (choice_buffer));
  688.     POSITION (pos);
  689.     vi$show_list (choice_buffer,
  690.         "                   Current buffers and associated information" +
  691.         "                  ",
  692.         info_window);
  693.     RETURN (0);
  694. ENDPROCEDURE;
  695.  
  696. !
  697. !   Perform the EX mode "&" command.
  698. !
  699. PROCEDURE vi$do_subs_alias (cmd, i, start_line, end_line, whole_range)
  700.     IF vi$replace_separ = 0 THEN
  701.         vi$info ("No previous substitution!");
  702.         RETURN;
  703.     ENDIF;
  704.  
  705.     ! Rebuild a proper substitute command.
  706.  
  707.     cmd := SUBSTR (cmd, 1, i-2) + "s" +
  708.                 vi$replace_separ + vi$replace_source +
  709.                 vi$replace_separ + vi$replace_dest +
  710.                 vi$replace_separ + SUBSTR (cmd, i, 255);
  711.  
  712.     RETURN (vi$do_substitute (start_line, end_line, whole_range, i, cmd));
  713. ENDPROCEDURE;
  714.  
  715. !
  716. !   Perform the EX mode "!" command.
  717. !
  718. PROCEDURE vi$do_subproc (cmd, i)
  719.     LOCAL
  720.         tstr,
  721.         errno,
  722.         ncmd;
  723.  
  724.     cmd := vi$rest_of_line (cmd, i);
  725.     IF cmd = "!" THEN
  726.         cmd := vi$last_cmd;
  727.     ELSE
  728.         vi$last_cmd := cmd;
  729.     ENDIF;
  730.  
  731.     IF cmd = 0 THEN
  732.         vi$info ("No command on command line!");
  733.         RETURN (1);
  734.     ENDIF;
  735.  
  736.     IF cmd = "" THEN
  737.         vi$info ("Use "":sh"" to get an interactive CLI");
  738.         RETURN (1);
  739.     ENDIF;
  740.  
  741.     IF (vi$process_special (cmd, ncmd)) THEN
  742.         vi$mess_select (NONE);
  743.         vi$info (":!"+ncmd);
  744.         UPDATE (message_window);
  745.     ENDIF;
  746.  
  747.     vi$pasthru_off;
  748.     ncmd := vi$dbl_chars ('"', ncmd);
  749.     vi$spawn ('@VI$ROOT:[EXE]DOSPAWN "'+ncmd+'"');
  750.     vi$pasthru_on;
  751.     vi$mess_select (REVERSE);
  752.     RETURN (0);
  753. ENDPROCEDURE;
  754.  
  755. !
  756. !   This procedure looks at the characters in cmd, and translates occurances
  757. !   of the characters % and # to the names of the current buffers file, and
  758. !   the previously edited buffers file, respectively.
  759. !
  760. PROCEDURE vi$process_special (cmd, ncmd)
  761.  
  762.     LOCAL
  763.         idx,
  764.         redo,
  765.         ch;
  766.  
  767.     ncmd := "";
  768.     idx := 1;
  769.     redo := 0;
  770.  
  771.     LOOP
  772.         EXITIF idx > LENGTH (cmd);
  773.         ch := SUBSTR (cmd, idx, 1);
  774.         IF (ch = "%") THEN
  775.             ch := GET_INFO (CURRENT_BUFFER, "OUTPUT_FILE");
  776.             redo := 1;
  777.         ELSE
  778.             IF(ch = "#") THEN
  779.                 IF vi$last_mapped <> 0 THEN
  780.                     ch := GET_INFO (vi$last_mapped, "OUTPUT_FILE");
  781.                     redo := 1;
  782.                 ENDIF;
  783.             ENDIF;
  784.         ENDIF;
  785.         ncmd := ncmd + ch;
  786.         idx := idx + 1;
  787.     ENDLOOP;
  788.  
  789.     RETURN (redo);
  790. ENDPROCEDURE;
  791. !
  792. !   Perform the EX mode copy command.
  793. !
  794. PROCEDURE vi$do_copy (cmd, i, whole_range, olen, start_line, end_line)
  795.     LOCAL
  796.         spos,
  797.         dest;
  798.  
  799.     vi$skip_white (cmd, i);
  800.     dest := vi$get_line_spec (i, cmd);
  801.  
  802.     IF (dest > GET_INFO (CURRENT_BUFFER, "RECORD_COUNT")) THEN
  803.         dest := GET_INFO (CURRENT_BUFFER, "RECORD_COUNT");
  804.     ENDIF;
  805.  
  806.     IF ((dest < start_line) OR (dest > end_line)) AND (dest > 0) THEN
  807.         vi$move_to_line (dest + 1);
  808.         spos := vi$get_undo_start;
  809.         COPY_TEXT (whole_range);
  810.         vi$kill_undo;
  811.         MOVE_HORIZONTAL (-1);
  812.         vi$undo_end := MARK (NONE);
  813.         vi$undo_start := vi$set_undo_start (spos);
  814.     ELSE
  815.         vi$info ("Error in copy range!");
  816.         RETURN (1);
  817.     ENDIF;
  818.  
  819.     vi$check_length (olen);
  820.     RETURN (1);
  821. ENDPROCEDURE;
  822.  
  823. !
  824. !   Perform the EX mode move command.
  825. !
  826. PROCEDURE vi$do_move (cmd, i, whole_range, start_line, end_line)
  827.     LOCAL
  828.         dest;
  829.  
  830.     vi$skip_white (cmd, i);
  831.     dest := vi$get_line_spec (i, cmd);
  832.  
  833.     IF (dest > GET_INFO (CURRENT_BUFFER, "RECORD_COUNT")) THEN
  834.         dest := GET_INFO (CURRENT_BUFFER, "RECORD_COUNT");
  835.     ENDIF;
  836.  
  837.     IF ((dest < start_line) OR (dest > end_line)) AND (dest > 0) THEN
  838.         vi$move_to_line (dest+1);
  839.         vi$undo_end := 0;
  840.         vi$kill_undo;
  841.         MOVE_TEXT (whole_range);
  842.     ELSE
  843.         vi$info ("Error in move range!");
  844.         RETURN (1);
  845.     ENDIF;
  846.     RETURN (0);
  847. ENDPROCEDURE;
  848.  
  849. !
  850. !   Perform the EX mode select command.
  851. !
  852. PROCEDURE vi$do_select
  853.     IF vi$select_pos = 0 THEN
  854.         vi$select_pos := SELECT (REVERSE);
  855.         vi$info ("Selection started!");
  856.     ELSE
  857.         vi$select_pos := 0;
  858.         vi$info ("Selection canceled!");
  859.     ENDIF;
  860.     RETURN (1);
  861. ENDPROCEDURE;
  862.  
  863. !
  864. !   Perform the EX mode fill command.
  865. !
  866. PROCEDURE vi$do_fill (cmd, i, whole_range, olen)
  867.     LOCAL
  868.         separ,
  869.         token_1,
  870.         token_2;
  871.  
  872.     token_1 := vi$skip_separ (cmd, i, vi$_space_tab, separ);
  873.     token_2 := vi$skip_separ (cmd, i, vi$_space_tab, separ);
  874.     IF token_1 = "" THEN
  875.         token_1 := 0;
  876.     ELSE
  877.         token_1 := INT (token_1);
  878.     ENDIF;
  879.  
  880.     IF token_2 = "" THEN
  881.         token_2 := 0;
  882.     ELSE
  883.         token_2 := INT (token_2);
  884.     ENDIF;
  885.  
  886.     IF (vi$select_pos <> 0) THEN
  887.         cmd := SELECT_RANGE;
  888.         IF (cmd = 0) THEN
  889.             vi$info ("Nothing selected!");
  890.             RETURN (1);
  891.         ENDIF;
  892.         vi$select_pos := 0;
  893.         vi$fill_region (token_1, token_2, cmd);
  894.         MESSAGE ("");
  895.     ELSE
  896.         vi$fill_region (token_1, token_2, whole_range);
  897.     ENDIF;
  898.  
  899.     vi$info ("Fill complete!");
  900.     sleep (1);
  901.     vi$check_length (olen);
  902.     RETURN (0);
  903. ENDPROCEDURE;
  904.  
  905. !
  906. !   Perform the EX mode upper, lower, and insert commands.
  907. !
  908. PROCEDURE vi$do_case (token_1, whole_range)
  909.     LOCAL
  910.         rng,
  911.         mode,
  912.         pos,
  913.         cmd;
  914.  
  915.     IF (vi$select_pos <> 0) THEN
  916.         rng := SELECT_RANGE;
  917.         vi$select_pos := 0;
  918.         mode := VI$IN_LINE_MODE;
  919.         vi$update (CURRENT_WINDOW);
  920.     ELSE
  921.         rng := whole_range;
  922.         mode := VI$LINE_MODE;
  923.     ENDIF;
  924.  
  925.     cmd := UPPER;
  926.     IF SUBSTR (token_1, 1, 1) = "l" THEN
  927.         cmd := LOWER;
  928.     ELSE
  929.         IF (SUBSTR (token_1, 1, 1) = "i") THEN
  930.             cmd := INVERT;
  931.         ENDIF;
  932.     ENDIF;
  933.  
  934.     vi$undo_start := BEGINNING_OF (rng);
  935.     vi$undo_end := END_OF (rng);
  936.     pos := MARK (NONE);
  937.     POSITION (BEGINNING_OF (rng));
  938.     vi$save_for_undo (rng, mode, 1);
  939.     POSITION (pos);
  940.     CHANGE_CASE (rng, cmd);
  941.     rng := 0;
  942.     RETURN (0);
  943. ENDPROCEDURE;
  944.  
  945. !
  946. !   Perform the EX mode delete command.
  947. !
  948. PROCEDURE vi$do_delete (start_mark, whole_range, olen)
  949.     POSITION (start_mark);
  950.     IF (MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER)) THEN
  951.         MOVE_HORIZONTAL (-1);
  952.         vi$undo_start := MARK (NONE);
  953.     ELSE
  954.         vi$undo_start := 0;
  955.     ENDIF;
  956.  
  957.     vi$save_for_undo (whole_range, VI$LINE_MODE, 1);
  958.     vi$undo_end := 0;
  959.     ERASE (whole_range);
  960.     IF (vi$undo_start <> 0) THEN
  961.         POSITION (vi$undo_start);
  962.         MOVE_HORIZONTAL (1);
  963.         vi$undo_start := MARK (NONE);
  964.     ELSE
  965.         vi$undo_start := BEGINNING_OF (CURRENT_BUFFER);
  966.     ENDIF;
  967.     vi$check_length (olen);
  968.     RETURN (0);
  969. ENDPROCEDURE;
  970.  
  971. !
  972. !   Perform the EX mode write command.
  973. !
  974. PROCEDURE vi$do_write (cmd, i, no_spec, token_1, whole_range)
  975.     LOCAL
  976.         range_used,
  977.         outf,
  978.         res_spec,
  979.         ncmd,
  980.         buf,
  981.         win,
  982.         owin,
  983.         bang,
  984.         proc,
  985.         token_2;
  986.  
  987.     ON_ERROR
  988.         IF ERROR = TPU$_PARSEFAIL THEN
  989.             vi$info ("Don't understand filename, '"+token_2+"'");
  990.             RETURN (1);
  991.         ENDIF;
  992.     ENDON_ERROR;
  993.  
  994.     bang := vi$parse_next_ch (i, cmd, "!");
  995.     vi$skip_white (cmd, i);
  996.  
  997.     IF (vi$parse_next_ch (i, cmd, "!")) THEN
  998.         buf := vi$init_buffer ("$$filt_temp$$", "");
  999.         win := CREATE_WINDOW (1, vi$scr_length-1, ON);
  1000.         owin := CURRENT_WINDOW;
  1001.         IF (buf = 0) OR (win = 0) THEN
  1002.             vi$info ("Can't get buffer and window for command!");
  1003.             RETURN (1);
  1004.         ENDIF;
  1005.  
  1006.         SET (STATUS_LINE, win, REVERSE,
  1007.                             "*Output from command: "+vi$rest_of_line (cmd,i));
  1008.         MAP (win, buf);
  1009.         UPDATE (win);
  1010.         vi$pasthru_off;
  1011.         proc := CREATE_PROCESS (buf, vi$rest_of_line (cmd, i));
  1012.         IF proc <> 0 THEN
  1013.             SEND (whole_range, proc);
  1014.             IF proc <> 0 THEN
  1015.                 SEND_EOF (proc);
  1016.             ENDIF;
  1017.         ENDIF;
  1018.         UPDATE (win);
  1019.         vi$info ("[Hit RETURN to continue]");
  1020.         LOOP
  1021.             EXITIF vi$read_a_key = RET_KEY;
  1022.         ENDLOOP;
  1023.  
  1024.         vi$pasthru_on;
  1025.         UNMAP (win);
  1026.         DELETE (win);
  1027.         DELETE (buf);
  1028.         POSITION (owin);
  1029.         RETURN (1);
  1030.     ENDIF;
  1031.  
  1032.     range_used := 0;
  1033.     IF (no_spec) AND (vi$select_pos <> 0) THEN
  1034.         whole_range := SELECT_RANGE;
  1035.         no_spec := 0;
  1036.         range_used := 1;
  1037.     ENDIF;
  1038.  
  1039.     vi$skip_white (cmd, i);
  1040.     ncmd := vi$rest_of_line (cmd, i);
  1041.     vi$process_special (ncmd, token_2);
  1042.  
  1043.     IF (token_2 <> "") THEN
  1044.         res_spec := FILE_PARSE (token_2);
  1045.  
  1046.         outf := FILE_SEARCH ("");
  1047.         outf := FILE_SEARCH (res_spec);
  1048.         IF (outf <> "") AND
  1049.                 (outf <> GET_INFO (CURRENT_BUFFER, "OUTPUT_FILE")) AND
  1050.                 NOT bang THEN
  1051.             vi$info (token_2 +
  1052.                         ' exists - use "' +
  1053.                         token_1 +
  1054.                         '! ' +
  1055.                         token_2 +
  1056.                         '" to overwrite.');
  1057.             RETURN (1);
  1058.         ELSE
  1059.             vi$info ("Writing out """+res_spec+"""");
  1060.             IF (no_spec = 0) THEN
  1061.                 WRITE_FILE (whole_range, res_spec);
  1062.             ELSE
  1063.                 WRITE_FILE (CURRENT_BUFFER, res_spec);
  1064.             ENDIF;
  1065.         ENDIF;
  1066.     ELSE
  1067.         IF (no_spec = 0) THEN
  1068.             IF bang THEN
  1069.                 vi$info ('Use "w!" to write partial buffer');
  1070.                 outf := "";
  1071.             ELSE
  1072.                 outf := GET_INFO (CURRENT_BUFFER, "OUTPUT_FILE");
  1073.                 IF outf <> "" THEN
  1074.                     vi$info ("Writing out """+outf+"""");
  1075.                     outf := WRITE_FILE (whole_range, outf);
  1076.                 ELSE
  1077.                     vi$info ("Buffer has no output file!");
  1078.                 ENDIF;
  1079.             ENDIF;
  1080.         ELSE
  1081.             IF (vi$can_write (CURRENT_BUFFER)) THEN
  1082.                 vi$info ("Writing out """+
  1083.                                 GET_INFO (CURRENT_BUFFER, "NAME")+"""");
  1084.                 outf := WRITE_FILE (CURRENT_BUFFER);
  1085.             ELSE
  1086.                 RETURN;
  1087.             ENDIF
  1088.         ENDIF;
  1089.  
  1090.         IF (outf <> "") THEN
  1091.             SET (OUTPUT_FILE, CURRENT_BUFFER, outf);
  1092.         ENDIF;
  1093.     ENDIF;
  1094.  
  1095.     IF range_used THEN
  1096.         vi$select_pos := 0;
  1097.     ENDIF;
  1098.  
  1099.     vi$kill_undo;
  1100.     vi$undo_end := 0;
  1101.  
  1102.     ! Always leave message visible
  1103.  
  1104.     RETURN (1);
  1105. ENDPROCEDURE;
  1106.  
  1107. !
  1108. !   Check to see if a buffer is readonly or not.
  1109. !
  1110. PROCEDURE vi$can_write (buf)
  1111.     LOCAL
  1112.         bmode;
  1113.  
  1114.     bmode := vi$getbufmode (buf);
  1115.     IF (bmode) THEN
  1116.         vi$info (FAO ("!AS is set readonly", GET_INFO (buf, "NAME")));
  1117.     ENDIF;
  1118.  
  1119.     RETURN (bmode = 0);
  1120. ENDPROCEDURE;
  1121.  
  1122. !
  1123. !   Perform the EX mode read command.
  1124. !
  1125. PROCEDURE vi$do_read (cmd, i, start_line, olen)
  1126.     LOCAL
  1127.         outf,
  1128.         spos,
  1129.         epos,
  1130.         ret,
  1131.         token_2,
  1132.         token_3;
  1133.  
  1134.     token_3 := vi$rest_of_line (cmd, i);
  1135.     vi$process_special (token_3, token_2);
  1136.     i := 1;
  1137.     vi$skip_white (token_3, i);
  1138.     IF (vi$parse_next_ch (i, token_3, "!")) THEN
  1139.         POSITION (LINE_BEGIN);
  1140.         vi$move_vertical (1);
  1141.         SPLIT_LINE;
  1142.         MOVE_HORIZONTAL (-1);
  1143.         vi$kill_undo;
  1144.         epos := MARK (NONE);
  1145.         spos := MARK (NONE);
  1146.         vi$undo_start := vi$get_undo_start;
  1147.         ret := vi$filter_region (CREATE_RANGE (spos, epos, NONE),
  1148.                 vi$rest_of_line (token_3, i));
  1149.         MOVE_HORIZONTAL (-1);
  1150.         vi$undo_end := MARK (NONE);
  1151.         vi$undo_start := vi$set_undo_start (vi$undo_start);
  1152.         POSITION (vi$undo_start);
  1153.         RETURN (ret);
  1154.     ENDIF;
  1155.  
  1156.     token_3 := vi$rest_of_line (cmd, i);
  1157.     vi$process_special (token_3, token_2);
  1158.  
  1159.     IF (token_2 <> "") THEN
  1160.         token_2 := FILE_PARSE (token_2);
  1161.         outf := FILE_SEARCH ("");
  1162.         outf := FILE_SEARCH (token_2);
  1163.         IF (outf <> "") THEN
  1164.             IF (start_line > 0) THEN
  1165.                 POSITION (BEGINNING_OF (CURRENT_BUFFER));
  1166.                 MOVE_VERTICAL (start_line - 1);
  1167.             ENDIF;
  1168.             POSITION (LINE_BEGIN);
  1169.             IF (MARK (NONE) = END_OF (CURRENT_BUFFER)) THEN
  1170.                 SPLIT_LINE;
  1171.             ELSE
  1172.                 MOVE_VERTICAL (1);
  1173.             ENDIF;
  1174.             MOVE_HORIZONTAL (-1);
  1175.             spos := MARK (NONE);
  1176.             MOVE_HORIZONTAL (1);
  1177.             outf := READ_FILE (outf);
  1178.             IF (outf <> "") THEN
  1179.                 MOVE_HORIZONTAL (-1);
  1180.                 vi$undo_end := MARK (NONE);
  1181.                 vi$kill_undo;
  1182.                 POSITION (spos);
  1183.                 MOVE_HORIZONTAL (1);
  1184.                 vi$undo_start := MARK (NONE);
  1185.             ENDIF;
  1186.         ELSE
  1187.             vi$info (token_2 + " does not exist!");
  1188.         ENDIF;
  1189.     ELSE
  1190.         vi$info ("Filename required!");
  1191.     ENDIF;
  1192.     vi$check_length (olen);
  1193.  
  1194.     ! Always leave last message visible
  1195.  
  1196.     RETURN (1);
  1197. ENDPROCEDURE;
  1198.  
  1199. !
  1200. !   Perform the EX mode file command.
  1201. !
  1202. PROCEDURE vi$do_file_ex (cmd, i)
  1203.     LOCAL
  1204.         token_2;
  1205.  
  1206.     ON_ERROR
  1207.         IF ERROR = TPU$_PARSEFAIL THEN
  1208.             vi$info ("Don't understand filename: "+token_2);
  1209.         ENDIF;
  1210.     ENDON_ERROR;
  1211.  
  1212.     token_2 := vi$rest_of_line (cmd, i);
  1213.     IF (token_2 <> "") THEN
  1214.         token_2 := FILE_PARSE (token_2);
  1215.         SET (OUTPUT_FILE, CURRENT_BUFFER, token_2);
  1216.         vi$status_lines (CURRENT_BUFFER);
  1217.     ENDIF;
  1218.     vi$what_line;
  1219.  
  1220.     RETURN (1);
  1221. ENDPROCEDURE;
  1222.  
  1223. !
  1224. !   Perform the EX mode buffer command.
  1225. !
  1226. PROCEDURE vi$do_buffer (cmd, i, token_1)
  1227.  
  1228.     LOCAL
  1229.         buf,
  1230.         cbuf,
  1231.         bang,
  1232.         separ,
  1233.         token_2,
  1234.         token_3;
  1235.  
  1236.     ON_ERROR
  1237.         IF ERROR = TPU$_PARSEFAIL THEN
  1238.             vi$info ("Don't understand filename given!");
  1239.             RETURN (1);
  1240.         ENDIF;
  1241.     ENDON_ERROR;
  1242.  
  1243.     bang := vi$parse_next_ch (i, cmd, "!");
  1244.     buf := 0;
  1245.     cbuf := CURRENT_BUFFER;
  1246.  
  1247.     token_2 := vi$skip_separ (cmd, i, vi$_space_tab, separ);
  1248.     token_3 := vi$skip_separ (cmd, i, vi$_space_tab, separ);
  1249.  
  1250.     IF (vi$rest_of_line (cmd, i) <> "") THEN
  1251.         vi$info ("Too many paramters!");
  1252.         RETURN (1);
  1253.     ENDIF;
  1254.  
  1255.     IF (token_2 <> "") THEN
  1256.         IF (token_3 = "") THEN
  1257.             buf := vi$find_buffer_by_name (token_2);
  1258.             IF buf = 0 THEN
  1259.                 buf := vi$_create_buffer (token_2, 0, 0);
  1260.             ENDIF;
  1261.         ELSE
  1262.             token_3 := FILE_PARSE (token_3);
  1263.             buf := vi$_create_buffer (token_2, token_3, token_3);
  1264.         ENDIF;
  1265.  
  1266.         IF (buf <> 0) THEN
  1267.             POSITION (cbuf);
  1268.             IF (vi$check_auto_write) THEN
  1269.                 RETURN;
  1270.             ENDIF;
  1271.             MAP (CURRENT_WINDOW, buf);
  1272.             vi$set_status_line (CURRENT_WINDOW);
  1273.         ENDIF;
  1274.     ELSE
  1275.         vi$what_line;
  1276.     ENDIF;
  1277.  
  1278.     vi$kill_undo;
  1279.     vi$undo_end := 0;
  1280.     RETURN (1);
  1281. ENDPROCEDURE;
  1282.  
  1283. !
  1284. !   Perform the EX mode "vi" and/or "edit" commands.
  1285. !
  1286. PROCEDURE vi$do_edit (cmd, i, token_1)
  1287.     LOCAL
  1288.         buf,
  1289.         bang,
  1290.         num,
  1291.         look,
  1292.         ch,
  1293.         endch,
  1294.         token_2;
  1295.  
  1296.     num := -1;
  1297.     look := -1;
  1298.  
  1299.     bang := vi$parse_next_ch (i, cmd, "!");
  1300.     vi$skip_white (cmd, i);
  1301.     IF vi$parse_next_ch (i, cmd, "+") THEN
  1302.         ! Get a goto spec.
  1303.         IF vi$parse_next_ch (i, cmd, "/") THEN
  1304.             ! Get a search string
  1305.             look := "";
  1306.             IF vi$parse_next_ch (i, cmd, '"') THEN
  1307.                 endch := '"';
  1308.             ELSE
  1309.                 endch := " ";
  1310.             ENDIF;
  1311.             LOOP
  1312.                 ch := vi$next_char (cmd, i);
  1313.                 EXITIF (endch = ch) OR (ch = "");
  1314.                 IF (ch = "/") THEN
  1315.                     ch := vi$next_char (cmd, i);
  1316.                     IF ch <> '"' THEN
  1317.                         ch := "/" + ch;
  1318.                     ENDIF;
  1319.                 ENDIF;
  1320.                 look := look + ch;
  1321.             ENDLOOP;
  1322.             vi$skip_white (cmd, i);
  1323.         ELSE
  1324.             ! Get a number
  1325.             num := "";
  1326.             LOOP
  1327.                 EXITIF INDEX (vi$_numeric_chars, SUBSTR (cmd, i, 1)) = 0;
  1328.                 num := num + vi$next_char (cmd, i);
  1329.             ENDLOOP;
  1330.             vi$skip_white (cmd, i);
  1331.             num := INT (num);
  1332.         ENDIF;
  1333.     ENDIF;
  1334.     token_2 := vi$rest_of_line (cmd, i);
  1335.  
  1336.     ! Check for use of % as file name, this means current file, so it is
  1337.     ! synonomous with specifying no filename.
  1338.  
  1339.     IF (token_2 = "") OR (token_2 = "%") THEN
  1340.         IF (NOT bang) AND (GET_INFO (CURRENT_BUFFER, "MODIFIED")) THEN
  1341.             vi$info ("No write since last change, use """ +
  1342.                      token_1 + "!"" to override");
  1343.             RETURN (1);
  1344.         ENDIF;
  1345.  
  1346.         token_2 := GET_INFO (CURRENT_BUFFER, "FILE_NAME");
  1347.         IF (token_2 = 0) OR (token_2 = "") THEN
  1348.             vi$info ("Buffer has no file!");
  1349.             RETURN (1);
  1350.         ENDIF;
  1351.  
  1352.         ! Get everything but the version.
  1353.  
  1354.         token_2 := FILE_PARSE (token_2, "", "", DEVICE) +
  1355.                      FILE_PARSE (token_2, "", "", DIRECTORY) +
  1356.                      FILE_PARSE (token_2, "", "", NAME) +
  1357.                      FILE_PARSE (token_2, "", "", TYPE);
  1358.  
  1359.         buf := CURRENT_BUFFER;
  1360.         MAP (CURRENT_WINDOW, MESSAGE_BUFFER);
  1361.         POSITION (MESSAGE_BUFFER);
  1362.         DELETE (buf);
  1363.     ENDIF;
  1364.  
  1365.     ! Check for abbreviation for previous file, and just swap buffers if
  1366.     ! that is the case.
  1367.  
  1368.     IF (token_2 = "#") THEN
  1369.         vi$move_prev_buf (bang);
  1370.     ELSE
  1371.         vi$get_file (token_2);
  1372.         vi$pos_in_middle (MARK (NONE));
  1373.         vi$kill_undo;
  1374.         vi$undo_end := 0;
  1375.     ENDIF;
  1376.     IF (num <> -1) THEN
  1377.         vi$move_to_line (num);
  1378.         vi$pos_in_middle (MARK (NONE));
  1379.     ELSE
  1380.         IF (look <> -1) THEN
  1381.             vi$search_string := look;
  1382.             num := vi$find_str (look, 0, 0);
  1383.             IF (num <> 0) THEN
  1384.                 vi$beep_position (num, 1, 1);
  1385.                 vi$pos_in_middle (MARK (NONE));
  1386.             ENDIF;
  1387.         ENDIF;
  1388.     ENDIF;
  1389.     RETURN (1);
  1390. ENDPROCEDURE;
  1391.  
  1392. !
  1393. !   Perform the EX mode messages command.
  1394. !
  1395. PROCEDURE vi$do_messages
  1396.     vi$last_mapped := CURRENT_BUFFER;
  1397.     MAP (CURRENT_WINDOW, MESSAGE_BUFFER);
  1398.     POSITION (MESSAGE_BUFFER);
  1399.     vi$set_status_line (CURRENT_WINDOW);
  1400.     vi$kill_undo;
  1401.     vi$undo_end := 0;
  1402.     RETURN (0);
  1403. ENDPROCEDURE;
  1404.  
  1405. !
  1406. !   Perform the EX mode tag command.
  1407. !
  1408. PROCEDURE vi$do_tag (tag_str, bang);
  1409.     vi$load_tags;
  1410.     RETURN (vi$to_tag (tag_str, bang));
  1411. ENDPROCEDURE;
  1412.  
  1413. !
  1414. !   Load the tags files into a buffer
  1415. !
  1416. PROCEDURE vi$load_tags
  1417.     LOCAL
  1418.         idx,
  1419.         fname,
  1420.         ch,
  1421.         flist,
  1422.         pos;
  1423.  
  1424.     ON_ERROR
  1425.     ENDON_ERROR;
  1426.  
  1427.     pos := MARK (NONE);
  1428.     ERASE (vi$tag_buf);
  1429.  
  1430.     POSITION (BEGINNING_OF (vi$tag_buf));
  1431.     idx := 0;
  1432.     fname := "";
  1433.  
  1434.     flist := vi$tag_files + " ";
  1435.     LOOP
  1436.         EXITIF (idx > LENGTH(flist));
  1437.         ch := SUBSTR (flist, idx, 1);
  1438.         IF (INDEX (vi$_space_tab, ch) <> 0) AND (fname <> "") THEN
  1439.             vi$info_success_off;
  1440.             fname := FILE_PARSE (fname);
  1441.             IF (fname <> "") AND (FILE_SEARCH (fname) <> "") THEN
  1442.                 READ_FILE (FILE_PARSE (fname));
  1443.             ENDIF;
  1444.             vi$info_success_on;
  1445.             fname := "";
  1446.         ELSE
  1447.             IF (INDEX (vi$_space_tab, ch) = 0) THEN
  1448.                 fname := fname + ch;
  1449.             ENDIF;
  1450.         ENDIF;
  1451.         idx := idx + 1;
  1452.     ENDLOOP;
  1453.  
  1454.     POSITION (pos);
  1455.     RETURN (0);
  1456. ENDPROCEDURE;
  1457.  
  1458. !
  1459. !   Position to the tag given or use the current symbol in the buffer
  1460. !
  1461. PROCEDURE vi$to_tag (tag, bang)
  1462.     LOCAL
  1463.         fname,
  1464.         sch_pat,
  1465.         tloc,
  1466.         pos;
  1467.  
  1468.     ON_ERROR
  1469.     ENDON_ERROR;
  1470.  
  1471.     pos := MARK (NONE);
  1472.  
  1473.     ! Read the symbol name from the CURRENT location in the buffer.
  1474.  
  1475.     IF (tag = 0) THEN
  1476.         tag := vi$sym_name;
  1477.     ENDIF;
  1478.  
  1479.     IF (tag = "") THEN
  1480.         vi$info ("Bad tag name");
  1481.         POSITION (pos);
  1482.         RETURN (1);
  1483.     ENDIF;
  1484.  
  1485.     POSITION (BEGINNING_OF (vi$tag_buf));
  1486.     IF (MARK (NONE) = END_OF (vi$tag_buf)) THEN
  1487.         vi$info ("NO tags file!");
  1488.         POSITION (pos);
  1489.         RETURN (1);
  1490.     ENDIF;
  1491.  
  1492.     vi$global_var := 0;
  1493.     EXECUTE (COMPILE ("vi$global_var := LINE_BEGIN & '"+tag+ASCII(9)+"'"));
  1494.  
  1495.     vi$info_success_off;
  1496.     tloc := SEARCH (vi$global_var, FORWARD, vi$tag_case);
  1497.     vi$info_success_on;
  1498.  
  1499.     IF (tloc <> 0) THEN
  1500.         POSITION (END_OF (tloc));
  1501.         MOVE_HORIZONTAL (1);
  1502.         fname := vi$space_word;
  1503.         sch_pat := SUBSTR (CURRENT_LINE, CURRENT_OFFSET+2, 1024);
  1504.         POSITION (pos);
  1505.  
  1506.         IF (NOT bang) AND (vi$check_auto_write) THEN
  1507.             RETURN (1);
  1508.         ENDIF;
  1509.  
  1510.         IF (vi$get_file (fname) > 0) THEN
  1511.             POSITION (END_OF (CURRENT_BUFFER));
  1512.             IF (vi$do_cmd_line (sch_pat)) THEN
  1513.                 POSITION (BEGINNING_OF (CURRENT_BUFFER));
  1514.                 vi$info ("Tag not found!");
  1515. $$EOD$$
  1516.