v04i107: TPUVI for VMS part 16 of 17

Gregg Wonderly gregg at a.cs.okstate.edu
Wed Sep 28 08:20:10 AEST 1988


Posting-number: Volume 4, Issue 107
Submitted-by: "Gregg Wonderly" <gregg at a.cs.okstate.edu>
Archive-name: vms-vi-2/Part16

$ WRITE SYS$OUTPUT "Creating ""VI.12"""
$ CREATE VI.12
$ DECK/DOLLARS=$$EOD$$
    ENDIF;
    bn := bn + btype;

    found_one := vi$choose_buffer (bn, how_many_buffers,
                            possible_buffer, possible_buffer_name, loop_buffer);

    IF (found_one) THEN
        POSITION (pos);
        IF (CURRENT_BUFFER = loop_buffer) THEN
            vi$info ("Already positioned in that buffer");
        ELSE
            UNMAP (win);
            MAP (win, loop_buffer);
            vi$set_status_line (CURRENT_WINDOW);
            vi$what_line;
        ENDIF;
    ELSE
        vi$info (FAO (
            "No such buffer ""!AS"", buffer has been deleted!", bn));
        POSITION (vi$file_names);
        MOVE_VERTICAL (1);
    ENDIF;

    POSITION (win);
    vi$kill_undo;
    vi$undo_end := 0;
    RETURN (1);
ENDPROCEDURE

!
!   This procedure should be envoked after a wild card edit.  It will allow
!   a list of files that have been created due to a wildcard filespec to be
!   processed sequentially.
!
PROCEDURE vi$_previous_file (bang)
    LOCAL
        win,
        fn,
        pos,
        found_one,
        btype,
        bn,
        how_many_buffers,
        possible_buffer,
        possible_buffer_name,
        loop_buffer,
        line;

    ON_ERROR
        ! Ignore errors
    ENDON_ERROR;

    IF (NOT bang) AND (vi$check_auto_write) THEN
        RETURN;
    ENDIF;

    pos := MARK (NONE);
    win := CURRENT_WINDOW;

    fn := GET_INFO (CURRENT_BUFFER, "OUTPUT_FILE");

    POSITION (vi$file_names);
    IF (MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER)) THEN
        IF (MARK (NONE) = END_OF (CURRENT_BUFFER)) THEN
            MOVE_VERTICAL (-1);
        ENDIF;
        MOVE_VERTICAL (-1);
    ELSE
        vi$info ("No previous file!");
        POSITION (pos);
        RETURN (1);
    ENDIF;

    fn := vi$current_line;

    bn := FILE_PARSE (fn, "", "", NAME);
    btype := FILE_PARSE (fn, "", "", TYPE);

    IF btype = "" THEN
        btype := ".";
    ENDIF;
    bn := bn + btype;

    found_one := vi$choose_buffer (bn, how_many_buffers,
                            possible_buffer, possible_buffer_name, loop_buffer);

    IF (found_one) THEN
        POSITION (pos);
        IF (CURRENT_BUFFER = loop_buffer) THEN
            vi$info ("Already positioned in that buffer");
        ELSE
            UNMAP (win);
            MAP (win, loop_buffer);
            vi$set_status_line (CURRENT_WINDOW);
        ENDIF;
    ELSE
        vi$info ("No previous file!");
    ENDIF;

    vi$kill_undo;
    vi$undo_end := 0;
    POSITION (win);
    RETURN (1);
ENDPROCEDURE

!
!   Map first file in file list to the current window, providing it makes
!   sense to do so (eg. no mapping should be done to the command window.
!
PROCEDURE vi$_first_file (bang)
    LOCAL
        win,
        fn,
        pos,
        found_one,
        btype,
        bn,
        how_many_buffers,
        possible_buffer,
        possible_buffer_name,
        loop_buffer,
        line;

    ON_ERROR
        ! Ignore errors
    ENDON_ERROR;

    IF (NOT bang) AND (vi$check_auto_write) THEN
        RETURN;
    ENDIF;

    pos := MARK (NONE);
    win := CURRENT_WINDOW;

    POSITION (BEGINNING_OF (vi$file_names));
    IF (MARK (NONE) = END_OF (vi$file_names)) THEN
        vi$info ("No filename list!");
        POSITION (pos);
        RETURN (1);
    ENDIF;

    fn := vi$current_line;

    bn := FILE_PARSE (fn, "", "", NAME);
    btype := FILE_PARSE (fn, "", "", TYPE);

    IF btype = "" THEN
        btype := ".";
    ENDIF;

    bn := bn + btype;

    found_one := vi$choose_buffer (bn, how_many_buffers,
                            possible_buffer, possible_buffer_name, loop_buffer);

    IF (found_one) THEN
        POSITION (pos);
        IF (CURRENT_BUFFER = loop_buffer) THEN
            vi$info ("Already positioned in that buffer");
        ELSE
            UNMAP (win);
            MAP (win, loop_buffer);
            vi$set_status_line (CURRENT_WINDOW);
        ENDIF;
    ELSE
        vi$info ("Buffer not found: " + bn + "!");
    ENDIF;

    vi$kill_undo;
    vi$undo_end := 0;
    POSITION (win);
    RETURN (1);
ENDPROCEDURE;

!
!   Show the contents of the tags buffer
!
PROCEDURE vi$_show_tags
    vi$show_list (vi$tag_buf,
        "Current tags from the files: "+vi$tag_files, info_window)
ENDPROCEDURE;

!
!   Show the list of filenames currently being used by the NEXT FILE, FIRST
!   FILE, and PREVIOUS FILE commands.
!
PROCEDURE vi$_show_files
    vi$show_list (vi$file_names,
"  File names currently active for PREVIOUS, FIRST and NEXT line mode commands",
        info_window)

ENDPROCEDURE;

!
!   Show a buffer, dbuf, in a window, dwin, with the status line set to 'stat'.
!   Allow scrolling around, but no editing.  <ENTER> gets you out.
!
PROCEDURE vi$show_list (dbuf, stat, dwin)

    LOCAL
        this_key,
        win,
        pos;

    win := CURRENT_WINDOW;
    pos := MARK (NONE);

    MAP (dwin, dbuf);
    SET (STATUS_LINE, dwin, NONE, "");
    SET (STATUS_LINE, dwin, REVERSE, stat);
    POSITION (dwin);
    SET (EOB_TEXT, dbuf,
"[Press RETURN to continue editing]                        ");
    UPDATE (dwin);

    LOOP
        this_key := vi$read_a_key;
        EXITIF (this_key = RET_KEY);

        IF (this_key = CTRL_D_KEY) OR
           (this_key = CTRL_U_KEY) OR
           (this_key = CTRL_F_KEY) OR
           (this_key = CTRL_B_KEY) OR
           (this_key = KEY_NAME ('h')) OR
           (this_key = KEY_NAME ('j')) OR
           (this_key = KEY_NAME ('k')) OR
           (this_key = KEY_NAME ('l')) THEN

            EXECUTE (LOOKUP_KEY (this_key, PROGRAM, vi$cmd_keys));
            UPDATE (CURRENT_WINDOW);
        ENDIF;
    ENDLOOP;

    UNMAP (dwin);
    SET (STATUS_LINE, dwin, NONE, "");
    SET (EOB_TEXT, dbuf, "");
    POSITION (win);
    POSITION (pos);
ENDPROCEDURE;

!
!   This procedure creates a new buffer with the named file in it.
!   Checking is done to see if the input file exists, and CREATE was on
!   the command line, etc...
!
PROCEDURE vi$_create_buffer (buffer_name, req_name, actual_file_name)

    LOCAL
        info,
        succ,
        outf,
        new_buffer;     ! Buffer created

    ON_ERROR
        IF ERROR = TPU$_DUPBUFNAME THEN
            vi$info (FAO ("Buffer !AS already exists", buffer_name));
            RETURN (0);
        ENDIF;
    ENDON_ERROR;

    IF (actual_file_name = 0) OR (actual_file_name = "") THEN
        new_buffer := CREATE_BUFFER (buffer_name);

        IF (req_name <> 0) THEN
            outf := FILE_PARSE (req_name);
            vi$info (FAO ("New file ""!AS""", outf));
            SET (OUTPUT_FILE, new_buffer, outf);
        ENDIF;
    ELSE
        vi$info ("Reading file """+actual_file_name+"""");
        new_buffer := CREATE_BUFFER (buffer_name, actual_file_name);

        vi$info (FAO ("""!AS"", !UL lines", actual_file_name,
            GET_INFO (new_buffer, "RECORD_COUNT")));

        IF (vi$starting_up) THEN
            IF GET_INFO (COMMAND_LINE, "OUTPUT") THEN
                SET (OUTPUT_FILE, new_buffer,
                    FILE_PARSE (GET_INFO (COMMAND_LINE, "OUTPUT_FILE"),
                                                        actual_file_name));

                !  Set the buffer to be modified so that the file will
                !  be written on exit.

                SPLIT_LINE;
                APPEND_LINE;
            ENDIF;
        ELSE
            SET (OUTPUT_FILE, new_buffer, actual_file_name);
        ENDIF;
    ENDIF;

    IF (vi$check_auto_write) THEN
        RETURN;
    ENDIF;

    vi$setbufmode (new_buffer, vi$readonly);

    MAP (CURRENT_WINDOW, new_buffer);
    vi$status_lines (new_buffer);

    SET (TAB_STOPS, new_buffer, vi$tab_amount);

    RETURN (new_buffer);
ENDPROCEDURE;

!
!   Add a string to the end of the choice buffer
!
PROCEDURE vi$add_choice (choice_string)

    LOCAL
        pos;        ! Current position in the buffer

    pos := MARK (NONE);
    POSITION (END_OF (choice_buffer));
    COPY_TEXT (choice_string);
    POSITION (pos);
ENDPROCEDURE;

!
!   Put a message into the message window, and note that it is there.  The
!   main command procedure will remove it later.
!
PROCEDURE vi$info (mess)
    MESSAGE (mess);
    vi$did_mess := 1;
ENDPROCEDURE;

!
!   Print the system error message corresponding to the error code passed.
!
PROCEDURE vi$system_message (errno)
    vi$info (CALL_USER (vi$cu_getmsg, STR(errno)));
ENDPROCEDURE;

!
!  Below are the window manipulation routines.  They take care of
!  spliting and deleting windows.  The vi$prev_win and vi$next_win are
!  very VERY dependent on there not being any occusion of the windows
!  that they consider.  If a window is occluded, the results are
!  unpredictable.
!
!  Split the current window exactly where it is at
!
PROCEDURE vi$split_here

    LOCAL
        curwin,
        nextwin,
        curtop,
        curbuf,
        len,
        line,
        row,
        errno,
        spos,
        newwin,
        newlen,
        newtop,
        top;

    ON_ERROR
        errno := ERROR;
        line := ERROR_LINE;
        vi$info ("ERROR at line: "+ STR (line));
        vi$system_message (errno);
        RETURN(1);
    ENDON_ERROR

    IF (vi$in_occlusion) THEN
        vi$info ("Can't split while MAKE FULL SCREEN is active");
        RETURN (1);
    ENDIF;

    spos := MARK (NONE);
    curwin  :=  CURRENT_WINDOW;
    row     :=  GET_INFO (curwin, "CURRENT_ROW");
    top     :=  GET_INFO (curwin, "VISIBLE_TOP");
    len     :=  GET_INFO (curwin, "VISIBLE_LENGTH");

    IF (row - top < 1) OR (top + len - row < 3) THEN

        IF (len < 3) THEN
            vi$info ("Can't split window");
            RETURN(1);
        ENDIF;
        row := top + (len/2) - 1;
    ENDIF;

    curbuf := GET_INFO (curwin, "BUFFER");
    UNMAP (curwin);
    DELETE (curwin);

    ! Create the upper window.

    newlen := row - top + 1;
    newwin := CREATE_WINDOW (top, newlen, ON);

    MAP (newwin, curbuf);
    vi$set_status_line (newwin);

    ! Create the lower window.

    newtop := row + 1;
    newwin := CREATE_WINDOW (newtop, len - (newtop - top), ON);

    MAP (newwin, curbuf);
    vi$set_status_line (newwin);

    POSITION (newwin);
    vi$pos_in_middle (MARK (NONE));
    vi$previous_window;
    vi$pos_in_middle (MARK (NONE));

    vi$this_window := CURRENT_WINDOW;

    RETURN (0);
ENDPROCEDURE;

!
!   This procedure is used to initialize some things that are necessarily
!   changed when the editing environment changes because of window or other
!   operations.
!
PROCEDURE vi$new_env
    vi$how_much_scroll := GET_INFO (CURRENT_WINDOW, "VISIBLE_LENGTH") / 2;
    vi$new_offset := 1;
ENDPROCEDURE;

!
!  Delete the current window
!
PROCEDURE vi$delete_window
    LOCAL
        curwin;

    IF (vi$in_occlusion) THEN
        IF (CURRENT_WINDOW <> vi$occluding_win) THEN
            vi$info ("Can't delete this window.");
            RETURN;
        ENDIF;

        UNMAP (vi$old_occ_win);
        MAP (vi$old_occ_win, CURRENT_BUFFER);
        DELETE (vi$occluding_win);
        vi$in_occlusion := 0;
        vi$set_status_line (CURRENT_WINDOW);
        vi$new_env;
    ELSE
        curwin  := GET_INFO (WINDOWS, "CURRENT");
        vi$del_win (curwin);
    ENDIF;
ENDPROCEDURE;

!
!   Do the actual work of deleting a window
!
PROCEDURE vi$del_win (curwin)

    LOCAL
        max_len,        ! Maximum length of screen minus the
                        ! command window and message window
        prevwin,        ! Window before the current
        nextwin,        ! Window below the current
        prevtop,        ! Top line of previous window
        nexttop,        ! Top line of next window
        curtop,         ! Top line of current window
        prevbuf,        ! Buffer mapped to previous window
        prevlen,        ! Length of previous window
        curlen,         ! Length of current window
        nextbuf,        ! Buffer mapped to next window
        nextend,        ! Last line of next window
        newwin,
        nextlen;        ! Length of next window

    max_len := vi$scr_length - 2;
    prevwin := vi$prev_win (curwin);
    nextwin := vi$next_win (curwin);
    curlen  := GET_INFO (curwin, "VISIBLE_LENGTH");
    curtop  := GET_INFO (curwin, "VISIBLE_TOP");

    IF (nextwin <> 0) THEN
        nextend := GET_INFO (nextwin, "VISIBLE_BOTTOM");
    ELSE
        nextend := max_len+1;  ! Something greater than the max_len used below
    ENDIF;

    IF (nextwin <> 0) AND (nextend <= max_len) THEN
        nextlen := GET_INFO (nextwin, "VISIBLE_LENGTH");
        nextbuf := GET_INFO (nextwin, "BUFFER");
        newwin := CREATE_WINDOW (curtop, curlen+nextlen, ON);
        UNMAP (curwin);
        UNMAP (nextwin);
        MAP (newwin, nextbuf);
        vi$set_status_line (newwin);
        DELETE (curwin);
        DELETE (nextwin);
    ELSE
        IF (prevwin <> 0) THEN
            prevlen := GET_INFO (prevwin, "VISIBLE_LENGTH");
            prevbuf := GET_INFO (prevwin, "BUFFER");
            prevtop := GET_INFO (prevwin, "VISIBLE_TOP");
            newwin := CREATE_WINDOW (prevtop, curlen+prevlen, ON);
            UNMAP (curwin);
            UNMAP (prevwin);
            MAP (newwin, prevbuf);
            vi$set_status_line (newwin);
            DELETE (curwin);
            DELETE (prevwin);
        ELSE
            vi$info ("Can't delete this window");
            RETURN;
        ENDIF;
    ENDIF;

    IF (vi$prev_win (CURRENT_WINDOW) = 0) THEN
        IF (vi$next_win (CURRENT_WINDOW) = 0) THEN
            SET (STATUS_LINE, CURRENT_WINDOW, NONE, "");
            REFRESH;
        ENDIF;
    ENDIF;
    vi$this_window := CURRENT_WINDOW;
    vi$pos_in_middle (MARK (NONE));
    vi$new_env;
ENDPROCEDURE;

!
!   Take the current buffer (if there is more than one window displayed on the
!   screen), and remap it to a new window that occludes all others and is
!   the size of the screen.
!
PROCEDURE vi$make_full_screen

    LOCAL
        win,
        buf;

    IF (vi$in_occlusion) THEN
        vi$info ("Already in full screen");
        RETURN;
    ENDIF;

    IF (vi$next_win (CURRENT_WINDOW) = 0) THEN
        IF (vi$prev_win (CURRENT_WINDOW) = 0) THEN
            vi$info ("Current window is only window");
            RETURN;
        ENDIF;
    ENDIF;

    vi$old_occ_win := CURRENT_WINDOW;

    buf := CURRENT_BUFFER;
    win := CREATE_WINDOW (1, vi$scr_length - 1, ON);
    vi$occluding_win := win;

    IF (win <> 0) THEN
        vi$in_occlusion := 1;
        SET (STATUS_LINE, win, NONE, "");
        MAP (win, buf);
        vi$pos_in_middle (MARK (NONE));
        vi$new_env;
    ELSE
        vi$info ("Error creating window, command aborted!");
    ENDIF;
ENDPROCEDURE;

!
!  Move to next window going down the screen
!
PROCEDURE vi$next_window

    LOCAL
        nextwin,
        curwin;

    IF (vi$in_occlusion) THEN
        RETURN;
    ENDIF;

    curwin := CURRENT_WINDOW;
    nextwin := vi$next_win (curwin);

    IF (nextwin <> 0) THEN
        POSITION (nextwin);
        vi$set_status_line (nextwin);
        vi$new_env;
    ENDIF;
ENDPROCEDURE;

!
!  Move to previous window going up the screen
!
PROCEDURE vi$previous_window

    LOCAL
        prevwin,
        curwin;

    IF (vi$in_occlusion) THEN
        RETURN;
    ENDIF;

    curwin := CURRENT_WINDOW;
    prevwin := vi$prev_win (curwin);

    IF (prevwin <> 0) THEN
        POSITION (prevwin);
        vi$set_status_line (prevwin);
        vi$new_env;
    ENDIF;
ENDPROCEDURE;

!
!   Return the window that is below the current one, or ZERO if there is
!   none.  Note the special case that occurs while MAKE_FULL_SCREEN is active.
!
PROCEDURE vi$next_win (win)

    LOCAL
        winbot,
        nexttop,
        nextwin;

    IF (vi$in_occlusion) THEN
        RETURN (0);
    ENDIF;

    nextwin := GET_INFO (WINDOWS, "FIRST");
    winbot := GET_INFO (win, "VISIBLE_BOTTOM");

    IF (winbot >= (vi$scr_length - 3)) THEN
        RETURN (0);
    ENDIF;

    LOOP
        EXITIF nextwin = 0;

        IF (GET_INFO (nextwin, "BUFFER") <> 0) THEN
            nexttop := GET_INFO (nextwin, "VISIBLE_TOP");

            IF (winbot + 2 = nexttop) THEN
                RETURN (nextwin);
            ENDIF;
        ENDIF;

        nextwin := GET_INFO (nextwin, "NEXT");
    ENDLOOP;

    RETURN (0);
ENDPROCEDURE;

!
!   Return the window that is above the current one, or ZERO if there is
!   none.  Note the special case that occurs while MAKE_FULL_SCREEN is active.
!
PROCEDURE vi$prev_win (win)

    LOCAL
        max_len,    ! Maximum length of screen minus the
                    ! command window, and message window.
        wintop,
        prevbot,
        prevwin;

    IF (vi$in_occlusion) THEN
        RETURN(0);
    ENDIF;

    max_len := vi$scr_length - 1;
    prevwin := GET_INFO (WINDOWS, "FIRST");
    wintop := GET_INFO (win, "VISIBLE_TOP");

    IF (max_len <= wintop) THEN
        RETURN (0);
    ENDIF;

    IF (max_len - 1 = GET_INFO (win, "VISIBLE_BOTTOM")) AND (wintop = 1) THEN
        RETURN (0);
    ENDIF;

    LOOP
        EXITIF prevwin = 0;

        IF (GET_INFO (prevwin, "BUFFER") <> 0) THEN
            prevbot := GET_INFO (prevwin, "VISIBLE_BOTTOM");

            IF (prevbot + 2 = wintop) THEN
                RETURN (prevwin);
            ENDIF;
        ENDIF;

        prevwin := GET_INFO (prevwin, "NEXT");
    ENDLOOP;

    RETURN (0);
ENDPROCEDURE;

!
!   Shrink the current window, lengthing the lower window if possible first.
!   If there is no window below, then try above.  If can't do that either,
!   then give up with a message
!
PROCEDURE vi$shrink_window (shrinkparm)

    LOCAL
        curwin,
        currow,
        prevwin,
        nextwin,
        newshrink;

    IF (vi$in_occlusion) THEN
        RETURN;
    ENDIF;

    newshrink := shrinkparm;

    curwin := GET_INFO (WINDOWS, "CURRENT");
    currow := GET_INFO (curwin, "VISIBLE_LENGTH");

    IF (currow < 3) THEN
        vi$info ("Can't shrink this window");
        RETURN;
    ENDIF;

    IF newshrink > currow - 2 THEN
        newshrink := currow - 2;
    ENDIF;

    IF newshrink <= 0 THEN
        vi$info ("Can't shrink this window");
        RETURN;
    ENDIF;

    nextwin := vi$next_win (curwin);
    prevwin := vi$prev_win (curwin);

    IF (nextwin <> 0) THEN
        ADJUST_WINDOW (curwin, 0, -newshrink);
        ADJUST_WINDOW (nextwin, -newshrink, 0);
    ELSE
        IF (prevwin <> 0) THEN
            ADJUST_WINDOW (curwin, newshrink, 0);
            ADJUST_WINDOW (prevwin, 0, newshrink);
        ELSE
            vi$info ("Can't shrink this window");
            RETURN;
        ENDIF;
    ENDIF;
    POSITION (curwin);
    vi$pos_in_middle (MARK(NONE));
ENDPROCEDURE;

!
!   Enlarge the current window if possible.  Try moving the bottom down.
!   If that doesn't work, then try moving the top up.
!
PROCEDURE vi$enlarge_window (enlargeparm)

    LOCAL
        curwin,
        prevwin,
        nextwin,
        nextrow,
        newenlarge,
        prevrow;

    IF (vi$in_occlusion) THEN
        RETURN;
    ENDIF;

    newenlarge := enlargeparm;

    curwin := GET_INFO (WINDOWS, "CURRENT");

    nextwin := vi$next_win (curwin);
    prevwin := vi$prev_win (curwin);

    IF (nextwin <> 0) THEN
        nextrow := GET_INFO (nextwin, "VISIBLE_LENGTH");

        IF (nextrow > 2) then
            IF (newenlarge + 2 > nextrow) THEN
                newenlarge := nextrow - 2;
            ENDIF;

            IF newenlarge <= 0 THEN
                vi$info ("Can't enlarge this window");
                RETURN;
            ENDIF;

            ADJUST_WINDOW (nextwin, newenlarge, 0);
            ADJUST_WINDOW (curwin, 0, newenlarge);
        ELSE
            vi$info ("Can't shrink next window");
            RETURN;
        ENDIF;
    ELSE
        IF (prevwin <> 0) THEN

            prevrow := GET_INFO (prevwin, "VISIBLE_LENGTH");

            IF (prevrow < 3) THEN
                vi$info ("Can't shrink previous window");
                RETURN;
            ENDIF;

            IF (newenlarge + 2 > prevrow) THEN
                newenlarge := prevrow - 2;
            ENDIF;

            IF newenlarge = 0 THEN
                vi$info ("Can't enlarge this window");
                RETURN;
            ENDIF;

            ADJUST_WINDOW (prevwin, 0, -newenlarge);
            ADJUST_WINDOW (curwin, -newenlarge, 0);
        ELSE
            vi$info ("Can't enlarge this window");
            RETURN;
        ENDIF;
    ENDIF;

    POSITION (curwin);
    vi$pos_in_middle (MARK(NONE));
ENDPROCEDURE;

!
!   Set the status line for the window passed
!
PROCEDURE vi$set_status_line (win)
    LOCAL
        nowr,
        buf,
        fmtstr,
        fn;

    IF (GET_INFO (win, "STATUS_VIDEO") <> REVERSE) THEN
        RETURN;
    ENDIF;

    buf := GET_INFO (win, "BUFFER");
    nowr := " ";
    IF (GET_INFO (buf, "NO_WRITE")) THEN
        nowr := "*";
    ENDIF;
    fn := GET_INFO (buf, "NAME");
    SET (STATUS_LINE, win, NONE, "");
    fmtstr := "!" + STR (GET_INFO (win, "WIDTH"));
    SET (STATUS_LINE, win, REVERSE,
            FAO (fmtstr+"<!ASBuffer: !AS!>", nowr, fn));
ENDPROCEDURE;

!
!   Position the location passed into the middle of the current window.
!
PROCEDURE vi$pos_in_middle (pos)
    LOCAL
        leng,
        s_amt,
        s_bot,
        s_top,
        cur_window;

    ON_ERROR
    ENDON_ERROR;

    cur_window    := CURRENT_WINDOW;
    leng := GET_INFO (cur_window, "VISIBLE_LENGTH");

    s_amt := GET_INFO (cur_window, "SCROLL_AMOUNT");
    s_bot := GET_INFO (cur_window, "SCROLL_TOP");
    s_top := GET_INFO (cur_window, "SCROLL_BOTTOM");
    SET (SCROLLING, cur_window, ON, 0, 0, leng/2);
    POSITION (pos);
    vi$update (cur_window);
    SET (SCROLLING, cur_window, ON, s_top, s_bot, s_amt);
    POSITION (pos);
ENDPROCEDURE;

!
!   Update the status lines for windows with the buffer passed mapped to them
!
PROCEDURE vi$status_lines (buf)
    LOCAL
        win;

    win := GET_INFO (WINDOWS, "FIRST");
    LOOP
        EXITIF (win = 0);
        IF (GET_INFO (win, "BUFFER") = buf) THEN
            vi$set_status_line (win);
        ENDIF;
        win := GET_INFO (WINDOWS, "NEXT");
    ENDLOOP;
ENDPROCEDURE;

!
!   Send the string passed to a DCL process.  All the necessary stuff is
!   done to move to the DCL buffer, and start the DCL process, and all
!   of the other junk.
!
PROCEDURE vi$send_to_dcl (dcl_string)

    ON_ERROR
        IF ERROR = TPU$_CREATEFAIL THEN
            vi$info ("DCL subprocess could not be created");
            RETURN (1);
        ENDIF;
    ENDON_ERROR;

    IF CURRENT_BUFFER <> vi$dcl_buf THEN

        IF (GET_INFO (vi$dcl_buf, "MAP_COUNT") > 0) AND
                (vi$in_occlusion = 0) THEN
            POSITION (vi$dcl_buf);
        ELSE

            ! Attempt to split the screen at the cursor position

            IF (vi$split_here = 1) THEN
                IF (vi$in_occlusion = 0) THEN
                    vi$info ("Move cursor to middle of current window");
                ENDIF;
                RETURN (1);
            ENDIF;

            MAP (CURRENT_WINDOW, vi$dcl_buf);
        ENDIF;
    ENDIF;

    POSITION (END_OF (vi$dcl_buf));
    vi$status_lines (CURRENT_BUFFER);
    UPDATE (CURRENT_WINDOW);

    IF (GET_INFO (vi$dcl_process, "TYPE") = UNSPECIFIED) OR
                                               (vi$dcl_process = 0) THEN
        vi$info ("Creating DCL subprocess...");
        vi$dcl_process := CREATE_PROCESS (vi$dcl_buf);
        IF (vi$dcl_process = 0) THEN
            RETURN;
        ENDIF;
        vi$info ("Process was created");
    ENDIF;

    SPLIT_LINE;
    COPY_TEXT (dcl_string);
    UPDATE (CURRENT_WINDOW);
    SEND (dcl_string, vi$dcl_process);
    POSITION (END_OF (vi$dcl_buf));
    UPDATE (CURRENT_WINDOW);

    RETURN (0);
ENDPROCEDURE;

!
!
!
PROCEDURE vi$mess_select (mode)
    LOCAL
        pos;

    pos := MARK (NONE);
    vi$message_select := 0;
    POSITION (END_OF (message_buffer));
    vi$message_select := SELECT (mode);
    POSITION (pos);
ENDPROCEDURE;

!
!  Allow local modifications to be done here.
!
PROCEDURE tpu$local_init
ENDPROCEDURE;

!
!   Create a section file, and terminate.
!
vi$init_keys;
COMPILE ("PROCEDURE vi$init_keys ENDPROCEDURE;");
SAVE ("SYS$DISK:[]VI.GBL");
QUIT;
$$EOD$$



More information about the Comp.sources.misc mailing list