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

  1. Path: xanth!mcnc!gatech!cwjcc!hal!ncoast!allbery
  2. From: gregg@a.cs.okstate.edu (Gregg Wonderly)
  3. Newsgroups: comp.sources.misc
  4. Subject: v04i107: TPUVI for VMS part 16 of 17
  5. Message-ID: <8809211812.AA21980@uunet.UU.NET>
  6. Date: 27 Sep 88 22:20:10 GMT
  7. Sender: allbery@ncoast.UUCP
  8. Reply-To: gregg@a.cs.okstate.edu (Gregg Wonderly)
  9. Lines: 992
  10. Approved: allbery@ncoast.UUCP
  11.  
  12. Posting-number: Volume 4, Issue 107
  13. Submitted-by: "Gregg Wonderly" <gregg@a.cs.okstate.edu>
  14. Archive-name: vms-vi-2/Part16
  15.  
  16. $ WRITE SYS$OUTPUT "Creating ""VI.12"""
  17. $ CREATE VI.12
  18. $ DECK/DOLLARS=$$EOD$$
  19.     ENDIF;
  20.     bn := bn + btype;
  21.  
  22.     found_one := vi$choose_buffer (bn, how_many_buffers,
  23.                             possible_buffer, possible_buffer_name, loop_buffer);
  24.  
  25.     IF (found_one) THEN
  26.         POSITION (pos);
  27.         IF (CURRENT_BUFFER = loop_buffer) THEN
  28.             vi$info ("Already positioned in that buffer");
  29.         ELSE
  30.             UNMAP (win);
  31.             MAP (win, loop_buffer);
  32.             vi$set_status_line (CURRENT_WINDOW);
  33.             vi$what_line;
  34.         ENDIF;
  35.     ELSE
  36.         vi$info (FAO (
  37.             "No such buffer ""!AS"", buffer has been deleted!", bn));
  38.         POSITION (vi$file_names);
  39.         MOVE_VERTICAL (1);
  40.     ENDIF;
  41.  
  42.     POSITION (win);
  43.     vi$kill_undo;
  44.     vi$undo_end := 0;
  45.     RETURN (1);
  46. ENDPROCEDURE
  47.  
  48. !
  49. !   This procedure should be envoked after a wild card edit.  It will allow
  50. !   a list of files that have been created due to a wildcard filespec to be
  51. !   processed sequentially.
  52. !
  53. PROCEDURE vi$_previous_file (bang)
  54.     LOCAL
  55.         win,
  56.         fn,
  57.         pos,
  58.         found_one,
  59.         btype,
  60.         bn,
  61.         how_many_buffers,
  62.         possible_buffer,
  63.         possible_buffer_name,
  64.         loop_buffer,
  65.         line;
  66.  
  67.     ON_ERROR
  68.         ! Ignore errors
  69.     ENDON_ERROR;
  70.  
  71.     IF (NOT bang) AND (vi$check_auto_write) THEN
  72.         RETURN;
  73.     ENDIF;
  74.  
  75.     pos := MARK (NONE);
  76.     win := CURRENT_WINDOW;
  77.  
  78.     fn := GET_INFO (CURRENT_BUFFER, "OUTPUT_FILE");
  79.  
  80.     POSITION (vi$file_names);
  81.     IF (MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER)) THEN
  82.         IF (MARK (NONE) = END_OF (CURRENT_BUFFER)) THEN
  83.             MOVE_VERTICAL (-1);
  84.         ENDIF;
  85.         MOVE_VERTICAL (-1);
  86.     ELSE
  87.         vi$info ("No previous file!");
  88.         POSITION (pos);
  89.         RETURN (1);
  90.     ENDIF;
  91.  
  92.     fn := vi$current_line;
  93.  
  94.     bn := FILE_PARSE (fn, "", "", NAME);
  95.     btype := FILE_PARSE (fn, "", "", TYPE);
  96.  
  97.     IF btype = "" THEN
  98.         btype := ".";
  99.     ENDIF;
  100.     bn := bn + btype;
  101.  
  102.     found_one := vi$choose_buffer (bn, how_many_buffers,
  103.                             possible_buffer, possible_buffer_name, loop_buffer);
  104.  
  105.     IF (found_one) THEN
  106.         POSITION (pos);
  107.         IF (CURRENT_BUFFER = loop_buffer) THEN
  108.             vi$info ("Already positioned in that buffer");
  109.         ELSE
  110.             UNMAP (win);
  111.             MAP (win, loop_buffer);
  112.             vi$set_status_line (CURRENT_WINDOW);
  113.         ENDIF;
  114.     ELSE
  115.         vi$info ("No previous file!");
  116.     ENDIF;
  117.  
  118.     vi$kill_undo;
  119.     vi$undo_end := 0;
  120.     POSITION (win);
  121.     RETURN (1);
  122. ENDPROCEDURE
  123.  
  124. !
  125. !   Map first file in file list to the current window, providing it makes
  126. !   sense to do so (eg. no mapping should be done to the command window.
  127. !
  128. PROCEDURE vi$_first_file (bang)
  129.     LOCAL
  130.         win,
  131.         fn,
  132.         pos,
  133.         found_one,
  134.         btype,
  135.         bn,
  136.         how_many_buffers,
  137.         possible_buffer,
  138.         possible_buffer_name,
  139.         loop_buffer,
  140.         line;
  141.  
  142.     ON_ERROR
  143.         ! Ignore errors
  144.     ENDON_ERROR;
  145.  
  146.     IF (NOT bang) AND (vi$check_auto_write) THEN
  147.         RETURN;
  148.     ENDIF;
  149.  
  150.     pos := MARK (NONE);
  151.     win := CURRENT_WINDOW;
  152.  
  153.     POSITION (BEGINNING_OF (vi$file_names));
  154.     IF (MARK (NONE) = END_OF (vi$file_names)) THEN
  155.         vi$info ("No filename list!");
  156.         POSITION (pos);
  157.         RETURN (1);
  158.     ENDIF;
  159.  
  160.     fn := vi$current_line;
  161.  
  162.     bn := FILE_PARSE (fn, "", "", NAME);
  163.     btype := FILE_PARSE (fn, "", "", TYPE);
  164.  
  165.     IF btype = "" THEN
  166.         btype := ".";
  167.     ENDIF;
  168.  
  169.     bn := bn + btype;
  170.  
  171.     found_one := vi$choose_buffer (bn, how_many_buffers,
  172.                             possible_buffer, possible_buffer_name, loop_buffer);
  173.  
  174.     IF (found_one) THEN
  175.         POSITION (pos);
  176.         IF (CURRENT_BUFFER = loop_buffer) THEN
  177.             vi$info ("Already positioned in that buffer");
  178.         ELSE
  179.             UNMAP (win);
  180.             MAP (win, loop_buffer);
  181.             vi$set_status_line (CURRENT_WINDOW);
  182.         ENDIF;
  183.     ELSE
  184.         vi$info ("Buffer not found: " + bn + "!");
  185.     ENDIF;
  186.  
  187.     vi$kill_undo;
  188.     vi$undo_end := 0;
  189.     POSITION (win);
  190.     RETURN (1);
  191. ENDPROCEDURE;
  192.  
  193. !
  194. !   Show the contents of the tags buffer
  195. !
  196. PROCEDURE vi$_show_tags
  197.     vi$show_list (vi$tag_buf,
  198.         "Current tags from the files: "+vi$tag_files, info_window)
  199. ENDPROCEDURE;
  200.  
  201. !
  202. !   Show the list of filenames currently being used by the NEXT FILE, FIRST
  203. !   FILE, and PREVIOUS FILE commands.
  204. !
  205. PROCEDURE vi$_show_files
  206.     vi$show_list (vi$file_names,
  207. "  File names currently active for PREVIOUS, FIRST and NEXT line mode commands",
  208.         info_window)
  209.  
  210. ENDPROCEDURE;
  211.  
  212. !
  213. !   Show a buffer, dbuf, in a window, dwin, with the status line set to 'stat'.
  214. !   Allow scrolling around, but no editing.  <ENTER> gets you out.
  215. !
  216. PROCEDURE vi$show_list (dbuf, stat, dwin)
  217.  
  218.     LOCAL
  219.         this_key,
  220.         win,
  221.         pos;
  222.  
  223.     win := CURRENT_WINDOW;
  224.     pos := MARK (NONE);
  225.  
  226.     MAP (dwin, dbuf);
  227.     SET (STATUS_LINE, dwin, NONE, "");
  228.     SET (STATUS_LINE, dwin, REVERSE, stat);
  229.     POSITION (dwin);
  230.     SET (EOB_TEXT, dbuf,
  231. "[Press RETURN to continue editing]                        ");
  232.     UPDATE (dwin);
  233.  
  234.     LOOP
  235.         this_key := vi$read_a_key;
  236.         EXITIF (this_key = RET_KEY);
  237.  
  238.         IF (this_key = CTRL_D_KEY) OR
  239.            (this_key = CTRL_U_KEY) OR
  240.            (this_key = CTRL_F_KEY) OR
  241.            (this_key = CTRL_B_KEY) OR
  242.            (this_key = KEY_NAME ('h')) OR
  243.            (this_key = KEY_NAME ('j')) OR
  244.            (this_key = KEY_NAME ('k')) OR
  245.            (this_key = KEY_NAME ('l')) THEN
  246.  
  247.             EXECUTE (LOOKUP_KEY (this_key, PROGRAM, vi$cmd_keys));
  248.             UPDATE (CURRENT_WINDOW);
  249.         ENDIF;
  250.     ENDLOOP;
  251.  
  252.     UNMAP (dwin);
  253.     SET (STATUS_LINE, dwin, NONE, "");
  254.     SET (EOB_TEXT, dbuf, "");
  255.     POSITION (win);
  256.     POSITION (pos);
  257. ENDPROCEDURE;
  258.  
  259. !
  260. !   This procedure creates a new buffer with the named file in it.
  261. !   Checking is done to see if the input file exists, and CREATE was on
  262. !   the command line, etc...
  263. !
  264. PROCEDURE vi$_create_buffer (buffer_name, req_name, actual_file_name)
  265.  
  266.     LOCAL
  267.         info,
  268.         succ,
  269.         outf,
  270.         new_buffer;     ! Buffer created
  271.  
  272.     ON_ERROR
  273.         IF ERROR = TPU$_DUPBUFNAME THEN
  274.             vi$info (FAO ("Buffer !AS already exists", buffer_name));
  275.             RETURN (0);
  276.         ENDIF;
  277.     ENDON_ERROR;
  278.  
  279.     IF (actual_file_name = 0) OR (actual_file_name = "") THEN
  280.         new_buffer := CREATE_BUFFER (buffer_name);
  281.  
  282.         IF (req_name <> 0) THEN
  283.             outf := FILE_PARSE (req_name);
  284.             vi$info (FAO ("New file ""!AS""", outf));
  285.             SET (OUTPUT_FILE, new_buffer, outf);
  286.         ENDIF;
  287.     ELSE
  288.         vi$info ("Reading file """+actual_file_name+"""");
  289.         new_buffer := CREATE_BUFFER (buffer_name, actual_file_name);
  290.  
  291.         vi$info (FAO ("""!AS"", !UL lines", actual_file_name,
  292.             GET_INFO (new_buffer, "RECORD_COUNT")));
  293.  
  294.         IF (vi$starting_up) THEN
  295.             IF GET_INFO (COMMAND_LINE, "OUTPUT") THEN
  296.                 SET (OUTPUT_FILE, new_buffer,
  297.                     FILE_PARSE (GET_INFO (COMMAND_LINE, "OUTPUT_FILE"),
  298.                                                         actual_file_name));
  299.  
  300.                 !  Set the buffer to be modified so that the file will
  301.                 !  be written on exit.
  302.  
  303.                 SPLIT_LINE;
  304.                 APPEND_LINE;
  305.             ENDIF;
  306.         ELSE
  307.             SET (OUTPUT_FILE, new_buffer, actual_file_name);
  308.         ENDIF;
  309.     ENDIF;
  310.  
  311.     IF (vi$check_auto_write) THEN
  312.         RETURN;
  313.     ENDIF;
  314.  
  315.     vi$setbufmode (new_buffer, vi$readonly);
  316.  
  317.     MAP (CURRENT_WINDOW, new_buffer);
  318.     vi$status_lines (new_buffer);
  319.  
  320.     SET (TAB_STOPS, new_buffer, vi$tab_amount);
  321.  
  322.     RETURN (new_buffer);
  323. ENDPROCEDURE;
  324.  
  325. !
  326. !   Add a string to the end of the choice buffer
  327. !
  328. PROCEDURE vi$add_choice (choice_string)
  329.  
  330.     LOCAL
  331.         pos;        ! Current position in the buffer
  332.  
  333.     pos := MARK (NONE);
  334.     POSITION (END_OF (choice_buffer));
  335.     COPY_TEXT (choice_string);
  336.     POSITION (pos);
  337. ENDPROCEDURE;
  338.  
  339. !
  340. !   Put a message into the message window, and note that it is there.  The
  341. !   main command procedure will remove it later.
  342. !
  343. PROCEDURE vi$info (mess)
  344.     MESSAGE (mess);
  345.     vi$did_mess := 1;
  346. ENDPROCEDURE;
  347.  
  348. !
  349. !   Print the system error message corresponding to the error code passed.
  350. !
  351. PROCEDURE vi$system_message (errno)
  352.     vi$info (CALL_USER (vi$cu_getmsg, STR(errno)));
  353. ENDPROCEDURE;
  354.  
  355. !
  356. !  Below are the window manipulation routines.  They take care of
  357. !  spliting and deleting windows.  The vi$prev_win and vi$next_win are
  358. !  very VERY dependent on there not being any occusion of the windows
  359. !  that they consider.  If a window is occluded, the results are
  360. !  unpredictable.
  361. !
  362. !  Split the current window exactly where it is at
  363. !
  364. PROCEDURE vi$split_here
  365.  
  366.     LOCAL
  367.         curwin,
  368.         nextwin,
  369.         curtop,
  370.         curbuf,
  371.         len,
  372.         line,
  373.         row,
  374.         errno,
  375.         spos,
  376.         newwin,
  377.         newlen,
  378.         newtop,
  379.         top;
  380.  
  381.     ON_ERROR
  382.         errno := ERROR;
  383.         line := ERROR_LINE;
  384.         vi$info ("ERROR at line: "+ STR (line));
  385.         vi$system_message (errno);
  386.         RETURN(1);
  387.     ENDON_ERROR
  388.  
  389.     IF (vi$in_occlusion) THEN
  390.         vi$info ("Can't split while MAKE FULL SCREEN is active");
  391.         RETURN (1);
  392.     ENDIF;
  393.  
  394.     spos := MARK (NONE);
  395.     curwin  :=  CURRENT_WINDOW;
  396.     row     :=  GET_INFO (curwin, "CURRENT_ROW");
  397.     top     :=  GET_INFO (curwin, "VISIBLE_TOP");
  398.     len     :=  GET_INFO (curwin, "VISIBLE_LENGTH");
  399.  
  400.     IF (row - top < 1) OR (top + len - row < 3) THEN
  401.  
  402.         IF (len < 3) THEN
  403.             vi$info ("Can't split window");
  404.             RETURN(1);
  405.         ENDIF;
  406.         row := top + (len/2) - 1;
  407.     ENDIF;
  408.  
  409.     curbuf := GET_INFO (curwin, "BUFFER");
  410.     UNMAP (curwin);
  411.     DELETE (curwin);
  412.  
  413.     ! Create the upper window.
  414.  
  415.     newlen := row - top + 1;
  416.     newwin := CREATE_WINDOW (top, newlen, ON);
  417.  
  418.     MAP (newwin, curbuf);
  419.     vi$set_status_line (newwin);
  420.  
  421.     ! Create the lower window.
  422.  
  423.     newtop := row + 1;
  424.     newwin := CREATE_WINDOW (newtop, len - (newtop - top), ON);
  425.  
  426.     MAP (newwin, curbuf);
  427.     vi$set_status_line (newwin);
  428.  
  429.     POSITION (newwin);
  430.     vi$pos_in_middle (MARK (NONE));
  431.     vi$previous_window;
  432.     vi$pos_in_middle (MARK (NONE));
  433.  
  434.     vi$this_window := CURRENT_WINDOW;
  435.  
  436.     RETURN (0);
  437. ENDPROCEDURE;
  438.  
  439. !
  440. !   This procedure is used to initialize some things that are necessarily
  441. !   changed when the editing environment changes because of window or other
  442. !   operations.
  443. !
  444. PROCEDURE vi$new_env
  445.     vi$how_much_scroll := GET_INFO (CURRENT_WINDOW, "VISIBLE_LENGTH") / 2;
  446.     vi$new_offset := 1;
  447. ENDPROCEDURE;
  448.  
  449. !
  450. !  Delete the current window
  451. !
  452. PROCEDURE vi$delete_window
  453.     LOCAL
  454.         curwin;
  455.  
  456.     IF (vi$in_occlusion) THEN
  457.         IF (CURRENT_WINDOW <> vi$occluding_win) THEN
  458.             vi$info ("Can't delete this window.");
  459.             RETURN;
  460.         ENDIF;
  461.  
  462.         UNMAP (vi$old_occ_win);
  463.         MAP (vi$old_occ_win, CURRENT_BUFFER);
  464.         DELETE (vi$occluding_win);
  465.         vi$in_occlusion := 0;
  466.         vi$set_status_line (CURRENT_WINDOW);
  467.         vi$new_env;
  468.     ELSE
  469.         curwin  := GET_INFO (WINDOWS, "CURRENT");
  470.         vi$del_win (curwin);
  471.     ENDIF;
  472. ENDPROCEDURE;
  473.  
  474. !
  475. !   Do the actual work of deleting a window
  476. !
  477. PROCEDURE vi$del_win (curwin)
  478.  
  479.     LOCAL
  480.         max_len,        ! Maximum length of screen minus the
  481.                         ! command window and message window
  482.         prevwin,        ! Window before the current
  483.         nextwin,        ! Window below the current
  484.         prevtop,        ! Top line of previous window
  485.         nexttop,        ! Top line of next window
  486.         curtop,         ! Top line of current window
  487.         prevbuf,        ! Buffer mapped to previous window
  488.         prevlen,        ! Length of previous window
  489.         curlen,         ! Length of current window
  490.         nextbuf,        ! Buffer mapped to next window
  491.         nextend,        ! Last line of next window
  492.         newwin,
  493.         nextlen;        ! Length of next window
  494.  
  495.     max_len := vi$scr_length - 2;
  496.     prevwin := vi$prev_win (curwin);
  497.     nextwin := vi$next_win (curwin);
  498.     curlen  := GET_INFO (curwin, "VISIBLE_LENGTH");
  499.     curtop  := GET_INFO (curwin, "VISIBLE_TOP");
  500.  
  501.     IF (nextwin <> 0) THEN
  502.         nextend := GET_INFO (nextwin, "VISIBLE_BOTTOM");
  503.     ELSE
  504.         nextend := max_len+1;  ! Something greater than the max_len used below
  505.     ENDIF;
  506.  
  507.     IF (nextwin <> 0) AND (nextend <= max_len) THEN
  508.         nextlen := GET_INFO (nextwin, "VISIBLE_LENGTH");
  509.         nextbuf := GET_INFO (nextwin, "BUFFER");
  510.         newwin := CREATE_WINDOW (curtop, curlen+nextlen, ON);
  511.         UNMAP (curwin);
  512.         UNMAP (nextwin);
  513.         MAP (newwin, nextbuf);
  514.         vi$set_status_line (newwin);
  515.         DELETE (curwin);
  516.         DELETE (nextwin);
  517.     ELSE
  518.         IF (prevwin <> 0) THEN
  519.             prevlen := GET_INFO (prevwin, "VISIBLE_LENGTH");
  520.             prevbuf := GET_INFO (prevwin, "BUFFER");
  521.             prevtop := GET_INFO (prevwin, "VISIBLE_TOP");
  522.             newwin := CREATE_WINDOW (prevtop, curlen+prevlen, ON);
  523.             UNMAP (curwin);
  524.             UNMAP (prevwin);
  525.             MAP (newwin, prevbuf);
  526.             vi$set_status_line (newwin);
  527.             DELETE (curwin);
  528.             DELETE (prevwin);
  529.         ELSE
  530.             vi$info ("Can't delete this window");
  531.             RETURN;
  532.         ENDIF;
  533.     ENDIF;
  534.  
  535.     IF (vi$prev_win (CURRENT_WINDOW) = 0) THEN
  536.         IF (vi$next_win (CURRENT_WINDOW) = 0) THEN
  537.             SET (STATUS_LINE, CURRENT_WINDOW, NONE, "");
  538.             REFRESH;
  539.         ENDIF;
  540.     ENDIF;
  541.     vi$this_window := CURRENT_WINDOW;
  542.     vi$pos_in_middle (MARK (NONE));
  543.     vi$new_env;
  544. ENDPROCEDURE;
  545.  
  546. !
  547. !   Take the current buffer (if there is more than one window displayed on the
  548. !   screen), and remap it to a new window that occludes all others and is
  549. !   the size of the screen.
  550. !
  551. PROCEDURE vi$make_full_screen
  552.  
  553.     LOCAL
  554.         win,
  555.         buf;
  556.  
  557.     IF (vi$in_occlusion) THEN
  558.         vi$info ("Already in full screen");
  559.         RETURN;
  560.     ENDIF;
  561.  
  562.     IF (vi$next_win (CURRENT_WINDOW) = 0) THEN
  563.         IF (vi$prev_win (CURRENT_WINDOW) = 0) THEN
  564.             vi$info ("Current window is only window");
  565.             RETURN;
  566.         ENDIF;
  567.     ENDIF;
  568.  
  569.     vi$old_occ_win := CURRENT_WINDOW;
  570.  
  571.     buf := CURRENT_BUFFER;
  572.     win := CREATE_WINDOW (1, vi$scr_length - 1, ON);
  573.     vi$occluding_win := win;
  574.  
  575.     IF (win <> 0) THEN
  576.         vi$in_occlusion := 1;
  577.         SET (STATUS_LINE, win, NONE, "");
  578.         MAP (win, buf);
  579.         vi$pos_in_middle (MARK (NONE));
  580.         vi$new_env;
  581.     ELSE
  582.         vi$info ("Error creating window, command aborted!");
  583.     ENDIF;
  584. ENDPROCEDURE;
  585.  
  586. !
  587. !  Move to next window going down the screen
  588. !
  589. PROCEDURE vi$next_window
  590.  
  591.     LOCAL
  592.         nextwin,
  593.         curwin;
  594.  
  595.     IF (vi$in_occlusion) THEN
  596.         RETURN;
  597.     ENDIF;
  598.  
  599.     curwin := CURRENT_WINDOW;
  600.     nextwin := vi$next_win (curwin);
  601.  
  602.     IF (nextwin <> 0) THEN
  603.         POSITION (nextwin);
  604.         vi$set_status_line (nextwin);
  605.         vi$new_env;
  606.     ENDIF;
  607. ENDPROCEDURE;
  608.  
  609. !
  610. !  Move to previous window going up the screen
  611. !
  612. PROCEDURE vi$previous_window
  613.  
  614.     LOCAL
  615.         prevwin,
  616.         curwin;
  617.  
  618.     IF (vi$in_occlusion) THEN
  619.         RETURN;
  620.     ENDIF;
  621.  
  622.     curwin := CURRENT_WINDOW;
  623.     prevwin := vi$prev_win (curwin);
  624.  
  625.     IF (prevwin <> 0) THEN
  626.         POSITION (prevwin);
  627.         vi$set_status_line (prevwin);
  628.         vi$new_env;
  629.     ENDIF;
  630. ENDPROCEDURE;
  631.  
  632. !
  633. !   Return the window that is below the current one, or ZERO if there is
  634. !   none.  Note the special case that occurs while MAKE_FULL_SCREEN is active.
  635. !
  636. PROCEDURE vi$next_win (win)
  637.  
  638.     LOCAL
  639.         winbot,
  640.         nexttop,
  641.         nextwin;
  642.  
  643.     IF (vi$in_occlusion) THEN
  644.         RETURN (0);
  645.     ENDIF;
  646.  
  647.     nextwin := GET_INFO (WINDOWS, "FIRST");
  648.     winbot := GET_INFO (win, "VISIBLE_BOTTOM");
  649.  
  650.     IF (winbot >= (vi$scr_length - 3)) THEN
  651.         RETURN (0);
  652.     ENDIF;
  653.  
  654.     LOOP
  655.         EXITIF nextwin = 0;
  656.  
  657.         IF (GET_INFO (nextwin, "BUFFER") <> 0) THEN
  658.             nexttop := GET_INFO (nextwin, "VISIBLE_TOP");
  659.  
  660.             IF (winbot + 2 = nexttop) THEN
  661.                 RETURN (nextwin);
  662.             ENDIF;
  663.         ENDIF;
  664.  
  665.         nextwin := GET_INFO (nextwin, "NEXT");
  666.     ENDLOOP;
  667.  
  668.     RETURN (0);
  669. ENDPROCEDURE;
  670.  
  671. !
  672. !   Return the window that is above the current one, or ZERO if there is
  673. !   none.  Note the special case that occurs while MAKE_FULL_SCREEN is active.
  674. !
  675. PROCEDURE vi$prev_win (win)
  676.  
  677.     LOCAL
  678.         max_len,    ! Maximum length of screen minus the
  679.                     ! command window, and message window.
  680.         wintop,
  681.         prevbot,
  682.         prevwin;
  683.  
  684.     IF (vi$in_occlusion) THEN
  685.         RETURN(0);
  686.     ENDIF;
  687.  
  688.     max_len := vi$scr_length - 1;
  689.     prevwin := GET_INFO (WINDOWS, "FIRST");
  690.     wintop := GET_INFO (win, "VISIBLE_TOP");
  691.  
  692.     IF (max_len <= wintop) THEN
  693.         RETURN (0);
  694.     ENDIF;
  695.  
  696.     IF (max_len - 1 = GET_INFO (win, "VISIBLE_BOTTOM")) AND (wintop = 1) THEN
  697.         RETURN (0);
  698.     ENDIF;
  699.  
  700.     LOOP
  701.         EXITIF prevwin = 0;
  702.  
  703.         IF (GET_INFO (prevwin, "BUFFER") <> 0) THEN
  704.             prevbot := GET_INFO (prevwin, "VISIBLE_BOTTOM");
  705.  
  706.             IF (prevbot + 2 = wintop) THEN
  707.                 RETURN (prevwin);
  708.             ENDIF;
  709.         ENDIF;
  710.  
  711.         prevwin := GET_INFO (prevwin, "NEXT");
  712.     ENDLOOP;
  713.  
  714.     RETURN (0);
  715. ENDPROCEDURE;
  716.  
  717. !
  718. !   Shrink the current window, lengthing the lower window if possible first.
  719. !   If there is no window below, then try above.  If can't do that either,
  720. !   then give up with a message
  721. !
  722. PROCEDURE vi$shrink_window (shrinkparm)
  723.  
  724.     LOCAL
  725.         curwin,
  726.         currow,
  727.         prevwin,
  728.         nextwin,
  729.         newshrink;
  730.  
  731.     IF (vi$in_occlusion) THEN
  732.         RETURN;
  733.     ENDIF;
  734.  
  735.     newshrink := shrinkparm;
  736.  
  737.     curwin := GET_INFO (WINDOWS, "CURRENT");
  738.     currow := GET_INFO (curwin, "VISIBLE_LENGTH");
  739.  
  740.     IF (currow < 3) THEN
  741.         vi$info ("Can't shrink this window");
  742.         RETURN;
  743.     ENDIF;
  744.  
  745.     IF newshrink > currow - 2 THEN
  746.         newshrink := currow - 2;
  747.     ENDIF;
  748.  
  749.     IF newshrink <= 0 THEN
  750.         vi$info ("Can't shrink this window");
  751.         RETURN;
  752.     ENDIF;
  753.  
  754.     nextwin := vi$next_win (curwin);
  755.     prevwin := vi$prev_win (curwin);
  756.  
  757.     IF (nextwin <> 0) THEN
  758.         ADJUST_WINDOW (curwin, 0, -newshrink);
  759.         ADJUST_WINDOW (nextwin, -newshrink, 0);
  760.     ELSE
  761.         IF (prevwin <> 0) THEN
  762.             ADJUST_WINDOW (curwin, newshrink, 0);
  763.             ADJUST_WINDOW (prevwin, 0, newshrink);
  764.         ELSE
  765.             vi$info ("Can't shrink this window");
  766.             RETURN;
  767.         ENDIF;
  768.     ENDIF;
  769.     POSITION (curwin);
  770.     vi$pos_in_middle (MARK(NONE));
  771. ENDPROCEDURE;
  772.  
  773. !
  774. !   Enlarge the current window if possible.  Try moving the bottom down.
  775. !   If that doesn't work, then try moving the top up.
  776. !
  777. PROCEDURE vi$enlarge_window (enlargeparm)
  778.  
  779.     LOCAL
  780.         curwin,
  781.         prevwin,
  782.         nextwin,
  783.         nextrow,
  784.         newenlarge,
  785.         prevrow;
  786.  
  787.     IF (vi$in_occlusion) THEN
  788.         RETURN;
  789.     ENDIF;
  790.  
  791.     newenlarge := enlargeparm;
  792.  
  793.     curwin := GET_INFO (WINDOWS, "CURRENT");
  794.  
  795.     nextwin := vi$next_win (curwin);
  796.     prevwin := vi$prev_win (curwin);
  797.  
  798.     IF (nextwin <> 0) THEN
  799.         nextrow := GET_INFO (nextwin, "VISIBLE_LENGTH");
  800.  
  801.         IF (nextrow > 2) then
  802.             IF (newenlarge + 2 > nextrow) THEN
  803.                 newenlarge := nextrow - 2;
  804.             ENDIF;
  805.  
  806.             IF newenlarge <= 0 THEN
  807.                 vi$info ("Can't enlarge this window");
  808.                 RETURN;
  809.             ENDIF;
  810.  
  811.             ADJUST_WINDOW (nextwin, newenlarge, 0);
  812.             ADJUST_WINDOW (curwin, 0, newenlarge);
  813.         ELSE
  814.             vi$info ("Can't shrink next window");
  815.             RETURN;
  816.         ENDIF;
  817.     ELSE
  818.         IF (prevwin <> 0) THEN
  819.  
  820.             prevrow := GET_INFO (prevwin, "VISIBLE_LENGTH");
  821.  
  822.             IF (prevrow < 3) THEN
  823.                 vi$info ("Can't shrink previous window");
  824.                 RETURN;
  825.             ENDIF;
  826.  
  827.             IF (newenlarge + 2 > prevrow) THEN
  828.                 newenlarge := prevrow - 2;
  829.             ENDIF;
  830.  
  831.             IF newenlarge = 0 THEN
  832.                 vi$info ("Can't enlarge this window");
  833.                 RETURN;
  834.             ENDIF;
  835.  
  836.             ADJUST_WINDOW (prevwin, 0, -newenlarge);
  837.             ADJUST_WINDOW (curwin, -newenlarge, 0);
  838.         ELSE
  839.             vi$info ("Can't enlarge this window");
  840.             RETURN;
  841.         ENDIF;
  842.     ENDIF;
  843.  
  844.     POSITION (curwin);
  845.     vi$pos_in_middle (MARK(NONE));
  846. ENDPROCEDURE;
  847.  
  848. !
  849. !   Set the status line for the window passed
  850. !
  851. PROCEDURE vi$set_status_line (win)
  852.     LOCAL
  853.         nowr,
  854.         buf,
  855.         fmtstr,
  856.         fn;
  857.  
  858.     IF (GET_INFO (win, "STATUS_VIDEO") <> REVERSE) THEN
  859.         RETURN;
  860.     ENDIF;
  861.  
  862.     buf := GET_INFO (win, "BUFFER");
  863.     nowr := " ";
  864.     IF (GET_INFO (buf, "NO_WRITE")) THEN
  865.         nowr := "*";
  866.     ENDIF;
  867.     fn := GET_INFO (buf, "NAME");
  868.     SET (STATUS_LINE, win, NONE, "");
  869.     fmtstr := "!" + STR (GET_INFO (win, "WIDTH"));
  870.     SET (STATUS_LINE, win, REVERSE,
  871.             FAO (fmtstr+"<!ASBuffer: !AS!>", nowr, fn));
  872. ENDPROCEDURE;
  873.  
  874. !
  875. !   Position the location passed into the middle of the current window.
  876. !
  877. PROCEDURE vi$pos_in_middle (pos)
  878.     LOCAL
  879.         leng,
  880.         s_amt,
  881.         s_bot,
  882.         s_top,
  883.         cur_window;
  884.  
  885.     ON_ERROR
  886.     ENDON_ERROR;
  887.  
  888.     cur_window    := CURRENT_WINDOW;
  889.     leng := GET_INFO (cur_window, "VISIBLE_LENGTH");
  890.  
  891.     s_amt := GET_INFO (cur_window, "SCROLL_AMOUNT");
  892.     s_bot := GET_INFO (cur_window, "SCROLL_TOP");
  893.     s_top := GET_INFO (cur_window, "SCROLL_BOTTOM");
  894.     SET (SCROLLING, cur_window, ON, 0, 0, leng/2);
  895.     POSITION (pos);
  896.     vi$update (cur_window);
  897.     SET (SCROLLING, cur_window, ON, s_top, s_bot, s_amt);
  898.     POSITION (pos);
  899. ENDPROCEDURE;
  900.  
  901. !
  902. !   Update the status lines for windows with the buffer passed mapped to them
  903. !
  904. PROCEDURE vi$status_lines (buf)
  905.     LOCAL
  906.         win;
  907.  
  908.     win := GET_INFO (WINDOWS, "FIRST");
  909.     LOOP
  910.         EXITIF (win = 0);
  911.         IF (GET_INFO (win, "BUFFER") = buf) THEN
  912.             vi$set_status_line (win);
  913.         ENDIF;
  914.         win := GET_INFO (WINDOWS, "NEXT");
  915.     ENDLOOP;
  916. ENDPROCEDURE;
  917.  
  918. !
  919. !   Send the string passed to a DCL process.  All the necessary stuff is
  920. !   done to move to the DCL buffer, and start the DCL process, and all
  921. !   of the other junk.
  922. !
  923. PROCEDURE vi$send_to_dcl (dcl_string)
  924.  
  925.     ON_ERROR
  926.         IF ERROR = TPU$_CREATEFAIL THEN
  927.             vi$info ("DCL subprocess could not be created");
  928.             RETURN (1);
  929.         ENDIF;
  930.     ENDON_ERROR;
  931.  
  932.     IF CURRENT_BUFFER <> vi$dcl_buf THEN
  933.  
  934.         IF (GET_INFO (vi$dcl_buf, "MAP_COUNT") > 0) AND
  935.                 (vi$in_occlusion = 0) THEN
  936.             POSITION (vi$dcl_buf);
  937.         ELSE
  938.  
  939.             ! Attempt to split the screen at the cursor position
  940.  
  941.             IF (vi$split_here = 1) THEN
  942.                 IF (vi$in_occlusion = 0) THEN
  943.                     vi$info ("Move cursor to middle of current window");
  944.                 ENDIF;
  945.                 RETURN (1);
  946.             ENDIF;
  947.  
  948.             MAP (CURRENT_WINDOW, vi$dcl_buf);
  949.         ENDIF;
  950.     ENDIF;
  951.  
  952.     POSITION (END_OF (vi$dcl_buf));
  953.     vi$status_lines (CURRENT_BUFFER);
  954.     UPDATE (CURRENT_WINDOW);
  955.  
  956.     IF (GET_INFO (vi$dcl_process, "TYPE") = UNSPECIFIED) OR
  957.                                                (vi$dcl_process = 0) THEN
  958.         vi$info ("Creating DCL subprocess...");
  959.         vi$dcl_process := CREATE_PROCESS (vi$dcl_buf);
  960.         IF (vi$dcl_process = 0) THEN
  961.             RETURN;
  962.         ENDIF;
  963.         vi$info ("Process was created");
  964.     ENDIF;
  965.  
  966.     SPLIT_LINE;
  967.     COPY_TEXT (dcl_string);
  968.     UPDATE (CURRENT_WINDOW);
  969.     SEND (dcl_string, vi$dcl_process);
  970.     POSITION (END_OF (vi$dcl_buf));
  971.     UPDATE (CURRENT_WINDOW);
  972.  
  973.     RETURN (0);
  974. ENDPROCEDURE;
  975.  
  976. !
  977. !
  978. !
  979. PROCEDURE vi$mess_select (mode)
  980.     LOCAL
  981.         pos;
  982.  
  983.     pos := MARK (NONE);
  984.     vi$message_select := 0;
  985.     POSITION (END_OF (message_buffer));
  986.     vi$message_select := SELECT (mode);
  987.     POSITION (pos);
  988. ENDPROCEDURE;
  989.  
  990. !
  991. !  Allow local modifications to be done here.
  992. !
  993. PROCEDURE tpu$local_init
  994. ENDPROCEDURE;
  995.  
  996. !
  997. !   Create a section file, and terminate.
  998. !
  999. vi$init_keys;
  1000. COMPILE ("PROCEDURE vi$init_keys ENDPROCEDURE;");
  1001. SAVE ("SYS$DISK:[]VI.GBL");
  1002. QUIT;
  1003. $$EOD$$
  1004.