home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!husc6!necntc!ncoast!allbery
- From: gregg@a.cs.okstate.edu@mandrill.CWRU.Edu (Gregg Wonderly)
- Newsgroups: comp.sources.misc
- Subject: VI in TPU part 10/13
- Message-ID: <4859@ncoast.UUCP>
- Date: 13 Oct 87 02:54:43 GMT
- Sender: allbery@ncoast.UUCP
- Organization: Oklahoma State Univ., Stillwater
- Lines: 1504
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8710/vms-vi/10
-
- $ WRITE SYS$OUTPUT "Creating ""VI.9"""
- $ CREATE VI.9
- $ DECK/DOLLARS=$$EOD$$
- vi$active_count := 0;
- ENDPROCEDURE;
-
- !
- ! Move to line in file. vi$active_count holds the line number to GO TO.
- ! If VI$ACTIVE_COUNT is zero, we move to the end of the file.
- !
- PROCEDURE vi$to_line (cnt)
-
- LOCAL
- this_pos, ! Saved position in case of botch
- last_line, ! Last line in the buffer
- win_len; ! Length of CURRENT_WINDOW
-
- ON_ERROR
- vi$message (FAO ("No such line: !SL", VI$ACTIVE_COUNT));
- POSITION (this_pos);
- cnt := 0;
- RETURN;
- ENDON_ERROR;
-
- this_pos := MARK(NONE);
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
- vi$start_pos := MARK (NONE);
-
- IF cnt = 0 THEN
- POSITION (END_OF (CURRENT_BUFFER));
- ELSE
- last_line := GET_INFO (CURRENT_BUFFER, "RECORD_COUNT");
-
- IF cnt > last_line THEN
- IF last_line > 0 THEN
- vi$message ("Not that many lines in buffer");
- POSITION (this_pos);
- RETURN (0);
- ENDIF;
- ELSE
- POSITION (BEGINNING_OF (CURRENT_BUFFER));
- win_len := GET_INFO (CURRENT_WINDOW, "VISIBLE_LENGTH");
- MOVE_VERTICAL (cnt - 1);
- cnt := 0;
- ENDIF;
- ENDIF;
-
- IF (MARK (NONE) <> END_OF (CURRENT_BUFFER)) THEN
- MOVE_VERTICAL (1);
- MOVE_HORIZONTAL (-1);
- vi$new_endpos := MARK (NONE);
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
- ENDIF;
-
- vi$yank_mode := VI$LINE_MODE;
- RETURN (vi$retpos (this_pos));
- ENDPROCEDURE;
-
- !
- ! Set a marker in the current buffer.
- !
- PROCEDURE vi$_set_mark
-
- LOCAL
- mark_char,
- mark_name,
- key_pressed;
-
- key_pressed := vi$read_a_key;
-
- mark_char := ASCII (key_pressed);
- IF (INDEX (vi$_lower_chars, mark_char) <> 0) THEN
- mark_name := "vi$mark_" + mark_char;
- EXECUTE (COMPILE (mark_name + " := MARK(NONE);"));
- ELSE
- vi$MESSAGE ("Invalid marker key!");
- ENDIF;
-
- ENDPROCEDURE;
-
- !
- ! Function mapped to "'" and "`".
- !
- PROCEDURE vi$_go_to_marker
- IF (vi$position (vi$to_marker, 1) <> 0) THEN
- vi$pos_in_middle (MARK (NONE));
- ENDIF;
- ENDPROCEDURE;
-
- !
- ! Function to move the marker indicated by the next keystroke.
- !
- PROCEDURE vi$to_marker
-
- LOCAL
- mode_key,
- pos,
- mark_name,
- mark_char,
- key_pressed;
-
- ON_ERROR;
- vi$message ("Mark not set!");
- RETURN (0);
- ENDON_ERROR;
-
- pos := MARK (NONE);
- mode_key := vi$last_key;
- key_pressed := vi$read_a_key;
-
- mark_char := ASCII (key_pressed);
- IF (INDEX (vi$_lower_chars+"'`", mark_char) = 0) THEN
- vi$MESSAGE ("Invalid marker key!");
- RETURN (0);
- ENDIF;
-
- IF (key_pressed <> F11) THEN
- IF (mark_char = "'") OR (mark_char = "`") THEN
- IF (vi$old_place <> 0) THEN
- IF (GET_INFO (vi$old_place, "BUFFER") = CURRENT_BUFFER) THEN
- POSITION (vi$old_place);
- ELSE
- MESSAGE ("Previous place not in this buffer!");
- RETURN (0);
- ENDIF;
- ELSE
- MESSAGE ("No previous mark to return to!");
- RETURN (0);
- ENDIF;
- ELSE
- mark_name := "vi$mark_" + mark_char;
- EXECUTE (COMPILE ("vi$global_mark := "+mark_name+";"));
-
- IF (vi$global_mark <> 0) AND (GET_INFO (vi$global_mark, "BUFFER") =
- CURRENT_BUFFER) THE
- N
- POSITION (vi$global_mark);
- vi$yank_mode := VI$LINE_MODE;
- ELSE
- vi$message ("Invalid mark for this buffer!");
- RETURN (0);
- ENDIF;
- ENDIF;
-
- IF ASCII (mode_key) = "'" THEN
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
- POSITION (vi$first_no_space);
- ENDIF;
-
- IF (MARK (NONE) <> END_OF (CURRENT_BUFFER)) THEN
- MOVE_VERTICAL (1);
- vi$new_endpos := MARK (NONE);
- MOVE_VERTICAL (-1);
- ENDIF;
-
- RETURN (vi$retpos (pos));
- ENDIF;
-
- POSITION (pos);
- RETURN (0);
- ENDPROCEDURE;
-
- !
- ! Maintain the repeat count in vi$active_count. If VI$ACTIVE_COUNT is ZERO,
- ! and '0' is typed, this means move to beginning of the line.
- !
- PROCEDURE vi$repeat_count
-
- IF VI$ACTIVE_COUNT = 0 THEN
- vi$active_count := INT (ASCII (KEY_NAME (vi$last_key)));
- IF vi$active_count = 0 THEN
- vi$position (vi$fol, 0);
- ENDIF;
- ELSE
- vi$active_count := vi$active_count * 10 +
- INT (ASCII (KEY_NAME (vi$last_key)));
- ENDIF;
-
- ENDPROCEDURE;
-
- !
- ! The function mapped to <CR>.
- !
- PROCEDURE vi$_next_line
- POSITION (vi$beg_next);
- ENDPROCEDURE;
-
- !
- ! Move the cursor to the beginning of the next line
- !
- PROCEDURE vi$beg_next
- LOCAL
- pos;
-
- ON_ERROR
- RETURN (MARK (NONE));
- ENDON_ERROR;
-
- pos := MARK (NONE);
- MOVE_VERTICAL (vi$cur_active_count);
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
- POSITION (vi$first_no_space);
- vi$yank_mode := VI$LINE_MODE;
- vi$new_offset := 1;
- RETURN (vi$retpos (pos));
-
- ENDPROCEDURE;
-
- !
- ! This function moves to the first non-blank character of a line
- !
- PROCEDURE vi$first_no_space
-
- LOCAL
- pos,
- t_range;
-
- ON_ERROR
- ! Ignore string not found messages.
- ENDON_ERROR;
-
- pos := MARK (NONE);
- MOVE_HORIZONTAL (- CURRENT_OFFSET);
-
- IF (LENGTH (CURRENT_LINE) > 0) THEN
- IF t_range = 0 THEN
- t_range :=
- SEARCH (ANCHOR & SPAN (vi$no_space) &
- NOTANY(vi$no_space), FORWARD);
- ENDIF;
-
- IF t_range <> 0 THEN
- POSITION (END_OF (t_range));
- ELSE
- ! If that fails, then search for a blank line with extra white
- ! space, and move to the end of the white space.
-
- t_range := SEARCH (ANCHOR & SPAN (vi$no_space), FORWARD);
-
- IF t_range <> 0 THEN
- POSITION (END_OF (t_range));
- ENDIF;
- ENDIF;
- ENDIF;
-
- vi$yank_mode := VI$IN_LINE_MODE;
- RETURN (vi$retpos (pos));
- ENDPROCEDURE;
-
- !
- ! Move by a section in the indicated direction
- !
- PROCEDURE vi$_section (dir)
- LOCAL
- ch;
-
- ch := vi$read_a_key;
- IF ((ASCII(ch) = "]") AND (dir = 1)) OR
- ((ASCII(ch) = "[") AND (dir = -1)) THEN
- vi$position (vi$section (dir), 1);
- ELSE
- vi$beep;
- ENDIF;
- ENDPROCEDURE;
-
- !
- ! Sound a bell.
- !
- PROCEDURE vi$beep
- LOCAL
- pos;
-
- IF (vi$error_bells = 0) THEN
- RETURN;
- ENDIF;
-
- pos := CURRENT_WINDOW;
- SET (BELL, ALL, ON);
- MESSAGE ("");
- SET (BELL, ALL, OFF);
- SET (BELL, BROADCAST, ON);
- POSITION (pos);
- ENDPROCEDURE;
-
- !
- ! Mapped to '}' and '{', moves by a paragraph in the indicated direction.
- !
- PROCEDURE vi$_paragraph(dir)
- vi$position (vi$paragraph(dir), 1);
- ENDPROCEDURE;
-
- !
- ! Mapped to ( moves backward a sentence
- !
- PROCEDURE vi$_begin_sentence
- vi$position (vi$begin_sentence, 1);
- ENDPROCEDURE;
-
- !
- ! Mapped to ) moves forward a sentence
- !
- PROCEDURE vi$_end_sentence
- vi$position (vi$end_sentence, 1);
- ENDPROCEDURE;
-
- !
- ! Move backward a sentence.
- !
- PROCEDURE vi$begin_sentence
- LOCAL
- rng,
- spos,
- pos;
-
- ON_ERROR;
- ENDON_ERROR;
-
- pos := MARK (NONE);
-
- MOVE_HORIZONTAL (-1);
-
- LOOP;
- rng := SEARCH (
- (("" | " " | " ") & ANY (vi$_upper_chars)),
- REVERSE, EXACT);
-
- EXITIF rng = 0;
-
- POSITION (BEGINNING_OF (rng));
- IF INDEX (" ", CURRENT_CHARACTER) = 0 THEN
- MOVE_HORIZONTAL (-1);
- ENDIF;
- IF INDEX (" ", CURRENT_CHARACTER) <> 0 THEN
- IF (CURRENT_CHARACTER = " ") THEN
- MOVE_HORIZONTAL (-1);
- IF INDEX (" ", CURRENT_CHARACTER) <> 0 THEN
- MOVE_HORIZONTAL (-1);
- IF INDEX ("?.!", CURRENT_CHARACTER) <> 0 THEN
- MOVE_HORIZONTAL (3);
- RETURN (vi$retpos (pos));
- ENDIF;
- ENDIF;
- ELSE
- MOVE_HORIZONTAL (1);
- RETURN (vi$retpos (pos));
- ENDIF;
- ENDIF;
- POSITION (BEGINNING_OF (rng));
- MOVE_HORIZONTAL (-1);
- ENDLOOP;
-
- RETURN (0);
- ENDPROCEDURE;
-
- !
- ! Move to next paragraph
- !
- PROCEDURE vi$paragraph (dir)
- RETURN (vi$para_sect (dir, vi$para_pat));
- ENDPROCEDURE;
-
- !
- ! Find next paragraph or section.
- !
- PROCEDURE vi$para_sect (dir, pat)
- LOCAL
- loc,
- direct,
- pos;
-
- pos := MARK (NONE);
-
- IF (dir < 0) THEN
- direct := REVERSE;
- MOVE_VERTICAL (-1);
- ELSE
- direct := FORWARD;
- MOVE_VERTICAL (1);
- ENDIF;
-
- SET (TIMER, ON, "Searching...");
- loc := SEARCH (pat, direct, NO_EXACT);
- SET (TIMER, OFF);
-
- IF (loc <> 0) THEN
- RETURN (BEGINNING_OF (loc));
- ELSE
- SET (TIMER, ON, "Searching...");
- loc := SEARCH (vi$next_blank, direct, NO_EXACT);
- SET (TIMER, OFF);
- IF (loc <> 0) THEN
- RETURN (BEGINNING_OF (loc));
- ENDIF;
- ENDIF;
-
- POSITION (pos);
- RETURN (0);
- ENDPROCEDURE;
-
- !
- ! Move to next section
- !
- PROCEDURE vi$section (dir)
- RETURN (vi$para_sect (dir, vi$sect_pat));
- ENDPROCEDURE;
-
- !
- ! Move forward a sentence.
- !
- PROCEDURE vi$end_sentence
- LOCAL
- rng,
- spos,
- pos;
-
- ON_ERROR;
- ENDON_ERROR;
-
- pos := MARK (NONE);
-
- MOVE_HORIZONTAL (1);
-
- LOOP;
- rng := SEARCH (ANY (vi$_upper_chars), FORWARD, EXACT);
-
- EXITIF rng = 0;
-
- POSITION (BEGINNING_OF (rng));
- IF INDEX (" ", CURRENT_CHARACTER) = 0 THEN
- MOVE_HORIZONTAL (-1);
- ENDIF;
- IF INDEX (" ", CURRENT_CHARACTER) <> 0 THEN
- IF (CURRENT_CHARACTER = " ") THEN
- MOVE_HORIZONTAL (-1);
- IF INDEX (" ", CURRENT_CHARACTER) <> 0 THEN
- MOVE_HORIZONTAL (-1);
- IF INDEX ("?.!", CURRENT_CHARACTER) <> 0 THEN
- MOVE_HORIZONTAL (3);
- RETURN (vi$retpos (pos));
- ENDIF;
- ENDIF;
- ELSE
- MOVE_HORIZONTAL (1);
- RETURN (vi$retpos (pos));
- ENDIF;
- ENDIF;
- POSITION (BEGINNING_OF (rng));
- MOVE_HORIZONTAL (1);
- ENDLOOP;
-
- RETURN (0);
- ENDPROCEDURE;
-
- !
- ! This function returns the value in vi$active count. It takes into
- ! account that when vi$active_count is zero, it should really be
- ! one.
- !
- PROCEDURE vi$cur_active_count
- LOCAL
- resp,
- old_cnt;
-
- old_cnt := vi$active_count;
- vi$active_count := 0;
- IF old_cnt <= 0 THEN
- old_cnt := 1;
- ENDIF;
-
- RETURN (old_cnt);
- ENDPROCEDURE;
-
- !
- ! The function mapped to 'p'.
- !
- PROCEDURE vi$put_after (dest_buf)
-
- LOCAL
- source,
- pos;
-
- source := vi$cur_text;
-
- IF (GET_INFO (dest_buf, "TYPE") = BUFFER) THEN
- source := dest_buf;
- ENDIF;
-
- IF (GET_INFO (source, "TYPE") = BUFFER) THEN
- pos := MARK (NONE);
- POSITION (BEGINNING_OF (source));
- vi$yank_mode := INT (vi$current_line);
- POSITION (pos);
- ENDIF;
-
- IF (source = "") THEN
- RETURN;
- ENDIF;
-
- IF (vi$yank_mode = VI$LINE_MODE) THEN
- IF (MARK(NONE) <> END_OF (CURRENT_BUFFER)) THEN
- MOVE_VERTICAL (1);
- ENDIF;
- ELSE
- IF (LENGTH (CURRENT_LINE) > 0) THEN
- MOVE_HORIZONTAL (1);
- ENDIF;
- ENDIF;
-
- vi$put_here (VI$AFTER, source);
- ENDPROCEDURE;
-
- !
- ! The function mapped to 'P'.
- !
- PROCEDURE vi$put_here (here_or_below, dest_buf)
- LOCAL
- olen,
- source,
- pos;
-
- source := vi$cur_text;
- olen := GET_INFO (CURRENT_BUFFER, "RECORD_COUNT");
-
- IF (GET_INFO (dest_buf, "TYPE") = BUFFER) THEN
- source := dest_buf;
- ENDIF;
-
- IF (GET_INFO (source, "TYPE") = BUFFER) THEN
- pos := MARK (NONE);
- POSITION (BEGINNING_OF (source));
- IF (MARK (NONE) = END_OF (source)) THEN
- RETURN;
- ENDIF;
- vi$yank_mode := INT (vi$current_line);
- ERASE_LINE;
- POSITION (pos);
- ELSE
- IF (source = "") THEN
- RETURN;
- ENDIF;
- ENDIF;
-
- IF source = 0 THEN
- vi$message ("Bad buffer for put!");
- RETURN;
- ENDIF;
-
- IF (vi$yank_mode = VI$LINE_MODE) THEN
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
- ENDIF;
-
- pos := vi$get_undo_start;
-
- COPY_TEXT (source);
- APPEND_LINE;
- MOVE_HORIZONTAL (-1);
- vi$undo_end := MARK (NONE);
- MOVE_HORIZONTAL (1);
-
- vi$kill_undo;
-
- IF (here_or_below = VI$AFTER) AND (vi$yank_mode = VI$LINE_MODE) THEN
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
- ENDIF;
-
- vi$undo_start := vi$set_undo_start (pos);
-
- ! Put the mode back into the buffer.
-
- IF (GET_INFO (source, "TYPE") = BUFFER) THEN
- POSITION (BEGINNING_OF (source));
- COPY_TEXT (STR (vi$yank_mode));
- SPLIT_LINE;
- POSITION (vi$undo_start);
- ENDIF;
-
- IF (here_or_below = VI$AFTER) AND (vi$yank_mode = VI$IN_LINE_MODE) THEN
- POSITION (vi$undo_end);
- ENDIF;
-
- vi$check_length (olen);
- ENDPROCEDURE;
-
- !
- ! Function mapped to 'o'. Note that this makes undo NOT place
- ! the cursor where is really should be.
- !
- PROCEDURE vi$open_below
- LOCAL
- uline;
-
- ON_ERROR
- ! Ignore attempt to move past EOB errors
- ENDON_ERROR;
-
- uline := vi$cur_line_no;
- MOVE_VERTICAL (1);
- vi$open_here;
- vi$undo_line := uline;
-
- ENDPROCEDURE;
-
- !
- ! Function mapped to 'O'
- !
- PROCEDURE vi$open_here
-
- LOCAL
- uline,
- offs,
- cnt,
- epos,
- spos;
-
- uline := vi$cur_line_no;
- offs := CURRENT_OFFSET;
-
- MOVE_HORIZONTAL (- CURRENT_OFFSET);
-
- IF (MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER)) THEN
- MOVE_HORIZONTAL (-1);
- spos := MARK (NONE);
- MOVE_HORIZONTAL (1);
- ELSE
- spos := 0;
- ENDIF;
-
- SPLIT_LINE;
-
- MOVE_VERTICAL (-1);
-
- cnt := vi$while_not_esc;
- epos := MARK (NONE);
-
- IF (cnt <> 0) THEN
- IF (LENGTH (vi$current_line) > 0) THEN
- MOVE_HORIZONTAL (1);
- ENDIF;
- ENDIF;
-
- vi$undo_end := MARK (NONE);
-
- IF spos <> 0 THEN
- POSITION (spos);
- MOVE_HORIZONTAL (1);
- ELSE
- POSITION (BEGINNING_OF (CURRENT_BUFFER));
- ENDIF;
-
- vi$undo_start := MARK (NONE);
- POSITION (epos);
-
- vi$kill_undo;
-
- vi$undo_line := uline;
- vi$undo_offset := offs;
- ENDPROCEDURE;
-
- !
- ! This function guards the right margin, and the end of the buffer so
- ! that the cursor never is displayed past those boundries.
- !
- PROCEDURE vi$check_rmarg
-
- ON_ERROR;
- ! ignore "Can't return line and end of buffer" messages
- RETURN;
- ENDON_ERROR;
-
- IF (LENGTH (vi$current_line) > 0) THEN
- IF (CURRENT_OFFSET = LENGTH (vi$current_line)) THEN
- MOVE_HORIZONTAL (-1);
- ENDIF;
- ENDIF;
-
- IF (MARK (NONE) = END_OF (CURRENT_BUFFER)) THEN
- MOVE_VERTICAL (-1);
- ENDIF;
- ENDPROCEDURE;
-
- !
- ! The function mapped to 'h'.
- !
- PROCEDURE vi$move_left
- vi$position (vi$left, 0);
- ENDPROCEDURE;
-
- !
- ! The function mapped to 'l'.
- !
- PROCEDURE vi$move_right
- vi$position (vi$right, 0);
- ENDPROCEDURE;
-
- !
- ! The function mapped to 'j'
- !
- PROCEDURE vi$move_down
- LOCAL
- save_mark;
-
- save_mark := 0;
-
- IF (vi$active_count >= vi$report) THEN
- save_mark := 1;
- ENDIF;
-
- vi$position (vi$downline (0), save_mark);
- ENDPROCEDURE;
-
- !
- ! The function mapped to 'k'.
- !
- PROCEDURE vi$move_up
- LOCAL
- save_mark;
-
- save_mark := 0;
-
- IF (vi$active_count >= vi$report) THEN
- save_mark := 1;
- ENDIF;
-
- vi$position (vi$upline, save_mark);
- ENDPROCEDURE;
-
- !
- ! The function mapped to 'i'.
- !
- PROCEDURE vi$insert_here
- LOCAL
- act_cnt,
- rnge,
- ccnt,
- epos,
- spos;
-
- vi$kill_undo;
-
- IF (MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER)) THEN
- MOVE_HORIZONTAL (-1);
- spos := MARK (NONE);
- MOVE_HORIZONTAL (1);
- ELSE
- spos := 0;
- ENDIF;
-
- vi$undo_start := MARK (NONE);
-
- ccnt := vi$while_not_esc;
-
- vi$undo_end := 0;
-
- IF (ccnt > 0) THEN
- IF (CURRENT_OFFSET = 0) AND
- ((ccnt > 1) OR (LENGTH (CURRENT_LINE) = 0)) AND
- (MARK (NONE) <> BEGINNING_OF (CURRENT_BUFFER)) THEN
- MOVE_HORIZONTAL (-1);
- epos := MARK (NONE);
- MOVE_HORIZONTAL (1);
- ELSE
- epos := MARK (NONE);
- ENDIF;
- ELSE
- epos := 0;
- ENDIF;
-
- IF epos <> 0 THEN
- act_cnt := vi$cur_active_count;
-
- IF spos <> 0 THEN
- POSITION (spos);
- MOVE_HORIZONTAL (1);
- ELSE
- POSITION (BEGINNING_OF (CURRENT_BUFFER));
- ENDIF;
- vi$undo_start := MARK (NONE);
-
- POSITION (epos);
-
- IF (vi$undo_start = 0) OR (epos = 0) THEN
- vi$message ("Ooops, bad markers in vi$insert_here");
- RETURN ;
- ENDIF;
-
- rnge := CREATE_RANGE (vi$undo_start, epos, NONE);
-
- LOOP
- EXITIF act_cnt < 2;
- MOVE_HORIZONTAL (1);
-
- IF rnge = 0 THEN
- vi$message ("Ooops, generated a bad range in vi$insert_here");
- RETURN ;
- ENDIF;
-
- COPY_TEXT (rnge);
- act_cnt := act_cnt - 1;
- MOVE_HORIZONTAL (-1);
- ENDLOOP;
-
- vi$undo_end := MARK (NONE);
- IF (CURRENT_OFFSET = LENGTH (vi$current_line)) THEN
- MOVE_HORIZONTAL (1);
- ENDIF;
- ENDIF;
- ENDPROCEDURE;
-
- !
- ! The function mapped to 'I'
- !
- PROCEDURE vi$insert_at_begin
-
- MOVE_HORIZONTAL (- CURRENT_OFFSET);
- vi$_bol;
- vi$insert_here;
-
- ENDPROCEDURE;
-
- !
- ! The function mapped to 'a'
- !
- PROCEDURE vi$insert_after
-
- IF (LENGTH (vi$current_line) > 0) THEN
- IF (CURRENT_OFFSET < LENGTH(vi$current_line)) THEN
- MOVE_HORIZONTAL (1);
- ENDIF;
- ENDIF;
- vi$insert_here;
-
- ENDPROCEDURE;
-
- !
- ! A do nothing function
- !
- PROCEDURE vi$_dummy
- ENDPROCEDURE;
-
- !
- ! Do the command line input processing
- !
- PROCEDURE vi$while_not_esc
-
- LOCAL
- max_mark,
- start_pos,
- max_col;
-
- max_col := CURRENT_OFFSET;
- start_pos := max_col;
- max_mark := MARK(NONE);
- vi$update (CURRENT_WINDOW);
-
- RETURN (vi$line_edit (max_col, start_pos, max_mark, 0));
- ENDPROCEDURE;
-
- !
- ! Insert text into the buffer using standard VI insertion.
- ! Used by CHANGE, APPEND, INSERT, and REPLACE functions.
- !
- PROCEDURE vi$line_edit (max_col, start_pos, max_mark, replace)
-
- LOCAL
- chcnt,
- offset,
- seen_eol,
- col,
- cnt,
- tabstops,
- current_mark,
- desc,
- start_ins,
- ins_text,
- should_wrap,
- abbrs,
- rchar,
- abbrlen,
- cabbr,
- pos,
- in_char;
-
- ON_ERROR
- ENDON_ERROR;
-
- IF (vi$show_mode) THEN
- vi$mess_select (BOLD);
- MESSAGE (FAO ("!7* INSERT"));
- vi$mess_select (REVERSE);
- ENDIF;
- chcnt := 0;
- seen_eol := 0;
-
- abbrs := EXPAND_NAME ("vi$abbr_", VARIABLES) + " ";
-
- cabbr := "";
- abbrlen := 0;
-
- SET (INSERT, CURRENT_BUFFER);
- IF (max_col > CURRENT_OFFSET) OR (replace <> 0) THEN
- SET (OVERSTRIKE, CURRENT_BUFFER);
- ENDIF;
-
- start_ins := MARK (NONE);
-
- LOOP
- LOOP
- in_char := vi$read_a_key;
- desc := LOOKUP_KEY (KEY_NAME (in_char), COMMENT, vi$edit_keys);
- EXITIF (desc <> "reinsert");
-
- IF max_mark <> MARK (NONE) THEN
- current_mark := MARK (NONE);
- POSITION (max_mark);
- MOVE_HORIZONTAL (-1);
-
- ERASE (CREATE_RANGE (MARK (NONE), current_mark, NONE));
- ENDIF;
-
- SET (INSERT, CURRENT_BUFFER);
- COPY_TEXT (vi$last_insert);
- APPEND_LINE;
-
- max_col := CURRENT_OFFSET;
- start_pos := CURRENT_OFFSET;
- max_mark := MARK(NONE);
- chcnt := chcnt + 1;
- ENDLOOP;
-
- IF (desc = "active_macro") THEN
- EXECUTE (LOOKUP_KEY (KEY_NAME (in_char), PROGRAM, vi$edit_keys));
- ELSE
- EXITIF desc = "escape";
-
- should_wrap := (vi$wrap_margin <> 0) AND
- ((CURRENT_OFFSET + vi$wrap_margin) > vi$scr_width);
-
- IF (desc <> "eol") AND (desc <> "bword") AND (desc <> "bs") THEN
- IF (should_wrap) THEN
-
- offset := 0;
- MOVE_HORIZONTAL (-1);
-
- LOOP
- EXITIF (CURRENT_OFFSET = 0);
- EXITIF (INDEX (" ", CURRENT_CHARACTER) <> 0);
- MOVE_HORIZONTAL (-1);
- offset := offset + 1;
- ENDLOOP;
-
- IF (offset <> 0) THEN
- ERASE_CHARACTER (1);
- LOOP
- EXITIF (CURRENT_OFFSET = 0);
- MOVE_HORIZONTAL (-1);
- EXITIF (
- INDEX (" ", CURRENT_CHARACTER) = 0);
- ERASE_CHARACTER (1);
- ENDLOOP;
- ENDIF;
-
- IF (CURRENT_OFFSET <> 0) THEN
- MOVE_HORIZONTAL (1);
- SPLIT_LINE;
- max_col := CURRENT_OFFSET;
- start_pos := CURRENT_OFFSET;
- max_mark := MARK(NONE);
- MOVE_HORIZONTAL (offset);
- ELSE
- MOVE_HORIZONTAL (offset);
- SPLIT_LINE;
- max_col := CURRENT_OFFSET;
- start_pos := CURRENT_OFFSET;
- max_mark := MARK(NONE);
- ENDIF;
- ENDIF;
-
- vi$update (CURRENT_WINDOW);
-
- IF desc = "vquote" THEN
- in_char := vi$read_a_key;
- ENDIF;
-
- IF in_char = TAB_KEY THEN
- vi$abbr (abbrs, 0, cabbr, abbrlen);
- IF (vi$use_tabs = 1) THEN
- COPY_TEXT (ASCII (9));
- ELSE
- cnt := 0;
- col := GET_INFO (SCREEN, "CURRENT_COLUMN");
- tabstops := GET_INFO (CURRENT_BUFFER, "TAB_STOPS");
-
- IF (GET_INFO (tabstops, "TYPE") <> STRING) THEN
- LOOP
- EXITIF (col - ((col / tabstops) *
- tabstops) = 0);
- cnt := cnt + 1;
- col := col + 1;
- ENDLOOP;
-
- chcnt := chcnt + cnt;
- LOOP
- EXITIF (cnt < 0);
- IF (CURRENT_OFFSET = max_col) AND
- ((replace = 0) OR seen_eol) THE
- N
- SET (INSERT, CURRENT_BUFFER);
- ELSE
- IF CURRENT_OFFSET > max_col THEN
- max_col := CURRENT_OFFSET;
- max_mark := MARK (NONE);;
- ENDIF;
- ENDIF;
- COPY_TEXT (" ");
- cnt := cnt - 1;
- ENDLOOP
- ELSE
-
- ! Give up on windows with weird tab stops.
-
- COPY_TEXT (ASCII (9));
- ENDIF;
- ENDIF;
- chcnt := chcnt + 1;
- ELSE
- IF (in_char <= CTRL_Z_KEY) AND (in_char >= CTRL_A_KEY) THEN
- in_char := (in_char - CTRL_A_KEY) /
- (CTRL_B_KEY - CTRL_A_KEY) + 1;
- ENDIF;
-
- rchar := vi$ascii(in_char);
-
- IF (INDEX (vi$_ws, rchar) <> 0) THEN
- chcnt := chcnt + vi$abbr (abbrs, rchar, cabbr, abbrlen)
- ;
- ELSE
- COPY_TEXT (rchar);
- IF (INDEX(vi$_upper_chars, rchar) <> 0) THEN
- cabbr := cabbr + "_";
- ENDIF;
- cabbr := cabbr + rchar;
- abbrlen := abbrlen + 1;
- chcnt := chcnt + 1;
- ENDIF;
- ENDIF;
-
- IF (CURRENT_OFFSET = max_col) AND
- ((replace = 0) OR seen_eol) THEN
- SET (INSERT, CURRENT_BUFFER);
- ELSE
- IF CURRENT_OFFSET > max_col THEN
- max_col := CURRENT_OFFSET;
- max_mark := MARK (NONE);
- ENDIF;
- ENDIF;
- ELSE
- IF desc = "bs" THEN
- IF start_pos < CURRENT_OFFSET THEN
- ! Delete backspace and the character before it.
- vi$del_a_key;
- vi$del_a_key;
- SET (OVERSTRIKE, CURRENT_BUFFER);
- MOVE_HORIZONTAL (-1);
- chcnt := chcnt - 1;
- ENDIF;
- ELSE
- IF desc = "eol" THEN
- IF (max_mark <> MARK (NONE)) AND (replace = 0) THEN
- current_mark := MARK (NONE);
- POSITION (max_mark);
- MOVE_HORIZONTAL (-1);
- ERASE (CREATE_RANGE (MARK (NONE),
- current_mark, NONE));
- ENDIF;
- vi$abbr (abbrs, 0, cabbr, abbrlen);
- SPLIT_LINE;
- chcnt := chcnt + 1;
- seen_eol := 1;
- IF (CURRENT_BUFFER = vi$dcl_buf) AND (vi$send_dcl) THEN
- MOVE_VERTICAL (-1);
- vi$send_to_dcl (CURRENT_LINE);
- MOVE_VERTICAL (1);
- ENDIF;
- max_col := CURRENT_OFFSET;
- start_pos := CURRENT_OFFSET;
- SET (INSERT, CURRENT_BUFFER);
- max_mark := MARK(NONE);
- IF (CURRENT_BUFFER = vi$dcl_buf) AND (vi$send_dcl) THEN
- EXITIF (1);
- ENDIF;
- ELSE
- IF (desc = "bword") THEN
-
- ! Backup over whitespace.
-
- LOOP
- EXITIF start_pos = CURRENT_OFFSET;
- MOVE_HORIZONTAL (-1);
- chcnt := chcnt - 1;
- EXITIF (INDEX (" ", CURRENT_CHARACTER) = 0);
- SET (OVERSTRIKE, CURRENT_BUFFER);
- ENDLOOP;
-
- ! Backup over noblank words.
-
- LOOP
- EXITIF start_pos = CURRENT_OFFSET;
- SET (OVERSTRIKE, CURRENT_BUFFER);
- IF (INDEX (" ", CURRENT_CHARACTER) <> 0) THE
- N
- chcnt := chcnt + 1;
- MOVE_HORIZONTAL (1);
- EXITIF (1);
- ENDIF;
- MOVE_HORIZONTAL (-1);
- chcnt := chcnt - 1;
- ENDLOOP;
- ENDIF;
- ENDIF;
- ENDIF;
- ENDIF;
- ENDIF;
-
- vi$update (CURRENT_WINDOW);
- ENDLOOP;
-
- IF max_mark <> MARK (NONE) THEN
- current_mark := MARK (NONE);
- IF (NOT seen_eol) AND (replace <> 0) THEN
- SET (OVERSTRIKE, CURRENT_BUFFER);
- COPY_TEXT (SUBSTR (replace, CURRENT_OFFSET + 1,
- max_col - CURRENT_OFFSET));
- POSITION (current_mark);
- ELSE
- POSITION (max_mark);
- IF (MARK(NONE) <> BEGINNING_OF (CURRENT_BUFFER)) THEN
- MOVE_HORIZONTAL (-1);
- ENDIF;
- ERASE (CREATE_RANGE (MARK (NONE), current_mark, NONE));
- ENDIF;
- ENDIF;
-
- IF (CURRENT_OFFSET > 0) AND
- (MARK(NONE) <> BEGINNING_OF (CURRENT_BUFFER)) THEN
- MOVE_HORIZONTAL (-1);
- ENDIF;
-
- ins_text := CREATE_RANGE (start_ins, MARK (NONE), NONE);
-
- ! Save last inserted text to buffer.
-
- ERASE (vi$last_insert);
- pos := MARK (NONE);
-
- POSITION (vi$last_insert);
- COPY_TEXT (ins_text);
- SPLIT_LINE;
- POSITION (BEGINNING_OF (vi$last_insert));
-
- POSITION (pos);
-
- SET (INSERT, CURRENT_BUFFER);
-
- IF (vi$show_mode) THEN
- MESSAGE ("");
- ENDIF;
- RETURN (chcnt);
- ENDPROCEDURE;
-
- !
- ! Check to see if 'cabbr' is a known abbreviation, and substitute the
- ! proper text if it is.
- !
- PROCEDURE vi$abbr (abbrs, rchar, cabbr, abbrlen)
- LOCAL
- strg;
-
- strg := "";
-
- IF (abbrlen > 0) THEN
- EDIT (cabbr, UPPER);
- IF (INDEX (abbrs, "VI$ABBR_"+cabbr+" ") <> 0) THEN
- vi$global_var := 0;
- EXECUTE (COMPILE ("vi$global_var := vi$abbr_"+cabbr+";"));
- IF (vi$global_var <> 0) THEN
- ERASE_CHARACTER (-abbrlen);
- strg := vi$global_var;
- COPY_TEXT (strg);
- ENDIF;
- ENDIF;
- cabbr := "";
- abbrlen := 0;
- ENDIF;
- IF (rchar <> 0) THEN
- COPY_TEXT (rchar);
- ENDIF;
- RETURN (LENGTH (strg) + (rchar <> 0));
- ENDPROCEDURE;
-
- !
- ! Return a string describing the KEY_NAME passed. For control characters,
- ! it is "^?" where the '?' is A-Z. Otherwise, the value returned by the
- ! ASCII() builtin is used.
- !
- PROCEDURE vi$ascii_name (key_n)
- LOCAL
- key;
-
- key := (key_n - CTRL_A_KEY) / (CTRL_B_KEY - CTRL_A_KEY);
- IF (key > 31) OR (key < 0) THEN
- key := ASCII (key_n);
- ELSE
- key := "^" + ASCII(key+65);
- ENDIF;
-
- RETURN (key);
- ENDPROCEDURE;
-
- !
- ! Perform some mapping of keys to different ASCII values.
- !
- PROCEDURE vi$ascii (key_n)
- IF key_n = F12 THEN
- RETURN (ASCII (8));
- ENDIF;
- IF key_n = F11 THEN
- RETURN (ASCII (27));
- ENDIF;
- IF key_n = PF1 THEN
- RETURN (ASCII (27));
- ENDIF;
- IF key_n = RET_KEY THEN
- RETURN (ASCII (13));
- ENDIF;
- IF key_n = TAB_KEY THEN
- RETURN (ASCII (9));
- ENDIF;
- RETURN (ASCII (key_n));
- ENDPROCEDURE;
-
- !
- ! Move up by screens
- !
- PROCEDURE vi$prev_screen
- ON_ERROR
- ENDON_ERROR;
-
- MOVE_VERTICAL (-vi$cur_active_count *
- GET_INFO (CURRENT_WINDOW, "VISIBLE_LENGTH"));
-
- vi$position (vi$first_no_space, 0);
- ENDPROCEDURE;
-
- !
- ! Move down by screens
- !
- PROCEDURE vi$next_screen
- ON_ERROR
- ENDON_ERROR;
-
- MOVE_VERTICAL (vi$cur_active_count *
- (GET_INFO (CURRENT_WINDOW, "VISIBLE_LENGTH") + 2));
-
- vi$position (vi$first_no_space, 0);
- ENDPROCEDURE;
-
- !
- ! Scroll forward one screen
- !
- PROCEDURE vi$screen_forward
-
- vi$scroll_screen (1);
-
- ENDPROCEDURE;
-
- !
- ! Scroll back one screen
- !
- PROCEDURE vi$screen_backward
-
- vi$scroll_screen (-1);
-
- ENDPROCEDURE;
-
- !
- ! Scroll the screen up or down depending on the sign of "how_many_screens"
- ! The magnitude actually has effect as well, but is never greater than 1
- ! in this use.
- !
- PROCEDURE vi$scroll_screen (how_many_screens)
-
- LOCAL
- scroll_window, ! Window to be scrolled
- this_window, ! Current window
- this_column, ! Current column in scroll_window
- this_row, ! Current row in scroll_window
- old_scroll_top, ! Original value of scroll_top
- old_scroll_bottom, ! Original value of scroll_bottom
- old_scroll_amount; ! Original value of scroll_amount
-
- ! Trap and ignore messages about move beyond buffer boundaries -
- ! just move to top or bottom line of buffer
-
- ON_ERROR
- ENDON_ERROR;
-
- this_window := CURRENT_WINDOW;
-
- scroll_window := this_window;
-
- IF vi$active_count <> 0 THEN
- vi$how_much_scroll := vi$cur_active_count;
- ENDIF;
-
- this_row := GET_INFO (scroll_window, "CURRENT_ROW");
-
- IF this_row = 0 THEN
- this_row := GET_INFO (scroll_window, "VISIBLE_TOP");
- ENDIF;
-
- this_column := GET_INFO (scroll_window, "CURRENT_COLUMN");
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
-
- old_scroll_top := GET_INFO (scroll_window, "SCROLL_TOP");
- old_scroll_bottom := GET_INFO (scroll_window, "SCROLL_BOTTOM");
- old_scroll_amount := GET_INFO (scroll_window, "SCROLL_AMOUNT");
-
- SET (SCROLLING, scroll_window, ON,
- this_row - GET_INFO (scroll_window, "VISIBLE_TOP"),
- GET_INFO (scroll_window, "VISIBLE_BOTTOM") - this_row, 0);
-
- MOVE_VERTICAL (how_many_screens * vi$how_much_scroll);
- vi$update (scroll_window);
-
- IF this_window <> CURRENT_WINDOW THEN
- POSITION (this_window);
- ENDIF;
-
- SET (SCROLLING, scroll_window, ON, old_scroll_top, old_scroll_bottom,
- old_scroll_amount);
- ENDPROCEDURE;
-
- !
- ! Move forward logical words
- !
- PROCEDURE vi$_word_forward
- vi$position (vi$word_move (1), 0);
- ENDPROCEDURE;
-
- !
- ! Move backward logical words
- !
- PROCEDURE vi$_word_back
- vi$position (vi$word_move(-1), 0);
- ENDPROCEDURE;
-
- !
- ! Move by logical word taking into account the repeat count
- !
- PROCEDURE vi$word_move(dir)
- LOCAL
- old_pos,
- pos;
-
- old_pos := MARK (NONE);
-
- IF vi$active_count <= 0 THEN
- vi$active_count := 1;
- ENDIF;
-
- LOOP
- pos := vi$move_logical_word (dir);
- EXITIF pos = 0;
- POSITION (pos);
- vi$active_count := vi$active_count - 1;
- EXITIF vi$active_count = 0;
- ENDLOOP;
-
- vi$yank_mode := VI$IN_LINE_MODE;
- RETURN (vi$retpos (old_pos));
- ENDPROCEDURE;
-
- !
- ! Move to end of logical word
- !
- PROCEDURE vi$_word_end
- vi$position (vi$word_end, 0);
- ENDPROCEDURE;
-
- !
- ! Move to end of physical word
- !
- PROCEDURE vi$_full_word_end
- vi$position (vi$full_word_end, 0);
- ENDPROCEDURE;
-
- !
- ! Move to the end of the current word.
- !
- PROCEDURE vi$word_end
- LOCAL
- old_pos,
- pos;
-
- old_pos := MARK (NONE);
-
- IF vi$active_count <= 0 THEN
- vi$active_count := 1;
- ENDIF;
-
- LOOP
- pos := vi$move_logical_end;
- EXITIF pos = 0;
- POSITION (pos);
- vi$active_count := vi$active_count - 1;
- EXITIF vi$active_count = 0;
- ENDLOOP;
-
- vi$yank_mode := VI$IN_LINE_MODE;
- RETURN (vi$retpos (old_pos));
- ENDPROCEDURE;
-
- !
- ! Move to the end of a blank (eol is also considered blank) terminated word.
- !
- PROCEDURE vi$full_word_end
-
- LOCAL
- old_pos,
- pos;
-
- old_pos := MARK (NONE);
-
- IF vi$active_count <= 0 THEN
- vi$active_count := 1;
- ENDIF;
-
- LOOP
- pos := vi$move_full_end;
- EXITIF pos = 0;
- POSITION (pos);
- vi$active_count := vi$active_count - 1;
- EXITIF vi$active_count = 0;
- ENDLOOP;
-
- vi$yank_mode := VI$IN_LINE_MODE;
- RETURN (vi$retpos (old_pos));
- ENDPROCEDURE;
-
- !
- ! Move forward by ONE white-space delimited word
- !
- PROCEDURE vi$_full_word_forward
- vi$position (vi$full_word_move (1), 0);
- ENDPROCEDURE;
-
- !
- !
- ! Move backward by ONE white-space delimited word
- !
- PROCEDURE vi$_full_word_back
- vi$position (vi$full_word_move (-1), 0);
- ENDPROCEDURE;
-
- !
- ! Move by physical word taking the repeat count into account
- !
- PROCEDURE vi$full_word_move (dir)
-
- LOCAL
- old_pos,
- pos;
-
- old_pos := MARK (NONE);
-
- IF vi$active_count <= 0 THEN
- vi$active_count := 1;
- ENDIF;
-
- LOOP
- pos := vi$move_full_word (dir);
- EXITIF pos = 0;
- POSITION (pos);
- vi$active_count := vi$active_count - 1;
- EXITIF vi$active_count = 0;
- ENDLOOP;
-
- vi$yank_mode := VI$IN_LINE_MODE;
- RETURN (vi$retpos (old_pos));
- ENDPROCEDURE;
-
- !
- ! Move the cursor by BLANK separated words. DIRECTION is either
- ! +1, or -1 to indicate the direction (forward, or backword respectfully)
- ! to move
- !
- PROCEDURE vi$move_full_word (direction)
-
- LOCAL
- pos;
-
- pos := MARK (NONE);
-
- $$EOD$$
-