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

  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: v04i103: TPUVI for VMS part 12 of 17
  5. Message-ID: <8809212110.AA10951@uunet.UU.NET>
  6. Date: 27 Sep 88 01:57:50 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: gregg@a.cs.okstate.edu (Gregg Wonderly)
  9. Lines: 1503
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 4, Issue 103
  13. Submitted-by: "Gregg Wonderly" <gregg@a.cs.okstate.edu>
  14. Archive-name: vms-vi-2/Part12
  15.  
  16. $ WRITE SYS$OUTPUT "Creating ""VI.8"""
  17. $ CREATE VI.8
  18. $ DECK/DOLLARS=$$EOD$$
  19.                 RETURN (1);
  20.             ENDIF;
  21.             vi$pos_in_middle (MARK (NONE));
  22.         ENDIF;
  23.     ELSE
  24.         POSITION (pos);
  25.         vi$info ("Tag not in tags file");
  26.         RETURN (1);
  27.     ENDIF;
  28.     RETURN (0);
  29. ENDPROCEDURE;
  30.  
  31. !
  32. !   Return the word that is spanned by characters in the symbol set.
  33. !
  34. PROCEDURE vi$sym_name
  35.     LOCAL
  36.         ch;
  37.  
  38.     ch := "";
  39.     LOOP
  40.         EXITIF INDEX (vi$_sym_chars, CURRENT_CHARACTER) = 0;
  41.         ch := ch + CURRENT_CHARACTER;
  42.         MOVE_HORIZONTAL (1);
  43.     ENDLOOP;
  44.     RETURN (ch);
  45. ENDPROCEDURE;
  46.  
  47. !
  48. !   Return the word that is spanned by non-blank characters.
  49. !
  50. PROCEDURE vi$space_word
  51.     LOCAL
  52.         ch;
  53.  
  54.     ch := "";
  55.     LOOP
  56.         EXITIF (CURRENT_CHARACTER = " ") OR (CURRENT_CHARACTER = ASCII (9));
  57.         ch := ch + CURRENT_CHARACTER;
  58.         MOVE_HORIZONTAL (1);
  59.     ENDLOOP;
  60.     RETURN (ch);
  61. ENDPROCEDURE;
  62.  
  63. !
  64. !   Perform the EX mode tpu command.
  65. !
  66. PROCEDURE vi$do_tpu (cmd, i, no_spec, whole_range)
  67.  
  68.     ON_ERROR
  69.         RETURN (1);
  70.     ENDON_ERROR;
  71.  
  72.     IF no_spec AND (vi$rest_of_line (cmd, i) <> "") THEN
  73.         EXECUTE (COMPILE (vi$rest_of_line (cmd, i)));
  74.     ELSE
  75.         vi$info ("Compiling...");
  76.         IF no_spec AND (vi$rest_of_line (cmd, i) = "") THEN
  77.             IF (vi$select_pos <> 0) THEN
  78.                 EXECUTE (COMPILE (SELECT_RANGE));
  79.                 vi$select_pos := 0;
  80.                 MESSAGE ("");
  81.             ELSE
  82.                 vi$info ("Nothing selected to compile!");
  83.                 RETURN (1);
  84.             ENDIF;
  85.         ELSE
  86.             COMPILE (whole_range);
  87.         ENDIF;
  88.     ENDIF;
  89.  
  90.     RETURN (1);
  91. ENDPROCEDURE;
  92.  
  93. !
  94. !
  95. !
  96. PROCEDURE vi$do_wq (cmd, i, no_spec, token_1, whole_range)
  97.     vi$do_write (cmd, i, no_spec, token_1, whole_range);
  98.     vi$do_quit (cmd, token_1);
  99.     RETURN (1);
  100. ENDPROCEDURE;
  101. !
  102. !   Perform the EX mode quit command.
  103. !
  104. PROCEDURE vi$do_quit (cmd, token_1)
  105.     LOCAL
  106.         buf;
  107.  
  108.     buf := GET_INFO (BUFFERS, "FIRST");
  109.     LOOP
  110.         EXITIF buf = 0;
  111.         IF GET_INFO (buf, "MODIFIED") AND
  112.                                         (NOT GET_INFO (buf, "SYSTEM")) THEN
  113.             IF NOT GET_INFO (buf, "NO_WRITE") THEN
  114.                 IF INDEX (cmd, "!") <> 0 THEN
  115.                     SET (NO_WRITE, buf);
  116.                 ELSE
  117.                     vi$info ("No write of buffer """+GET_INFO (buf, "NAME") +
  118.                              """ since last change, use """+token_1 +
  119.                              "!"" to override.");
  120.                     RETURN (1);
  121.                 ENDIF;
  122.             ENDIF;
  123.         ENDIF;
  124.         buf := GET_INFO (BUFFERS, "NEXT");
  125.     ENDLOOP;
  126.     vi$quit;
  127.     RETURN (1);
  128. ENDPROCEDURE;
  129.  
  130. !
  131. !  Delete the buffer given by the name passed as the parameter.  The buffer
  132. !  must not be the current buffer, or if it is, there must be more than
  133. !  one buffer on the screen.
  134. !
  135. PROCEDURE vi$do_delbuf (cmd, i)
  136.  
  137.     LOCAL
  138.         win,
  139.         confirm,
  140.         possible_buffer,
  141.         possible_buffer_name,
  142.         found_a_buffer,
  143.         how_many_buffers,
  144.         this_buffer,
  145.         loop_buffer,
  146.         bang,
  147.         buffer_name;
  148.  
  149.     ! Get the buffer name, solving abiguity problems.
  150.  
  151.     bang := vi$parse_next_ch (i, cmd, "!");
  152.     vi$skip_white (cmd, i);
  153.     buffer_name := vi$rest_of_line (cmd, i);
  154.     CHANGE_CASE (buffer_name, UPPER);   ! for messages
  155.     loop_buffer := vi$find_buffer_by_name (buffer_name);
  156.  
  157.     IF (loop_buffer <> 0) THEN
  158.         buffer_name := GET_INFO (loop_buffer, "NAME");
  159.  
  160.         ! Now, we must first delete all windows mapped to this buffer.
  161.  
  162.         win := GET_INFO (WINDOWS, "FIRST");
  163.         LOOP
  164.             EXITIF (win = 0);
  165.             EXITIF (GET_INFO (loop_buffer, "MAP_COUNT") = 0);
  166.  
  167.             ! See if current window is mapped to this buffer.
  168.  
  169.             IF (GET_INFO (win, "BUFFER") = loop_buffer) THEN
  170.  
  171.                 ! If so, there must be a previous or a next window to move to.
  172.                 ! If there is not, then we can not delete the buffer until
  173.                 ! another buffer (and window) are available to move to.
  174.  
  175.                 IF (vi$prev_win (win) <> 0) OR (vi$next_win(win) <> 0) THEN
  176.                     POSITION (win);
  177.                     vi$del_win (win);
  178.  
  179.                     ! Restart at beginning of list.  Deleting a window will
  180.                     ! make "NEXT" not work.
  181.  
  182.                     win := GET_INFO (WINDOWS, "FIRST");
  183.                 ELSE
  184.                     vi$info ("Can't unmap all windows that are mapped to """ +
  185.                                                         buffer_name + """!");
  186.                     RETURN (1);
  187.                 ENDIF;
  188.             ELSE
  189.                 win := GET_INFO (WINDOWS, "NEXT");
  190.             ENDIF;
  191.         ENDLOOP;
  192.     ELSE
  193.         vi$info ("No such buffer, "+buffer_name);
  194.         RETURN (1);
  195.     ENDIF;
  196.  
  197.     CHANGE_CASE (buffer_name, UPPER);
  198.     IF (GET_INFO (loop_buffer, "MAP_COUNT") = 0) THEN
  199.         IF (GET_INFO (loop_buffer, "MODIFIED") AND NOT bang) THEN
  200.             confirm := READ_LINE ("Delete modified buffer, """+
  201.                                                         buffer_name+"""? ");
  202.  
  203.             EDIT (confirm, UPPER);
  204.             IF (SUBSTR (confirm, 1, 1) <> "Y") THEN
  205.                 vi$info ("Buffer NOT deleted!");
  206.                 RETURN (1);
  207.             ENDIF;
  208.         ENDIF;
  209.  
  210.         DELETE (loop_buffer);
  211.         vi$info ("Buffer, """+buffer_name+""", deleted!");
  212.     ELSE
  213.         vi$info ("Can't delete """+buffer_name+
  214.                                         """, it is still mapped to a window!");
  215.         RETURN (1);
  216.     ENDIF;
  217.  
  218. !   Normally we would return 0, but the above message must remain visible.
  219.  
  220.     RETURN (1);
  221. ENDPROCEDURE;
  222. !
  223. !   Return the proper value of a MARKER that indicates the previous position
  224. !   in the current buffer.
  225. !
  226. PROCEDURE vi$get_undo_start
  227.     LOCAL
  228.         pos;
  229.  
  230.     IF (MARK (NONE) = BEGINNING_OF (CURRENT_BUFFER)) THEN
  231.         RETURN (0);
  232.     ELSE
  233.         MOVE_HORIZONTAL (-1);
  234.         pos := MARK (NONE);
  235.         MOVE_HORIZONTAL (1);
  236.         RETURN (pos);
  237.     ENDIF;
  238. ENDPROCEDURE;
  239.  
  240. !
  241. !   Use "spos" to determine where "vi$undo_start" should be set.
  242. !
  243. PROCEDURE vi$set_undo_start (spos)
  244.     IF spos = 0 THEN
  245.         RETURN (BEGINNING_OF (CURRENT_BUFFER));
  246.     ELSE
  247.         POSITION (spos);
  248.         MOVE_HORIZONTAL (1);
  249.         RETURN (MARK (NONE));
  250.     ENDIF;
  251. ENDPROCEDURE;
  252.  
  253. !
  254. !  If this was real VI under UNIX, all you would need to do is filter text
  255. !  through NROFF...  sigh...  I guess you can't have it all?
  256. !
  257. PROCEDURE vi$fill_region (leftm, rightm, rng)
  258.     LOCAL
  259.         pos,
  260.         tend,
  261.         spos,
  262.         beg;
  263.  
  264.     IF (leftm = 0) THEN
  265.         leftm := 1;
  266.     ENDIF;
  267.  
  268.     IF (rightm = 0) THEN
  269.         rightm := vi$scr_width - vi$wrap_margin;
  270.     ENDIF;
  271.  
  272.     POSITION (BEGINNING_OF (rng));
  273.     LOOP
  274.         EXITIF (CURRENT_CHARACTER <> " ") AND (CURRENT_CHARACTER <> ASCII (9));
  275.         MOVE_HORIZONTAL (1);
  276.         EXITIF (MARK (NONE) = END_OF (rng));
  277.     ENDLOOP;
  278.  
  279.     beg := MARK (NONE);
  280.     POSITION (END_OF (rng));
  281.     MOVE_HORIZONTAL (-1);
  282.     tend := MARK (NONE);
  283.     rng := CREATE_RANGE (beg, tend, NONE);
  284.     POSITION (BEGINNING_OF (rng));
  285.     vi$save_for_undo (rng, VI$IN_LINE_MODE, 1);
  286.     spos := vi$get_undo_start;
  287.  
  288.     FILL (rng, " ", leftm, rightm);
  289.     vi$undo_end := MARK (NONE);
  290.     vi$undo_start := vi$set_undo_start (spos);
  291.     POSITION (vi$undo_start);
  292. ENDPROCEDURE;
  293.  
  294. !
  295. !   Given a buffer name, return the buffer TYPE variable for that buffer.
  296. !
  297. PROCEDURE vi$find_buffer_by_name (bname_param)
  298.     LOCAL
  299.         cnt,
  300.         bname,
  301.         possible,
  302.         pbuf,
  303.         buf;
  304.  
  305.     bname := bname_param;
  306.     CHANGE_CASE (bname, UPPER);
  307.     buf := GET_INFO (BUFFERS, "FIRST");
  308.     cnt := 0;
  309.  
  310.     LOOP
  311.         EXITIF buf = 0;
  312.         possible := GET_INFO (buf, "NAME");
  313.         EXITIF bname = possible;
  314.         IF vi$leading_str (bname, possible) THEN
  315.             cnt := cnt + 1;
  316.             pbuf := buf;
  317.         ENDIF;
  318.         buf := GET_INFO (BUFFERS, "NEXT");
  319.     ENDLOOP;
  320.  
  321.     IF buf = 0 THEN
  322.         IF cnt = 1 THEN
  323.             buf := pbuf;
  324.         ENDIF;
  325.     ENDIF;
  326.  
  327.     RETURN (buf);
  328. ENDPROCEDURE;
  329.  
  330. !
  331. !   Effect a key mapping, and squirl away the original mapping so that
  332. !   it can be restore later.
  333. !
  334. PROCEDURE vi$map_keys (cmd, i)
  335.     LOCAL
  336.         comment_string,
  337.         separ,
  338.         pos,
  339.         buf,
  340.         map_type,
  341.         keyn,
  342.         key;
  343.  
  344.     map_type := vi$cmd_keys;
  345.     IF (vi$parse_next_ch (i, cmd, "!")) THEN
  346.         map_type := vi$edit_keys;
  347.     ENDIF;
  348.  
  349.     IF SUBSTR (cmd, i, 1) <> " " THEN
  350.         vi$show_maps;
  351.         RETURN(1);
  352.     ENDIF;
  353.  
  354.     vi$skip_white (cmd, i);
  355.  
  356.     IF (i > LENGTH (cmd)) THEN
  357.         vi$show_maps;
  358.         RETURN (1);
  359.     ENDIF;
  360.  
  361.     key := KEY_NAME (SUBSTR (cmd, i, 1));
  362.     i := i + 1;
  363.     comment_string := LOOKUP_KEY (key, COMMENT, map_type);
  364.  
  365.     vi$skip_white (cmd, i);
  366.  
  367.     key := INT (key);
  368.     IF (key < 32) THEN
  369.         key := ((INT(CTRL_B_KEY) - INT(CTRL_A_KEY)) *
  370.                                         (key - 1)) + INT(CTRL_A_KEY);
  371.     ENDIF;
  372.  
  373.     keyn := vi$key_map_name (key);
  374.  
  375.     IF (map_type = vi$edit_keys) AND (comment_string <> 0) AND
  376.             (comment_string <> "") AND (comment_string <> "active_macro") THEN
  377.         vi$info ("You can't redefine that key!");
  378.         RETURN (1);
  379.     ENDIF;
  380.  
  381.     vi$global_var := 0;
  382.     buf := 0;
  383.  
  384.     ! The callable TPU interface can create certain problems, as it
  385.     ! may cause the key definitions to hang around when the map
  386.     ! buffers have actually been deleted.  Mail can do this!  As a
  387.     ! result, the following code detects when the map buffer is
  388.     ! missing, and creates a new one.  The original meaning of
  389.     ! any key that is mapped in this way is necessarily lost.
  390.  
  391.     IF comment_string = "active_macro" THEN
  392.         EXECUTE (COMPILE ("vi$global_var := vi$$key_map_buf_" +
  393.                             keyn + map_type + ";"));
  394.         buf := vi$global_var;
  395.  
  396.         ! If buf is zero at this point, then the key map buffer
  397.         ! has been deleted.
  398.  
  399.     ELSE
  400.         EXECUTE (COMPILE (
  401.             "vi$global_var := vi$init_buffer ('vi$$key_map_" +
  402.                                                 keyn + map_type + "', '');"));
  403.  
  404.         IF (vi$global_var = 0) THEN
  405.             vi$info ("Can't create buffer for key map!");
  406.             RETURN;
  407.         ENDIF;
  408.  
  409.         EXECUTE (COMPILE ("vi$$key_map_buf_" +
  410.                                     keyn + map_type + " := vi$global_var;"));
  411.  
  412.         ! Pass the flag.
  413.  
  414.         buf := 1;
  415.     ENDIF;
  416.  
  417.     ! New key map, save old map into keymap buffer.
  418.  
  419.     IF (GET_INFO (buf, "TYPE") = INTEGER) THEN
  420.         buf := vi$global_var;
  421.         pos := MARK (NONE);
  422.         POSITION (buf);
  423.         SPLIT_LINE;
  424.         COPY_TEXT (comment_string);
  425.     ELSE
  426.  
  427.         ! Old map should be erased first.
  428.  
  429.         IF (GET_INFO (buf, "TYPE") = BUFFER) THEN
  430.             pos := MARK (NONE);
  431.             POSITION (BEGINNING_OF (buf));
  432.             LOOP
  433.                 EXITIF (CURRENT_LINE = "");
  434.                 ERASE_LINE;
  435.             ENDLOOP;
  436.         ELSE
  437.  
  438.             ! Key map buffer has been deleted, create a new one.
  439.  
  440.             EXECUTE (COMPILE (
  441.                 "vi$global_var := vi$init_buffer ('vi$$key_map_" +
  442.                                                 keyn + map_type + "', '');"));
  443.  
  444.             IF (vi$global_var = 0) THEN
  445.                 vi$info ("Can't create buffer for key map!");
  446.                 RETURN;
  447.             ENDIF;
  448.  
  449.             EXECUTE (COMPILE ("vi$$key_map_buf_" +
  450.                                     keyn + map_type + " := vi$global_var;"));
  451.             buf := vi$global_var;
  452.             pos := MARK (NONE);
  453.             POSITION (buf);
  454.             SPLIT_LINE;
  455.             COPY_TEXT ("vi$lost_definition");
  456.         ENDIF;
  457.     ENDIF;
  458.  
  459.     POSITION (BEGINNING_OF (buf));
  460.  
  461.     LOOP
  462.         EXITIF (i > LENGTH (cmd));
  463.         COPY_TEXT (STR (INT (KEY_NAME (SUBSTR (cmd, i, 1)))));
  464.         SPLIT_LINE;
  465.         i := i + 1;
  466.     ENDLOOP;
  467.  
  468.     POSITION (BEGINNING_OF (buf));
  469.     POSITION (pos);
  470.  
  471.     vi$info_success_off;
  472.  
  473.     IF (map_type = vi$edit_keys) THEN
  474.         EXECUTE (COMPILE
  475.             ("DEFINE_KEY ('vi$insert_macro_keys (vi$$key_map_buf_" + keyn +
  476.             map_type + ")', KEY_NAME(" + STR(key) + "), 'active_macro', vi$edit_keys);"));
  477.     ELSE
  478.         EXECUTE (COMPILE ("DEFINE_KEY ('vi$do_macro (vi$$key_map_buf_" + keyn +
  479.             map_type + ", 1)', KEY_NAME(" + STR(key) +
  480.             "), 'active_macro', vi$cmd_keys);"));
  481.     ENDIF;
  482.  
  483.     vi$info_success_on;
  484.     RETURN (0);
  485. ENDPROCEDURE;
  486.  
  487. !
  488. !   Unmap a key mapping and restore the original if one existed.
  489. !
  490. PROCEDURE vi$unmap_keys (cmd, i)
  491.     LOCAL
  492.         comment_string,
  493.         separ,
  494.         pos,
  495.         buf,
  496.         map_type,
  497.         keyn,
  498.         key;
  499.  
  500.     map_type := vi$cmd_keys;
  501.     IF (SUBSTR (cmd, i, 1) = "!") THEN
  502.         map_type := vi$edit_keys;
  503.         i := i + 1;
  504.     ELSE
  505.         IF SUBSTR (cmd, i, 1) <> " " THEN
  506.             vi$info ("Bad command!");
  507.             RETURN;
  508.         ENDIF;
  509.     ENDIF;
  510.  
  511.     vi$skip_white (cmd, i);
  512.  
  513.     key := KEY_NAME (SUBSTR (cmd, i ,1));
  514.  
  515.     comment_string := LOOKUP_KEY (key, COMMENT, map_type);
  516.  
  517.     IF comment_string <> "active_macro" THEN
  518.         vi$info ("Key not currently mapped!");
  519.         RETURN;
  520.     ENDIF;
  521.  
  522.     key := INT (key);
  523.     IF (key < 32) THEN
  524.         key := ((INT(CTRL_B_KEY) - INT(CTRL_A_KEY)) *
  525.                                         (key - 1)) + INT(CTRL_A_KEY);
  526.     ENDIF;
  527.  
  528.     keyn := vi$key_map_name (key);
  529.  
  530.     vi$global_var := 0;
  531.     EXECUTE (COMPILE ("vi$global_var := vi$$key_map_buf_" +
  532.                                                     keyn + map_type + ";"));
  533.     buf := vi$global_var;
  534.  
  535.     pos := MARK (NONE);
  536.     POSITION (END_OF (buf));
  537.     MOVE_VERTICAL (-1);
  538.  
  539.     vi$info_success_off;
  540.     EXECUTE (COMPILE ("DEFINE_KEY ('"+CURRENT_LINE +
  541.         "', "+STR(key)+", '"+CURRENT_LINE+"', '" + map_type + "')"));
  542.     vi$info_success_on;
  543.  
  544.     POSITION (pos);
  545.     DELETE (buf);
  546.  
  547.     vi$info ("Key now unmapped!");
  548. ENDPROCEDURE;
  549.  
  550. !
  551. !
  552. !
  553. PROCEDURE vi$lost_definition
  554.     vi$info ("Key definition lost!");
  555. ENDPROCEDURE;
  556.  
  557. !
  558. !   Show current keyboard mappings.
  559. !
  560. PROCEDURE vi$show_maps
  561.     LOCAL
  562.         com,
  563.         key_type,
  564.         keyn,
  565.         key,
  566.         bpos,
  567.         npos,
  568.         pos,
  569.         buf;
  570.  
  571.     pos := MARK (NONE);
  572.     buf := choice_buffer;
  573.  
  574.     POSITION (buf);
  575.     ERASE (buf);
  576.  
  577.     key_type := vi$cmd_keys;
  578.     COPY_TEXT ("COMMAND KEY MAPS:");
  579.     SPLIT_LINE;
  580.     LOOP
  581.         keyn := GET_INFO (DEFINED_KEY, "first", key_type);
  582.         LOOP
  583.             EXITIF (keyn = 0);
  584.             com := LOOKUP_KEY (keyn, COMMENT, key_type);
  585.  
  586.             IF (com = "active_macro") THEN
  587.                 key := vi$key_map_name (keyn);
  588.                 vi$global_var := 0;
  589.                 EXECUTE (COMPILE ("vi$global_var:=vi$$key_map_buf_"+
  590.                                                             key+key_type));
  591.                 IF (vi$global_var <> 0) AND
  592.                         (GET_INFO (vi$global_var, "TYPE") = BUFFER) THEN
  593.                     key := vi$ascii_name (keyn);
  594.                     COPY_TEXT (" "+key+SUBSTR ("   ", 1, 4-LENGTH(key))+'"');
  595.                     npos := MARK (NONE);
  596.                     POSITION (BEGINNING_OF (vi$global_var));
  597.                     LOOP
  598.                         keyn := CURRENT_LINE;
  599.                         EXITIF (LENGTH (keyn) < 8);
  600.                         bpos := MARK (NONE);
  601.                         POSITION (npos);
  602.                         COPY_TEXT (vi$ascii_name (INT(keyn)));
  603.                         POSITION (bpos);
  604.                         MOVE_VERTICAL (1);
  605.                     ENDLOOP;
  606.                     POSITION (npos);
  607.                     COPY_TEXT ('"');
  608.                     SPLIT_LINE;
  609.                 ENDIF;
  610.             ENDIF;
  611.             keyn := GET_INFO (DEFINED_KEY, "next", key_type);
  612.         ENDLOOP;
  613.         EXITIF (key_type = vi$edit_keys);
  614.         key_type := vi$edit_keys;
  615.         SPLIT_LINE;
  616.         COPY_TEXT ("EDITING KEY MAPS:");
  617.         SPLIT_LINE;
  618.     ENDLOOP;
  619.  
  620.     APPEND_LINE;
  621.     POSITION (BEGINNING_OF (buf));
  622.     POSITION (pos);
  623.     vi$show_list (buf,
  624.         "                                 Current MAPPINGS" +
  625.         "                           ",
  626.         info_window);
  627.     RETURN (0);
  628.  
  629. ENDPROCEDURE;
  630.  
  631. !
  632. !   Generate a unique string based on a KEY_NAME value.
  633. !
  634. PROCEDURE vi$key_map_name (key)
  635.     LOCAL
  636.         k;
  637.  
  638.     k := key;
  639.     IF (GET_INFO (key, "TYPE") = KEYWORD) THEN
  640.         k := INT (key);
  641.     ENDIF;
  642.     RETURN (SUBSTR(FAO("!XL", key),1,6));
  643. ENDPROCEDURE;
  644.  
  645. !
  646. !   Increment "i" until it is no longer indexing a blank or tab in "cmd".
  647. !
  648. PROCEDURE vi$skip_white (cmd, i)
  649.  
  650.     LOOP
  651.         EXITIF i > LENGTH (cmd);
  652.         EXITIF (INDEX (vi$_space_tab, SUBSTR(cmd, i, 1)) = 0);
  653.         i := i + 1;
  654.     ENDLOOP;
  655. ENDPROCEDURE;
  656.  
  657. !
  658. !   Given a string, extract a line specification that is either absolute,
  659. !   relative, or an RE pattern expression.
  660. !
  661. PROCEDURE vi$get_line_spec (idx, cmd)
  662.     LOCAL
  663.         ch,
  664.         sch,
  665.         num;
  666.  
  667.     num := 0;
  668.  
  669.     ch := SUBSTR (cmd, idx, 1);
  670.  
  671.     IF (ch = "/") OR (ch = "?") THEN
  672.         idx := idx + 1;
  673.         sch := ch;
  674.         num := "";
  675.         LOOP
  676.             EXITIF (vi$parse_next_ch (idx, cmd, sch));
  677.             EXITIF (LENGTH (cmd) < idx);
  678.             ch := SUBSTR (cmd, idx, 1);
  679.             IF (ch = "\") THEN
  680.                 num := num + SUBSTR (cmd, idx, 2);
  681.                 idx := idx + 1;
  682.             ELSE
  683.                 num := num + ch;
  684.             ENDIF;
  685.             idx := idx + 1;
  686.         ENDLOOP;
  687.  
  688.         IF (LENGTH (cmd) < idx - 1) THEN
  689.             vi$info ("Oops, improper expression!");
  690.             RETURN (-1);
  691.         ENDIF;
  692.  
  693.         ch := SUBSTR (cmd, idx, 1);
  694.  
  695.         IF sch = "?" THEN
  696.             SET (REVERSE, CURRENT_BUFFER);
  697.         ELSE
  698.             SET (FORWARD, CURRENT_BUFFER);
  699.         ENDIF;
  700.  
  701.         num := vi$find_str (num, 0, 0);
  702.  
  703.         IF (num <> 0) THEN
  704.             num := BEGINNING_OF (num);
  705.             POSITION (num);
  706.             num := vi$cur_line_no;
  707.         ELSE
  708.             RETURN (-1);
  709.         ENDIF;
  710.     ELSE
  711.         IF (ch = "'") THEN
  712.             ch := SUBSTR (cmd, idx+1, 1);
  713.             idx := idx + 2;
  714.             vi$global_var := 0;
  715.             EXECUTE (COMPILE ("vi$global_var:=vi$mark_"+ch));
  716.             IF (vi$global_var <> 0) THEN
  717.                 POSITION (vi$global_var);
  718.                 num := vi$cur_line_no;
  719.             ELSE
  720.                 RETURN (-1);
  721.             ENDIF;
  722.         ELSE
  723.             LOOP
  724.                 ch := SUBSTR (cmd, idx, 1);
  725.                 EXITIF (INDEX (vi$_numeric_chars, ch) = 0);
  726.                 IF (num < 0) THEN
  727.                     num := INT (ch);
  728.                 ELSE
  729.                     num := num * 10 + INT (ch);
  730.                 ENDIF;
  731.                 idx := idx + 1;
  732.             ENDLOOP;
  733.         ENDIF;
  734.     ENDIF;
  735.  
  736.     IF (ch = ".") THEN
  737.         num := vi$cur_line_no;
  738.         idx := idx + 1;
  739.         IF (vi$parse_next_ch (idx, cmd, "+")) THEN
  740.             num := num + vi$get_line_spec (idx, cmd);
  741.         ENDIF;
  742.     ELSE
  743.         IF (ch = "$") THEN
  744.             num := GET_INFO (CURRENT_BUFFER, "RECORD_COUNT");
  745.             idx := idx + 1;
  746.         ELSE
  747.             IF (ch = "+") THEN
  748.                 num := num + vi$get_line_spec (idx, cmd);
  749.             ENDIF;
  750.         ENDIF;
  751.     ENDIF;
  752.  
  753.     RETURN (num);
  754. ENDPROCEDURE;
  755.  
  756. !
  757. !   If the character at location "idx" in "cmd" is "try", then increment
  758. !   "idx" and return TRUE, otherwise return FALSE.
  759. !
  760. PROCEDURE vi$parse_next_ch (idx, cmd, try)
  761.     IF (SUBSTR (cmd, idx, 1) = try) THEN
  762.         idx := idx + 1;
  763.         RETURN (1);
  764.     ENDIF;
  765.  
  766.     RETURN (0);
  767. ENDPROCEDURE;
  768.  
  769. !
  770. !   A function to get the string, in "cmd", that is spanned by the characters
  771. !   in "mask".  "idx" is incremented to point past this string, and the string
  772. !   is returned as the function value.
  773. !
  774. PROCEDURE vi$get_cmd_token (mask, cmd, idx)
  775.     LOCAL
  776.         token,
  777.         ch;
  778.  
  779.     token := "";
  780.  
  781.     vi$skip_white (cmd, idx);
  782.  
  783.     LOOP
  784.         EXITIF (idx > LENGTH (cmd));
  785.         ch := SUBSTR (cmd, idx, 1);
  786.         EXITIF (INDEX (mask, ch) = 0);
  787.         token := token + ch;
  788.         idx := idx + 1;
  789.     ENDLOOP;
  790.  
  791.     RETURN (token);
  792. ENDPROCEDURE;
  793.  
  794. !
  795. !   A function to see if the string "token" is a lead substring of "cmd".
  796. !
  797. PROCEDURE vi$leading_str (token, cmd)
  798.     RETURN ((token <> "") AND (INDEX (cmd, token) = 1));
  799. ENDPROCEDURE;
  800.  
  801. !
  802. !   A routine that looks for the first occurance of a character in
  803. !   "seps", in "cmd", and then changes "idx" to reflect that locatation.
  804. !   "separ" will contain the character in "seps" that was actually found.
  805. !
  806. PROCEDURE vi$skip_separ (cmd, idx, seps, separ)
  807.     LOCAL
  808.         nch,
  809.         retstr;
  810.  
  811.     retstr := "";
  812.     separ := "";
  813.     vi$skip_white (cmd, idx);
  814.  
  815.     LOOP
  816.         EXITIF (idx > LENGTH (cmd));
  817.         nch := SUBSTR (cmd, idx, 1);
  818.         idx := idx + 1;
  819.         IF (INDEX (seps, nch) <> 0) OR (nch = " ") OR (nch = ASCII (9)) THEN
  820.             separ := nch;
  821.             RETURN (retstr);
  822.         ENDIF;
  823.         retstr := retstr + nch;
  824.     ENDLOOP;
  825.     RETURN (retstr);
  826. ENDPROCEDURE;
  827.  
  828. !
  829. !   A procedure that returns the characters occuring at index, "idx", and
  830. !   after in the string "cmd".
  831. !
  832. PROCEDURE vi$rest_of_line (cmd, idx)
  833.     RETURN (SUBSTR (cmd, idx, LENGTH (cmd)-idx + 1));
  834. ENDPROCEDURE;
  835.  
  836. !
  837. !  SET (INFORMATIONAL/SUCCESS) short procedures.
  838. !
  839. PROCEDURE vi$info_success_off vi$info_off; vi$success_off; ENDPROCEDURE;
  840. PROCEDURE vi$info_success_on vi$info_on; vi$success_on; ENDPROCEDURE;
  841. PROCEDURE vi$success_off SET (SUCCESS, OFF); ENDPROCEDURE;
  842. PROCEDURE vi$success_on SET (SUCCESS, ON); ENDPROCEDURE;
  843. PROCEDURE vi$info_off SET (INFORMATIONAL, OFF); ENDPROCEDURE;
  844. PROCEDURE vi$info_on SET (INFORMATIONAL, ON); ENDPROCEDURE;
  845.  
  846. !
  847. !   Called from vi$do_global to perform a substitution during a global command.
  848. !
  849. PROCEDURE vi$global_subs (cmd, nsubs)
  850.  
  851.     LOCAL
  852.         idx,
  853.         result_text,
  854.         replace_text,
  855.         hrange,
  856.         ch,
  857.         pos,
  858.         spos,
  859.         epos,
  860.         lpos,
  861.         source,
  862.         scount,
  863.         dest,
  864.         query,
  865.         doglobal,
  866.         replace,
  867.         separ;
  868.  
  869.     idx := 1;
  870.  
  871.     separ := vi$next_char (cmd, idx);
  872.  
  873.     source := "";
  874.     dest   := "";
  875.     doglobal := 0;
  876.     query  := 0;
  877.  
  878.     LOOP
  879.         IF (idx > LENGTH (cmd)) THEN
  880.             vi$info ("Insufficent arguments!");
  881.             RETURN (0);
  882.         ENDIF;
  883.  
  884.         ch := SUBSTR (cmd, idx, 1);
  885.         EXITIF ch = separ;
  886.         source := source + ch;
  887.         idx := idx + 1;
  888.     ENDLOOP;
  889.  
  890.     idx := idx + 1;
  891.     LOOP
  892.         EXITIF idx > LENGTH (cmd);
  893.         ch := SUBSTR (cmd, idx, 1);
  894.         EXITIF ch = separ;
  895.         dest := dest + ch;
  896.         idx := idx + 1;
  897.     ENDLOOP;
  898.  
  899.     idx := idx + 1;
  900.     LOOP
  901.         EXITIF idx > LENGTH (cmd);
  902.         ch := SUBSTR (cmd, idx, 1);
  903.         IF (ch = "q") or (ch = "c") THEN
  904.             query := 1;
  905.         ELSE
  906.             IF ch = "g" THEN
  907.                 doglobal := 1;
  908.             ELSE
  909.                 vi$info ("Unrecognized command qualifier '"+ch+"'");
  910.                 RETURN (0);
  911.             ENDIF;
  912.         ENDIF;
  913.         idx := idx + 1;
  914.     ENDLOOP;
  915.  
  916.     vi$replace_source := source;
  917.     vi$replace_dest := dest;
  918.  
  919.     lpos := vi$perform_subs (source, dest, vi$cur_line_no,
  920.                                                 scount, doglobal, query);
  921.     nsubs := nsubs + scount;
  922.  
  923.     RETURN (lpos);
  924. ENDPROCEDURE;
  925. !
  926. !   Called from vi$do_command to parse the rest of the command line,
  927. !   this procedure then envokes lower level routines to perform the work
  928. !   of a substitution command.
  929. !
  930. PROCEDURE vi$do_substitute (start_line, end_line, whole_range, idx, cmd)
  931.  
  932.     LOCAL
  933.         result_text,
  934.         replace_text,
  935.         hrange,
  936.         ch,
  937.         pos,
  938.         spos,
  939.         epos,
  940.         lpos,
  941.         source,
  942.         scount,
  943.         dest,
  944.         query,
  945.         doglobal,
  946.         replace,
  947.         separ;
  948.  
  949.     pos := MARK (NONE);
  950.     POSITION (END_OF (whole_range));
  951.     epos := MARK (NONE);
  952.     POSITION (pos);
  953.  
  954.     separ := vi$next_char (cmd, idx);
  955.     vi$replace_separ := separ;
  956.  
  957.     source := "";
  958.     dest   := "";
  959.     doglobal := 0;
  960.     query  := 0;
  961.  
  962.     LOOP
  963.         IF (idx > LENGTH (cmd)) THEN
  964.             vi$info ("Insufficent arguments!");
  965.             RETURN (1);
  966.         ENDIF;
  967.  
  968.         ch := SUBSTR (cmd, idx, 1);
  969.         EXITIF ch = separ;
  970.         source := source + ch;
  971.         idx := idx + 1;
  972.     ENDLOOP;
  973.  
  974.     idx := idx + 1;
  975.     LOOP
  976.         EXITIF idx > LENGTH (cmd);
  977.         ch := SUBSTR (cmd, idx, 1);
  978.         EXITIF ch = separ;
  979.         dest := dest + ch;
  980.         idx := idx + 1;
  981.     ENDLOOP;
  982.  
  983.     idx := idx + 1;
  984.     LOOP
  985.         EXITIF idx > LENGTH (cmd);
  986.         ch := SUBSTR (cmd, idx, 1);
  987.         IF (ch = "q") OR (ch = "c") THEN
  988.             query := 1;
  989.         ELSE
  990.             IF ch = "g" THEN
  991.                 doglobal := 1;
  992.             ELSE
  993.                 vi$info ("Unrecognized command qualifier '"+ch+"'");
  994.                 RETURN (1);
  995.             ENDIF;
  996.         ENDIF;
  997.         idx := idx + 1;
  998.     ENDLOOP;
  999.  
  1000.     POSITION (pos);
  1001.     vi$save_for_undo (whole_range, VI$LINE_MODE, 1);
  1002.     vi$move_to_line (start_line);
  1003.  
  1004.     IF MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER) THEN
  1005.         MOVE_HORIZONTAL (-1);
  1006.         spos := MARK (NONE);
  1007.         MOVE_HORIZONTAL (1);
  1008.     ELSE
  1009.         spos := 0;
  1010.     ENDIF;
  1011.  
  1012.     vi$replace_source := source;
  1013.     vi$replace_dest := dest;
  1014.  
  1015.     scount := 0;
  1016.     lpos := vi$perform_subs (source, dest, end_line, scount, doglobal, query);
  1017.  
  1018.     IF (scount = 0) THEN
  1019.         vi$kill_undo;
  1020.         vi$undo_end := 0;
  1021.         POSITION (pos);
  1022.     ELSE
  1023.         vi$undo_end := epos;
  1024.         IF (spos = 0) THEN
  1025.             vi$undo_start := BEGINNING_OF (CURRENT_BUFFER);
  1026.         ELSE
  1027.             POSITION (spos);
  1028.             MOVE_HORIZONTAL (1);
  1029.             vi$undo_start := MARK (NONE);
  1030.         ENDIF;
  1031.         vi$pos_in_middle (lpos);
  1032.         vi$info (FAO ("!UL substitution!%S!", scount));
  1033.     ENDIF;
  1034.  
  1035.     RETURN (1);
  1036. ENDPROCEDURE;
  1037.  
  1038. !
  1039. !   Repeat the last substitute command that was issued at the ":" prompt.
  1040. !
  1041. !   The function mapped to '&'.
  1042. !
  1043. PROCEDURE vi$repeat_subs
  1044.     LOCAL
  1045.         scount,
  1046.         doglobal,
  1047.         query,
  1048.         lpos,
  1049.         spos,
  1050.         pos,
  1051.         epos,
  1052.         here;
  1053.  
  1054.     IF (vi$replace_separ = 0) THEN
  1055.         vi$info ("No previous substitution!");
  1056.         RETURN;
  1057.     ENDIF;
  1058.  
  1059.     doglobal := 0;
  1060.     query := 0;
  1061.     here := vi$cur_line_no;
  1062.     vi$save_for_undo (CURRENT_LINE, VI$LINE_MODE, 1);
  1063.  
  1064.     pos := MARK (NONE);
  1065.     POSITION (LINE_BEGIN);
  1066.  
  1067.     spos := vi$get_undo_start;
  1068.  
  1069.     POSITION (LINE_END);
  1070.     IF (LENGTH (CURRENT_LINE) > 0) THEN
  1071.         MOVE_HORIZONTAL (-1);
  1072.     ENDIF;
  1073.     epos := MARK (NONE);
  1074.     POSITION (pos);
  1075.  
  1076.     lpos := vi$perform_subs (vi$replace_source, vi$replace_dest,
  1077.                                                 here, scount, doglobal, query);
  1078.  
  1079.     IF (scount = 0) THEN
  1080.         vi$kill_undo;
  1081.         vi$undo_end := 0;
  1082.     ELSE
  1083.         vi$undo_end := epos;
  1084.         vi$undo_start := vi$set_undo_start (spos);
  1085.         POSITION (lpos);
  1086.     ENDIF;
  1087.  
  1088.     RETURN (lpos);
  1089. ENDPROCEDURE;
  1090.  
  1091. !
  1092. !   Perform a substitution from the current location to "end_line".
  1093. !   Use source as the search string, and dest as the substitution
  1094. !   spec.  "global" indicates whether or not all occurances on a line
  1095. !   are examined, and "query" indicates whether or not to prompt before
  1096. !   performing the substitution.  On return, "scount" will hold the
  1097. !   number of substitutions actually performed.
  1098. !
  1099. PROCEDURE vi$perform_subs (source, dest, end_line, scount, doglobal, query)
  1100.  
  1101.     LOCAL
  1102.         result_text,
  1103.         replace_text,
  1104.         answer,
  1105.         fcnt,
  1106.         lpos,
  1107.         hrange,
  1108.         replace,
  1109.         fpos,
  1110.         quit_now,
  1111.         cwin,
  1112.         pos;
  1113.  
  1114.     SET (FORWARD, CURRENT_BUFFER);
  1115.     scount := 0;
  1116.     fcnt := 0;
  1117.     quit_now := 0;
  1118.     pos := MARK (NONE);
  1119.  
  1120.     LOOP
  1121.         fpos := vi$find_str (source, 1, 1);
  1122.         EXITIF (fpos = 0);
  1123.         fcnt := fcnt + 1;
  1124.         POSITION (BEGINNING_OF (fpos));
  1125.  
  1126.         IF vi$cur_line_no > end_line THEN
  1127.             POSITION (pos);
  1128.             EXITIF (1);
  1129.         ENDIF;
  1130.         result_text := SUBSTR (fpos, 1, LENGTH (fpos));
  1131.         replace_text := vi$substitution (result_text, dest);
  1132.         POSITION (BEGINNING_OF (fpos));
  1133.  
  1134.         replace := 1;
  1135.         IF (query) THEN
  1136.             POSITION (BEGINNING_OF (fpos));
  1137.             hrange := CREATE_RANGE (BEGINNING_OF (fpos),
  1138.                                                     END_OF (fpos), REVERSE);
  1139.             cwin := GET_INFO (WINDOWS, "FIRST");
  1140.             LOOP
  1141.                 EXITIF (cwin = 0);
  1142.                 IF (GET_INFO (cwin, "VISIBLE")) THEN
  1143.                     UPDATE (cwin);
  1144.                 ENDIF;
  1145.                 cwin := GET_INFO (WINDOWS, "NEXT");
  1146.             ENDLOOP;
  1147.  
  1148.             answer := vi$read_line ("Replace y/n/a/q? ");
  1149.  
  1150.             CHANGE_CASE (answer, LOWER);
  1151.             IF (answer = "") OR (INDEX ("yes", answer) <> 1) THEN
  1152.                 replace := 0;
  1153.             ENDIF;
  1154.             IF (INDEX ("quit", answer) = 1) THEN
  1155.                 quit_now := 1;
  1156.             ENDIF;
  1157.             IF (INDEX ("all", answer) = 1) THEN
  1158.                 query := 0;
  1159.                 replace := 1;
  1160.             ENDIF;
  1161.         ENDIF;
  1162.  
  1163.         IF replace THEN
  1164.  
  1165. !           This is a hack necessary to fix TPU's pattern matching.
  1166. !           The length of the text matched by only "line_begin" and
  1167. !           "line_end" has length == 1 instead of 0 as one would expect.
  1168.  
  1169.             IF (source <> "^") AND (source <> "$") AND (source <> "") THEN
  1170.                 ERASE_CHARACTER (LENGTH (result_text));
  1171.             ENDIF;
  1172.             COPY_TEXT (replace_text);
  1173.             pos := MARK (NONE);
  1174.             scount := scount + 1;
  1175.         ELSE
  1176.             MOVE_HORIZONTAL (1);
  1177.         ENDIF;
  1178.  
  1179.         IF NOT doglobal THEN
  1180.             POSITION (LINE_BEGIN);
  1181.             EXITIF MARK (NONE) = END_OF (CURRENT_BUFFER);
  1182.             MOVE_VERTICAL (1);
  1183.         ENDIF;
  1184.         EXITIF quit_now;
  1185.     ENDLOOP;
  1186.  
  1187.     IF fcnt = 0 THEN
  1188.         vi$info ("string not found!");
  1189.     ENDIF;
  1190.  
  1191.     RETURN (pos);
  1192. ENDPROCEDURE;
  1193.  
  1194. !
  1195. !   Move horizontal, ignoring errors
  1196. !
  1197. PROCEDURE vi$move_horizontal (cnt)
  1198.     ON_ERROR
  1199.     ENDON_ERROR;
  1200.  
  1201.     MOVE_HORIZONTAL (cnt);
  1202. ENDPROCEDURE;
  1203.  
  1204. !
  1205. !   Move vertical, ignoring errors
  1206. !
  1207. PROCEDURE vi$move_vertical (cnt)
  1208.     ON_ERROR
  1209.     ENDON_ERROR;
  1210.  
  1211.     MOVE_VERTICAL (cnt);
  1212. ENDPROCEDURE;
  1213.  
  1214. !
  1215. !   Move to the indicated line number.
  1216. !
  1217. PROCEDURE vi$move_to_line (line_no)
  1218.     LOCAL
  1219.         pos;
  1220.  
  1221.     ON_ERROR
  1222.         POSITION (pos);
  1223.         RETURN (0);
  1224.     ENDON_ERROR;
  1225.  
  1226.     pos := MARK (NONE);
  1227.     POSITION (BEGINNING_OF (CURRENT_BUFFER));
  1228.     MOVE_VERTICAL (line_no - 1);
  1229.  
  1230.     RETURN (MARK (NONE));
  1231. ENDPROCEDURE;
  1232.  
  1233. !
  1234. !   Give a source string, and a "dest" substitution spec, perform the
  1235. !   RE style substitution, and return the resultant string.
  1236. !
  1237. PROCEDURE vi$substitution (source, dest)
  1238.  
  1239.     LOCAL
  1240.         cur_char,
  1241.         result,
  1242.         idx;
  1243.  
  1244.     idx := 0;
  1245.     result := "";
  1246.  
  1247.     LOOP
  1248.         EXITIF (idx > LENGTH(dest));
  1249.  
  1250.         cur_char := SUBSTR (dest, idx, 1);
  1251.         IF (cur_char = "&") THEN
  1252.             result := result + source;
  1253.             idx := idx + 1;
  1254.         ELSE
  1255.             IF (cur_char = '\') THEN
  1256.                 cur_char := SUBSTR(dest, idx+1, 1);
  1257.                 IF (INDEX ("123456789", cur_char) > 0) THEN
  1258.                     vi$global_var := 0;
  1259.                     IF INT(cur_char) > 1 THEN
  1260.                         EXECUTE (COMPILE ("vi$global_var := SUBSTR (p" +
  1261.                             cur_char +", LENGTH (o"+cur_char+")+1,512);"));
  1262.                     ELSE
  1263.                         EXECUTE (COMPILE ("vi$global_var := SUBSTR (p" +
  1264.                             cur_char +", LENGTH (o"+cur_char+"),512);"));
  1265.                     ENDIF;
  1266.                     result := result + vi$global_var;
  1267.                 ELSE
  1268.                     IF (cur_char = "&") THEN
  1269.                         result := result + cur_char;
  1270.                     ELSE
  1271.                         result := result + "\" + cur_char;
  1272.                     ENDIF;
  1273.                 ENDIF;
  1274.                 idx := idx + 2;
  1275.             ELSE
  1276.                 result := result + cur_char;
  1277.                 idx := idx + 1;
  1278.             ENDIF;
  1279.         ENDIF;
  1280.     ENDLOOP;
  1281.  
  1282.     RETURN (result);
  1283. ENDPROCEDURE;
  1284.  
  1285. !
  1286. !   Get the next character from a string at idx, and point past the character
  1287. !
  1288. PROCEDURE vi$next_char (cmd, idx)
  1289.  
  1290.     IF idx <= LENGTH (cmd) THEN
  1291.         idx := idx + 1;
  1292.         RETURN (SUBSTR (cmd, idx -1, 1));
  1293.     ENDIF;
  1294.  
  1295.     RETURN ("");
  1296. ENDPROCEDURE;
  1297.  
  1298. !
  1299. !  Process all set commands in the string cmd
  1300. !
  1301. PROCEDURE vi$set_commands (cmd, i)
  1302.     LOCAL
  1303.         err,
  1304.         separ,
  1305.         token_1;
  1306.  
  1307.     ON_ERROR
  1308.         RETURN;
  1309.     ENDON_ERROR;
  1310.  
  1311.     LOOP
  1312.         token_1 := vi$skip_separ (cmd, i, "= "+ASCII(9), separ);
  1313.         EDIT (token_1, COLLAPSE);
  1314.  
  1315.         EXITIF token_1 = "";
  1316.  
  1317.         err :=  vi$set_one (token_1, separ, cmd, i);
  1318.         EXITIF err;
  1319.     ENDLOOP;
  1320.     RETURN (err);
  1321. ENDPROCEDURE
  1322.  
  1323. !
  1324. !  Process a single set command and return success or failure.
  1325. !
  1326. PROCEDURE vi$set_one (token_1, separ, cmd, i)
  1327.  
  1328.     LOCAL
  1329.         val,
  1330.         errno,
  1331.         curwin,
  1332.         curbuf,
  1333.         buf,
  1334.         use_fortran,
  1335.         oldscrlen,
  1336.         npat,
  1337.         pstr,
  1338.         token_2;
  1339.  
  1340.     ON_ERROR
  1341.         errno := ERROR;
  1342.         vi$info ("ERROR at line: "+STR(ERROR_LINE)+", "+
  1343.                                 call_user(vi$cu_getmsg,STR(errno)));
  1344.         RETURN (1);
  1345.     ENDON_ERROR;
  1346.  
  1347.     token_2 := "";
  1348. a    IF (token_1 = "all") THEN
  1349.         vi$show_settings;
  1350.         RETURN (0);
  1351.     ENDIF;
  1352.  
  1353.     IF (token_1 = "tags") THEN
  1354.         vi$tag_files := vi$rest_of_line (cmd, i);
  1355.         i := LENGTH (cmd) + 1;
  1356.         RETURN (vi$load_tags);
  1357.     ENDIF;
  1358.  
  1359.     IF (token_1 = "notagcase") OR (token_1 = "notc") THEN
  1360.         vi$tag_case := NO_EXACT;
  1361.         RETURN (0);
  1362.     ENDIF;
  1363.  
  1364.     IF (token_1 = "tagcase") OR (token_1 = "tc") THEN
  1365.         vi$tag_case := EXACT;
  1366.         RETURN (0);
  1367.     ENDIF;
  1368.  
  1369.     IF (token_1 = "senddcl") THEN
  1370.         vi$send_dcl := 1;
  1371.         RETURN (0);
  1372.     ENDIF;
  1373.  
  1374.     IF (token_1 = "nosenddcl") THEN
  1375.         vi$send_dcl := 0;
  1376.         RETURN (0);
  1377.     ENDIF;
  1378.  
  1379.     IF (token_1 = "empty") THEN
  1380.         vi$delete_empty := 0;
  1381.         RETURN (0);
  1382.     ENDIF;
  1383.  
  1384.     IF (token_1 = "noempty") THEN
  1385.         vi$delete_empty := 1;
  1386.         RETURN (0);
  1387.     ENDIF;
  1388.  
  1389.     IF (token_1 = "files") OR (token_1 = "file") THEN
  1390.         val := vi$expand_file_list (vi$rest_of_line (cmd, i));
  1391.         vi$info (FAO ("!UL file!%S selected", val, 0));
  1392.         RETURN (2);
  1393.     ENDIF;
  1394.  
  1395.     IF (token_1 = "notabs") THEN
  1396.         vi$use_tabs := 0;
  1397.         RETURN (0);
  1398.     ENDIF;
  1399.  
  1400.     IF (token_1 = "tabs") THEN
  1401.         vi$use_tabs := 1;
  1402.         RETURN (0);
  1403.     ENDIF;
  1404.  
  1405.     IF (token_1 = "noreadonly") OR (token_1 = "noro") THEN
  1406.         SET (NO_WRITE, CURRENT_BUFFER, OFF);
  1407.         vi$setbufmode (CURRENT_BUFFER, 0);
  1408.         vi$status_lines (CURRENT_BUFFER);
  1409.         RETURN (0);
  1410.     ENDIF;
  1411.  
  1412.     IF (token_1 = "readonly") OR (token_1 = "ro") THEN
  1413.         vi$setbufmode (CURRENT_BUFFER, 1);
  1414.         vi$status_lines (CURRENT_BUFFER);
  1415.         RETURN (0);
  1416.     ENDIF;
  1417.  
  1418.     IF (token_1 = "write") OR (token_1 = "wr") THEN
  1419.         SET (NO_WRITE, CURRENT_BUFFER, OFF);
  1420.         vi$status_lines (CURRENT_BUFFER);
  1421.         RETURN (0);
  1422.     ENDIF;
  1423.  
  1424.     IF (token_1 = "nowrite") OR (token_1 = "nowr") THEN
  1425.         SET (NO_WRITE, CURRENT_BUFFER, ON);
  1426.         vi$status_lines (CURRENT_BUFFER);
  1427.         RETURN (0);
  1428.     ENDIF;
  1429.  
  1430.     IF (token_1 = "width") THEN
  1431.         token_2 := vi$skip_separ (cmd, i, "= "+ASCII(9), separ);
  1432.         val := INT (token_2);
  1433.         SET (WIDTH, CURRENT_WINDOW, val);
  1434.         vi$scr_width := val;
  1435.         RETURN (0);
  1436.     ENDIF;
  1437.  
  1438.     IF (token_1 = "window") THEN
  1439.         token_2 := vi$skip_separ (cmd, i, "= "+ASCII(9), separ);
  1440.         val := INT (token_2);
  1441.         RETURN (vi$do_set_window (val));
  1442.     ENDIF;
  1443.  
  1444.     IF (token_1 = "ts") OR (token_1 = "tabstops") THEN
  1445.         token_2 := vi$skip_separ (cmd, i, "=  "+ASCII(9), separ);
  1446.         val := INT (token_2);
  1447.         SET (TAB_STOPS, CURRENT_BUFFER, val);
  1448.         vi$tab_amount := val;
  1449.         RETURN (0);
  1450.     ENDIF;
  1451.  
  1452.     IF (token_1 = "sw") OR (token_1 = "shiftwidth") then
  1453.         token_2 := vi$skip_separ (cmd, i, "= "+ASCII(9), separ);
  1454.         vi$shift_width := INT (token_2);
  1455.         RETURN (0);
  1456.     ENDIF;
  1457.  
  1458.     IF (token_1 = "noautoindent") OR (token_1 = "noai") THEN
  1459.         vi$auto_indent := 0;
  1460.         RETURN (0);
  1461.     ENDIF;
  1462.  
  1463.     IF (token_1 = "autoindent") OR (token_1 = "ai") THEN
  1464.         vi$auto_indent := 1;
  1465.         RETURN (0);
  1466.     ENDIF;
  1467.  
  1468.     IF (token_1 = "noundomap") OR (token_1 = "noum") THEN
  1469.         vi$undo_map := 0;
  1470.         RETURN (0);
  1471.     ENDIF;
  1472.  
  1473.     IF (token_1 = "undomap") OR (token_1 = "um") THEN
  1474.         vi$undo_map := 1;
  1475.         RETURN (0);
  1476.     ENDIF;
  1477.  
  1478.     IF (token_1 = "scroll") THEN
  1479.         token_2 := vi$skip_separ (cmd, i, "= "+ASCII(9), separ);
  1480.         vi$how_much_scroll := INT (token_2);
  1481.         RETURN (0);
  1482.     ENDIF;
  1483.  
  1484.     IF (token_1 = "report") THEN
  1485.         token_2 := vi$skip_separ (cmd, i, "= "+ASCII(9), separ);
  1486.         vi$report := INT (token_2);
  1487.         RETURN (0);
  1488.     ENDIF;
  1489.  
  1490.     IF (token_1 = "aw") OR (token_1 = "autowrite") THEN
  1491.         vi$auto_write := 1;
  1492.         RETURN (0);
  1493.     ENDIF;
  1494.  
  1495.     IF (token_1 = "noaw") OR (token_1 = "noautowrite") THEN
  1496.         vi$auto_write := 0;
  1497.         RETURN (0);
  1498.     ENDIF;
  1499.  
  1500.     IF (token_1 = "noic") OR (token_1 = "noignorecase") THEN
  1501.         vi$ignore_case := EXACT;
  1502.         RETURN (0);
  1503.     ENDIF;
  1504.  
  1505.     IF (token_1 = "ic") OR (token_1 = "ignorecase") THEN
  1506.         vi$ignore_case := NO_EXACT;
  1507.         RETURN (0);
  1508.     ENDIF;
  1509.  
  1510.     IF (token_1 = "magic") THEN
  1511.         vi$magic := 1;
  1512.         RETURN (0);
  1513.     ENDIF;
  1514. $$EOD$$
  1515.