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 7/13
- Message-ID: <4856@ncoast.UUCP>
- Date: 13 Oct 87 02:52:41 GMT
- Sender: allbery@ncoast.UUCP
- Organization: Oklahoma State Univ., Stillwater
- Lines: 1502
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/8710/vms-vi/7
-
- $ WRITE SYS$OUTPUT "Creating ""VI.6"""
- $ CREATE VI.6
- $ DECK/DOLLARS=$$EOD$$
- ENDIF;
- ELSE
- regular := 1;
- ENDIF;
-
- IF (regular) THEN
- new_pat := new_pat + cur_pat;
- ELSE
- IF new_pat = "" THEN
- new_pat := cur_pat;
- ELSE
- new_pat := new_pat + "&" + cur_pat;
- ENDIF;
- ENDIF;
-
- pos := pos + 1;
-
- ENDLOOP;
-
- RETURN (new_pat);
- ENDPROCEDURE;
- !
- !
- ! TPU pattern generator. Generates a pattern string from the passed
- ! RE string. The function is used when :set magic is in effect.
- !
- PROCEDURE vi$re_pattern_gen (pat)
-
- LOCAL
- first, ! First pattern to be done
- part_pat,
- chno,
- startchar,
- haveany,
- regular,
- tstr,
- endchar,
- pat_str,
- str_pat,
- cur_pat, ! The current pattern to be extracted
- cur_char, ! The current character in the regular
- ! expression being examined
- new_pat, ! The output pattern
- in_ws,
- pos; ! The position within the regular
- ! expression string that we are examining
- ! currently
-
- vi$in_ws := 0;
- IF ((INDEX (pat, "$") <> 0) OR (INDEX (pat, "[") <> 0) OR
- (INDEX (pat, "^") <> 0) OR (INDEX (pat, ".") <> 0) OR
- (INDEX (pat, "*") <> 0) OR (INDEX (pat, "\") <> 0) OR
- (INDEX (pat, '"') <> 0)) THEN
- new_pat := "";
- ELSE
- new_pat := '"'+pat+'"';
- RETURN (new_pat);
- ENDIF;
-
- in_ws := 0;
- pos := 1;
-
- IF SUBSTR (pat, pos, 1) = "^" THEN
- new_pat := "line_begin";
- pos := pos + 1;
- ENDIF;
-
- LOOP
- EXITIF (pos > LENGTH (pat));
-
- regular := 0;
- cur_pat := "";
- cur_char := substr (pat, pos, 1);
- pat_str := "";
-
- IF (cur_char = "$") THEN
- IF (pos+1 >= LENGTH (pat)) THEN
- cur_pat := "line_end";
- ELSE
- vi$message ("$ found before end of string");
- RETURN (0);
- ENDIF;
- ELSE
- IF cur_char = "[" THEN
- pos := pos + 1;
-
- IF SUBSTR (pat, pos, 1) = "^" THEN
- pos := pos + 1;
- part_pat := "notany('";
- ELSE
- part_pat := "any('";
- ENDIF;
-
- LOOP
- EXITIF pos > LENGTH (pat);
- EXITIF SUBSTR (pat, pos, 1) = "]";
-
- IF SUBSTR (pat, pos, 1) = "\" THEN
- pos := pos + 1;
- IF pos > LENGTH (pat) THEN
- vi$message ("Missing character after \");
- RETURN ("");
- ENDIF;
- ENDIF;
-
- startchar := SUBSTR (pat, pos, 1);
- pat_str := pat_str + startchar;
- IF startchar = "'" THEN
- pat_str := pat_str + "'";
- ENDIF;
-
- IF (SUBSTR (pat, pos+1, 1) = '-') THEN
- pos := pos + 2;
- IF (pos >= LENGTH (pat)) THEN
- vi$message ("Missing character after '-'");
- RETURN ("");
- ENDIF;
-
- endchar := SUBSTR (pat, pos, 1);
-
- chno := 1;
- LOOP
- EXITIF (ASCII(chno) = startchar);
- chno := chno + 1;
- ENDLOOP;
-
- LOOP
- chno := chno + 1;
- IF (chno > 255) THEN
- vi$message (
- "Invalid character sequence for '-'");
- RETURN ("");
- ENDIF;
-
- EXITIF (ASCII (chno-1) = endchar);
- pat_str := pat_str + ASCII (chno);
- IF ASCII (chno) = "'" THEN
- pat_str := pat_str + "'";
- ENDIF;
- ENDLOOP;
- ENDIF;
- pos := pos + 1;
- ENDLOOP;
-
- IF pat_str = "" THEN
- vi$message ("No text found between []");
- RETURN ("");
- ENDIF;
-
- IF (SUBSTR (pat, pos+1, 1) = "*") THEN
- IF (part_pat = "notany('") THEN
- cur_pat := cur_pat + "(scan('"+pat_str+"')|"""")";
- ELSE
- cur_pat := cur_pat + "(span('"+pat_str+"')|"""")";
- ENDIF;
- pos := pos + 1;
- ELSE
- cur_pat := part_pat + pat_str + "')";
- ENDIF;
- ELSE
-
- tstr := '"';
- haveany := 0;
- regular := 1;
-
- LOOP
- cur_char := SUBSTR (pat, pos, 1);
- EXITIF (cur_char = "^") OR (cur_char = "[") OR
- (cur_char = "$");
- EXITIF (pos > LENGTH (pat));
-
- IF cur_char = "\" THEN
- pos := pos + 1;
- startchar := SUBSTR (pat, pos, 1);
- IF (startchar = "<") THEN
- in_ws := 1;
- vi$in_ws := 1;
- tstr := tstr + '"&(line_begin | any (vi$_ws))&"';
- ELSE
- IF (startchar = ">") THEN
- in_ws := 0;
- tstr := tstr + '"&(line_end | any (vi$_ws))&"';
- ELSE
- tstr := tstr + startchar;
- ENDIF;
- ENDIF;
- ELSE
- IF (cur_char = ".") THEN
- cur_char := "longer_than_1";
- ENDIF;
-
- IF (SUBSTR (pat, pos+1, 1) = '*') THEN
- pos := pos + 1;
-
- IF (LENGTH (cur_char) > 1) THEN
- cur_pat := "''&(span(vi$pch)|'')";
- ELSE
- cur_pat := "(span('"+cur_char+"')|"""")";
- ENDIF;
- tstr := tstr+'"'+"&"+cur_pat+"&"+'"';
- haveany := 0;
- ELSE
- IF (LENGTH (cur_char) > 1) THEN
- IF (haveany) THEN
- tstr := tstr +'"'+"&"+"arb(1)"+"&"+'"';
- haveany := 0;
- ELSE
- IF (LENGTH (tstr)>0) and (tstr <> '"') THEN
- tstr := tstr +'"'+"&"+"arb(1)"+"&"+'"';
- ELSE
- tstr := "arb(1)"+"&"+'"';
- ENDIF
- ENDIF;
- ELSE
- IF (cur_char = """") THEN
- tstr := tstr + '""';
- haveany := haveany + 2;
- ELSE
- tstr := tstr + cur_char;
- haveany := haveany + 1;
- ENDIF;
- ENDIF;
- ENDIF;
- ENDIF;
- pos := pos + 1;
- ENDLOOP;
- cur_pat := tstr + '"';
- pos := pos - 1;
- ENDIF;
- ENDIF;
-
- IF (regular) THEN
- IF new_pat = "" THEN
- new_pat := cur_pat;
- ELSE
- IF (LENGTH (tstr) > 1) THEN
- new_pat := new_pat + "&" + cur_pat;
- ENDIF;
- ENDIF;
- ELSE
- IF new_pat = "" THEN
- new_pat := cur_pat;
- ELSE
- new_pat := new_pat + "&" + cur_pat;
- ENDIF;
- ENDIF;
- pos := pos + 1;
-
- ENDLOOP;
-
- IF (in_ws) THEN
- MESSAGE ("Missing \> in pattern!");
- RETURN (0);
- ENDIF;
-
- RETURN (new_pat);
- ENDPROCEDURE;
-
- !
- ! Match brackets when '%' is typed.
- !
- PROCEDURE vi$_match_brackets
- vi$position (vi$match_brackets, 1);
- ENDPROCEDURE;
-
- !
- ! Perform the actual match bracket operation.
- !
- PROCEDURE vi$match_brackets
- LOCAL
- newpos,
- ind_pos,
- found,
- cur_ch,
- cur_dir,
- pos;
-
- ON_ERROR
- IF ERROR = TPU$_CONTROLC THEN
- vi$beep;
- vi$pasthru_on;
- RETURN (0);
- ENDIF;
- ENDON_ERROR;
-
- found := 1;
- vi$message ("");
- pos := MARK (NONE);
- cur_ch := CURRENT_CHARACTER;
- ind_pos := INDEX (vi$bracket_chars, cur_ch);
-
- IF (ind_pos = 0) THEN
- newpos := SEARCH (ANCHOR & SCAN (")") & ARB (1), FORWARD, EXACT);
- found := 0;
- IF newpos <> 0 THEN
- found := 1;
- IF vi$in_show_match = 0 THEN
- vi$old_place := pos;
- ENDIF;
- POSITION (END_OF (newpos));
- RETURN (vi$retpos (pos));
- ELSE
- POSITION (pos);
- RETURN (0);
- ENDIF;
- ENDIF;
-
- IF ((ind_pos/2)*2 <> ind_pos) THEN
- cur_dir := FORWARD;
- ELSE
- cur_dir := REVERSE;
- ENDIF;
-
- SET (TIMER, ON, "Searching...");
- newpos := vi$do_match (CURRENT_CHARACTER, cur_dir, 0);
- SET (TIMER, OFF);
-
- IF (GET_INFO (newpos, "TYPE") = MARKER) THEN
- RETURN (vi$retpos (pos));
- ELSE
- IF (newpos = 0) AND NOT (vi$in_show_match) THEN
- vi$message ("No matching bracket");
- ENDIF;
- POSITION (pos);
- ENDIF;
- RETURN (0);
- ENDPROCEDURE;
- !
- !
- ! This procedure knows how to traverse nested brackets to find the matching
- ! bracket. It takes the character that the cursor is positioned on, and
- ! finds the matching one. It recognizes '{}', '[]', '()' pairs.
- !
- PROCEDURE vi$do_match (bracket, cur_dir, level)
-
- LOCAL
- dgrp,
- dest_char,
- sel_reg,
- ind_pos,
- next_pos,
- possibles,
- cur_ch;
-
- ON_ERROR
- RETURN (0);
- ENDON_ERROR;
-
- IF level > 30 THEN
- vi$message ("Too many nested levels");
- RETURN (-1);
- ENDIF;
-
- ! Identify the desired search direction based on the character.
-
- ind_pos := INDEX (vi$bracket_chars, bracket);
- dest_char := SUBSTR ("}{)(][", ind_pos, 1);
-
- IF cur_dir = FORWARD THEN
- MOVE_HORIZONTAL (1);
- ENDIF;
-
- dgrp := bracket + dest_char;
- LOOP
- sel_reg := SEARCH (ANY (dgrp), cur_dir, EXACT);
-
- IF sel_reg = 0 THEN
- RETURN (0);
- ENDIF;
-
- POSITION (BEGINNING_OF (sel_reg));
-
- IF (CURRENT_CHARACTER = dest_char) THEN
- RETURN (MARK (NONE));
- ELSE
- IF (((INDEX ("([{", CURRENT_CHARACTER) <> 0) AND
- (cur_dir = FORWARD)) OR
- ((INDEX (")}]", CURRENT_CHARACTER) <> 0) AND
- (cur_dir = REVERSE))) THEN
-
- IF (INDEX (vi$bracket_chars, CURRENT_CHARACTER)-1)/2 <=
- (INDEX (vi$bracket_chars, dest_char)-1)/2 THEN
-
- next_pos := vi$do_match (CURRENT_CHARACTER,
- cur_dir, level+1)
- ;
-
- IF (next_pos <> 0) AND (next_pos <> -1) THEN
- POSITION (next_pos);
- ELSE
- RETURN (next_pos);
- ENDIF;
- ENDIF;
- ELSE
- IF (INDEX (vi$bracket_chars, CURRENT_CHARACTER) = 0) THEN
- vi$message ("Unknown bracket character: '"+
- CURRENT_CHARACTER+"'");
- RETURN (-1);
- ENDIF;
- ENDIF;
-
- IF cur_dir = FORWARD THEN
- MOVE_HORIZONTAL (1);
- ENDIF;
- ENDIF;
- ENDLOOP;
- ENDPROCEDURE;
-
- !
- ! Move to the top line of the window when 'H' is pressed.
- !
- PROCEDURE home
- POSITION (vi$to_home);
- ENDPROCEDURE;
-
- !
- ! Perform the actual movement for the 'H' command and return the marker.
- !
- PROCEDURE vi$to_home
-
- LOCAL
- pos;
-
- ON_ERROR
- ! Ignore attempt to move beyond end of buffer errors.
- ENDON_ERROR;
-
- pos := MARK (NONE);
- MOVE_VERTICAL ( GET_INFO (CURRENT_WINDOW, "VISIBLE_TOP") -
- GET_INFO (CURRENT_WINDOW, "CURRENT_ROW"));
-
- vi$yank_mode := VI$LINE_MODE;
- RETURN (vi$retpos(pos));
- ENDPROCEDURE
-
- !
- ! Position the cursor into the middle of the current window when 'M' is
- ! pressed.
- !
- PROCEDURE vi$middle
- POSITION (vi$to_middle);
- ENDPROCEDURE;
-
- !
- ! Perform the actual movement of the 'M' command.
- !
- PROCEDURE vi$to_middle
-
- LOCAL
- len,
- cur,
- top,
- pos;
-
- ON_ERROR
- ! Ignore attempt to move beyond end of buffer errors.
- ENDON_ERROR;
-
- pos := MARK (NONE);
-
- len := GET_INFO (CURRENT_WINDOW, "VISIBLE_LENGTH");
- cur := GET_INFO (CURRENT_WINDOW, "CURRENT_ROW");
- top := GET_INFO (CURRENT_WINDOW, "VISIBLE_TOP");
-
- MOVE_VERTICAL (((len-top+1)/2) - (cur - top + 1));
-
- vi$yank_mode := VI$LINE_MODE;
- RETURN (vi$retpos(pos));
- ENDPROCEDURE;
-
- !
- ! Move the the last line of the current window when 'L' is pressed.
- !
- PROCEDURE vi$last
- POSITION (vi$to_last);
- ENDPROCEDURE;
-
- !
- ! Perform the actual movement associated with the 'L' command.
- !
- PROCEDURE vi$to_last
-
- LOCAL
- pos;
-
- ON_ERROR
- ! Ignore attempt to move beyond end of buffer errors.
- ENDON_ERROR;
-
- pos := MARK (NONE);
- MOVE_VERTICAL ( GET_INFO (CURRENT_WINDOW, "VISIBLE_BOTTOM") -
- GET_INFO (CURRENT_WINDOW, "CURRENT_ROW"));
-
- vi$yank_mode := VI$LINE_MODE;
- RETURN (vi$retpos (pos));
- ENDPROCEDURE
-
- !
- ! Move to the end of the current line when '$' is pressed.
- !
- PROCEDURE vi$_eol
- POSITION (vi$eol);
- ENDPROCEDURE;
-
- !
- ! Perform the actual movement associated with the '$' command.
- !
- PROCEDURE vi$eol
- LOCAL
- pos;
-
- ON_ERROR
- RETURN (pos);
- ENDON_ERROR;
-
- pos := MARK (NONE);
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
- MOVE_HORIZONTAL (LENGTH (vi$current_line));
- vi$check_rmarg;
-
- vi$yank_mode := VI$IN_LINE_MODE;
- RETURN (vi$retpos (pos));
- ENDPROCEDURE;
-
- !
- ! Move the first non-blank character of the line when '^' is typed.
- !
- PROCEDURE vi$_bol
- vi$position (vi$first_no_space, 0);
- ENDPROCEDURE;
-
- !
- ! Move the beginning of the line when '0' is typed.
- !
- PROCEDURE vi$fol
- LOCAL
- pos;
-
- pos := MARK (NONE);
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
- vi$yank_mode := VI$IN_LINE_MODE;
- vi$new_offset := 1;
- RETURN (vi$retpos (pos));
- ENDPROCEDURE;
-
- !
- ! Move the the location searched for.
- !
- PROCEDURE vi$_search (direction)
- LOCAL
- pos;
-
- pos := vi$search(direction);
-
- vi$position (pos, 1);
- IF (pos <> 0) THEN
- vi$pos_in_middle (MARK (NONE));
- ENDIF;
- ENDPROCEDURE;
-
- !
- ! Move to the next location of the string previously searched for.
- !
- PROCEDURE vi$_search_next (direction)
- LOCAL
- pos;
-
- pos := vi$search_next(direction);
-
- vi$position (pos, 1);
- IF (pos <> 0) THEN
- vi$pos_in_middle (MARK (NONE));
- ENDIF;
- ENDPROCEDURE;
-
- !
- ! Repeat the last 't' or 'f' command backwards.
- !
- PROCEDURE vi$_repeat_torf_back
- vi$position (vi$repeat_torf_back, 0);
- ENDPROCEDURE
-
- !
- ! Repeat the last 't' or 'f' command.
- !
- PROCEDURE vi$_repeat_torf
- vi$position (vi$repeat_torf, 0);
- ENDPROCEDURE
-
- !
- ! Return the location found by repeating the last 't', 'f', 'T' or 'F'
- ! command backwards.
- !
- PROCEDURE vi$repeat_torf_back
- LOCAL
- old_func,
- back_func;
-
- IF vi$last_s_func = 0 THEN
- RETURN (0);
- ENDIF;
-
- old_func := vi$last_s_func;
- IF (vi$last_s_func = "vi$back_find_char") THEN
- back_func := "vi$find_char";
- ENDIF;
- IF (vi$last_s_func = "vi$find_char") THEN
- back_func := "vi$back_find_char";
- ENDIF;
- IF (vi$last_s_func = "vi$back_to_char") THEN
- back_func := "vi$to_char";
- ENDIF;
- IF (vi$last_s_func = "vi$to_char") THEN
- back_func := "vi$back_to_char";
- ENDIF;
-
- vi$global_var := 0;
- EXECUTE (COMPILE (
- "vi$global_var := " + back_func + "('"+vi$last_s_char + "')"));
- vi$last_s_func := old_func;
- RETURN (vi$global_var);
- ENDPROCEDURE
-
- !
- ! Return the location found by repeating the last 't', 'f', 'T' or 'F'
- ! command.
- !
- PROCEDURE vi$repeat_torf
- IF vi$last_s_func = 0 THEN
- RETURN (0);
- ENDIF;
-
- vi$global_var := 0;
- EXECUTE (COMPILE (
- "vi$global_var := " + vi$last_s_func + "('"+vi$last_s_char + "')"));
- RETURN (vi$global_var);
- ENDPROCEDURE
-
- !
- ! Return the value of a positive integer that is represented as a string.
- ! If the string is not a valid integer, then -1 is retured.
- !
- PROCEDURE vi$number_from_string (str_num)
- ON_ERROR
- RETURN (-1);
- ENDON_ERROR;
-
- RETURN (INT (str_num));
- ENDPROCEDURE;
-
- !
- ! Move to the line indicated by 'line_no', and return the marker that
- ! indicates the beginning of that line.
- !
- PROCEDURE vi$mark_line (line_no)
-
- LOCAL
- pos;
-
- ON_ERROR
- POSITION (pos);
- RETURN (0);
- ENDON_ERROR;
-
- pos := MARK (NONE);
- POSITION (BEGINNING_OF (CURRENT_BUFFER));
- MOVE_VERTICAL (line_no - 1);
- RETURN (vi$retpos (pos));
- ENDPROCEDURE;
-
- !
- ! Perform an EX mode command after a ':' is typed.
- !
- PROCEDURE vi$ex_mode
- LOCAL
- cmd_str;
-
- IF (vi$read_a_line (":", cmd_str) <> 0) and (cmd_str <> "") THEN
- IF (vi$do_cmd_line (cmd_str) = 0) THEN
- vi$message ("");
- ENDIF;
- ENDIF;
- ENDPROCEDURE;
-
- !
- !
- !
- PROCEDURE vi$read_a_line (prompt, cmd_str)
- LOCAL
- cmd_idx,
- addch,
- ch,
- did_ctl_v,
- win,
- pos;
-
- win := CURRENT_WINDOW;
- pos := MARK (NONE);
-
- POSITION (END_OF (command_buffer));
- MAP (command_window, command_buffer);
- COPY_TEXT (prompt);
- SET (OVERSTRIKE, CURRENT_BUFFER);
-
- cmd_str := "";
- cmd_idx := 0;
- LOOP
- vi$update (CURRENT_WINDOW);
- ch := vi$read_a_key;
-
- did_ctl_v := 0;
- IF ch = CTRL_V_KEY THEN
- COPY_TEXT ("^");
- did_ctl_v := 1;
- MOVE_HORIZONTAL (-1);
- vi$update (CURRENT_WINDOW);
- ch := vi$read_a_key;
- ERASE_CHARACTER (1);
- ENDIF;
-
- EXITIF ((ch = RET_KEY) OR (ch = F11)) AND (did_ctl_v = 0);
-
- IF (ch = RET_KEY) THEN ch := CTRL_M_KEY; ENDIF;
- IF (ch = F12) THEN ch := CTRL_H_KEY; ENDIF;
- IF (ch = F11) THEN ch := KEY_NAME (ASCII (27)); ENDIF;
-
- IF ((ch = DEL_KEY) OR (ch = CTRL_H_KEY)) AND (did_ctl_v = 0) THEN
- IF cmd_idx = 0 THEN
- UNMAP (command_window);
- UNMAP (message_window);
- MAP (message_window, message_buffer);
- POSITION (win);
- POSITION (pos);
- RETURN (0);
- ENDIF;
- ch := SUBSTR (cmd_str, cmd_idx, 1);
- cmd_idx := cmd_idx - 1;
- IF (INDEX (vi$_ctl_chars, ch) <> 0) THEN
- MOVE_HORIZONTAL (-2);
- ELSE
- MOVE_HORIZONTAL (-1);
- ENDIF;
- cmd_str := SUBSTR (cmd_str, 1, cmd_idx);
- ELSE
- IF (ch <= KEY_NAME (ASCII (31))) AND (ch >= CTRL_A_KEY) THEN
- IF ch = TAB_KEY THEN
- addch := 9;
- COPY_TEXT (ASCII(addch));
- ELSE
- addch := ((ch - CTRL_A_KEY) / 256) + 1;
- COPY_TEXT ("^");
- COPY_TEXT (ASCII (addch + 64));
- ENDIF;
- cmd_str := cmd_str + ASCII (addch);
- cmd_idx := cmd_idx + 1;
- IF ch = 27 THEN ch := F11; ENDIF;
- ELSE
- IF (ch = UP) THEN
- vi$next_in_cmd (cmd_str, cmd_idx, prompt, -1);
- ELSE
- IF (ch = DOWN) THEN
- vi$next_in_cmd (cmd_str, cmd_idx, prompt, 1);
- ELSE
- COPY_TEXT (ASCII(ch));
- cmd_str := cmd_str + ASCII (ch);
- cmd_idx := cmd_idx + 1;
- ENDIF;
- ENDIF;
- ENDIF;
- ENDIF;
- ENDLOOP;
-
- ERASE_CHARACTER (LENGTH (CURRENT_LINE) - CURRENT_OFFSET);
-
- POSITION (END_OF (command_buffer));
- LOOP
- MOVE_VERTICAL (-1);
- EXITIF (CURRENT_LINE <> prompt);
- ERASE_LINE;
- ENDLOOP;
-
- IF (CURRENT_LINE <> prompt + cmd_str) THEN
- MOVE_VERTICAL (1);
- COPY_TEXT (prompt + cmd_str);
- ENDIF;
-
- UNMAP (command_window);
- UNMAP (message_window);
- MAP (message_window, message_buffer);
-
- POSITION (win);
- POSITION (pos);
-
- RETURN (1);
- ENDPROCEDURE;
-
- !
- ! This procedure looks from the next occurence of 'prompt' at the
- ! beginning of the line, in the direction dir (1 or -1). If prompt
- ! is found, then cmd_str is set to the contents of that line, minus
- ! the text of the prompt, and cmd_idx is set to the length of cmd_str.
- ! The cursor is left positioned at the end of the line found, or if
- ! none is found, it is not moved.
- !
- PROCEDURE vi$next_in_cmd (cmd_str, cmd_idx, prompt, dir)
- LOCAL
- pos,
- len;
-
- ON_ERROR
- POSITION (pos);
- RETURN;
- ENDON_ERROR;
-
- pos := MARK (NONE);
- len := LENGTH (prompt);
-
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
- LOOP
- EXITIF (MARK (NONE) = BEGINNING_OF (CURRENT_BUFFER)) AND (dir = -1);
- EXITIF (MARK (NONE) = END_OF (CURRENT_BUFFER)) AND (dir = 1);
- MOVE_VERTICAL (DIR);
- IF SUBSTR (CURRENT_LINE, 1, len) = prompt THEN
- cmd_str := SUBSTR (CURRENT_LINE, len+1,
- LENGTH (CURRENT_LINE) - len + 1);
- cmd_idx := LENGTH (cmd_str);
- MOVE_HORIZONTAL (LENGTH (CURRENT_LINE));
- RETURN;
- ENDIF;
- ENDLOOP;
- POSITION (pos);
- ENDPROCEDURE;
-
- !
- ! Perform a whole series of command separated by '|'s.
- !
- PROCEDURE vi$do_cmd_line (cmd)
- LOCAL
- ch,
- retval,
- idx,
- strg;
-
- idx := 1;
- strg := "";
-
- LOOP
- EXITIF (idx > LENGTH (cmd));
- ch := SUBSTR (cmd, idx, 1);
- IF (ch = "|") THEN
- retval := vi$do_command (strg);
- IF (retval > 1) THEN
- RETURN (retval);
- ELSE
- IF (retval = 0) THEN
- MESSAGE ("");
- ENDIF;
- ENDIF;
- strg := 0;
- ELSE
- IF (ch = "\") THEN
- idx := idx + 1;
- IF (SUBSTR (cmd, idx, 1) = "|") THEN
- strg := strg + "|";
- ELSE
- strg := strg + "\" + SUBSTR (cmd, idx, 1);
- ENDIF;
- ELSE
- strg := strg + ch;
- ENDIF;
- ENDIF;
- idx := idx + 1;
- ENDLOOP;
-
- IF (strg <> 0) THEN
- IF (vi$do_command (strg) <> 0) THEN
- RETURN (1);
- ELSE
- MESSAGE ("");
- ENDIF;
- ENDIF;
- RETURN (0);
- ENDPROCEDURE;
-
- !
- ! Perform an EX (not all are implemented) command as given in "cmd".
- !
- PROCEDURE vi$do_command (cmd)
- LOCAL
- rng,
- outf,
- mode,
- token_1,
- token_2,
- token_3,
- res_spec,
- start_mark,
- end_mark,
- start_line,
- end_line,
- work_range,
- whole_range,
- buf,
- pos,
- spos,
- rest,
- separ,
- no_spec,
- ch,
- i,
- j,
- olen,
- bang,
- num,
- pos;
-
- olen := GET_INFO (CURRENT_BUFFER, "RECORD_COUNT");
-
- ! Start at beginning of string and look for a range of lines.
-
- i := 1;
-
- pos := MARK (NONE);
- num := vi$get_line_spec (i, cmd);
-
- no_spec := 0;
- IF (num < 0) THEN
- IF (vi$parse_next_ch (i, cmd, "%")) THEN
- start_line := 1;
- end_line := GET_INFO (CURRENT_BUFFER, "RECORD_COUNT");
- ELSE
- no_spec := 1;
- start_line := vi$cur_line_no;
- end_line := start_line;
- ENDIF;
- ELSE
- start_line := num;
- IF (vi$parse_next_ch (i, cmd, ",")) THEN
- num := vi$get_line_spec (i, cmd);
- IF (num < 0) THEN
- vi$message ("Invalid line range specification!");
- RETURN (1);
- ENDIF;
- end_line := num;
- ELSE
- end_line := start_line;
- ENDIF;
- ENDIF;
-
- POSITION (pos);
-
- work_range := 0;
- whole_range := 0;
-
- IF (start_line > end_line) THEN
- vi$message ("Bad range of lines!");
- RETURN (1);
- ENDIF;
-
- start_mark := vi$mark_line (start_line);
- end_mark := vi$mark_line (end_line);
-
- IF (start_mark = 0) OR (end_mark = 0) THEN
- vi$message ("Bad range of lines!");
- RETURN (1);
- ENDIF;
-
- work_range := CREATE_RANGE (start_mark, end_mark, NONE);
-
- pos := MARK (NONE);
- POSITION (end_mark);
-
- IF (end_mark <> END_OF (CURRENT_BUFFER)) THEN
- MOVE_VERTICAL (1);
- ENDIF;
-
- IF (end_mark <> BEGINNING_OF (CURRENT_BUFFER)) THEN
- MOVE_HORIZONTAL (-1);
- ENDIF;
-
- whole_range := CREATE_RANGE (start_mark, MARK (NONE), NONE);
- POSITION (pos);
-
- ! If there is no command then move to the line indicated.
-
- rest := vi$rest_of_line (cmd, i);
- EDIT (rest, COLLAPSE);
- IF rest = "" THEN
- vi$old_place := MARK (NONE);
- POSITION (start_mark);
- RETURN (0);
- ENDIF;
-
- token_1 := vi$get_cmd_token (vi$_lower_chars, cmd, i);
-
- IF (token_1 = "help") THEN
- RETURN (vi$do_help (vi$rest_of_line (cmd, i)));
- ENDIF;
-
- IF (token_1 = "show") THEN
- RETURN (vi$do_show (cmd, i));
- ENDIF;
-
- ! Check for substitution alias.
-
- IF (token_1 = "") AND (vi$parse_next_ch (i, cmd, "&")) THEN
- RETURN (vi$do_subs_alias (cmd, i, start_line, end_line, whole_range));
- ENDIF;
-
- IF (token_1 = "") AND (vi$parse_next_ch (i, cmd, "@")) THEN
- RETURN (vi$do_macro_buffer (cmd, i));
- ENDIF;
-
- IF (token_1 = "learn") THEN
- RETURN (vi$do_learn (cmd, i));
- ENDIF;
-
- IF (token_1 = "unlearn") THEN
- RETURN (vi$do_unlearn (cmd, i));
- ENDIF;
-
- IF (token_1 = "g") THEN
- RETURN (vi$do_global (cmd, i));
- ENDIF;
-
- IF (token_1 = "sh") OR (token_1 = "dcl") THEN
- RETURN (vi$spawn (0));
- ENDIF;
-
- IF (vi$leading_str (token_1, "unabbr") AND (LENGTH (token_1) > 4)) THEN
- RETURN (vi$do_unabbr (cmd, i));
- ENDIF;
-
- IF (vi$leading_str (token_1, "abbr") AND (LENGTH (token_1) > 3)) THEN
- RETURN (vi$do_abbr (cmd, i));
- ENDIF;
-
- IF (vi$leading_str (token_1, "edit")) OR
- (vi$leading_str (token_1, "vi")) THEN
- RETURN (vi$do_edit (cmd, i, token_1));
- ENDIF;
-
- IF (token_1 = "") THEN
- IF (vi$parse_next_ch (i, cmd, "!")) THEN
- RETURN (vi$do_subproc (cmd, i));
- ENDIF;
- ENDIF;
-
- IF (vi$leading_str (token_1, "copy")) THEN
- RETURN (vi$do_copy (cmd, i, whole_range, olen, start_line, end_line));
- ENDIF;
-
- IF (vi$leading_str (token_1, "move")) THEN
- RETURN (vi$do_move (cmd, i, whole_range, start_line, end_line));
- ENDIF;
-
- IF (vi$leading_str (token_1, "select")) AND (LENGTH (token_1) > 2) THEN
- RETURN (vi$do_select);
- ENDIF;
-
- IF (token_1 = "fill") THEN
- RETURN (vi$do_fill (cmd, i, whole_range, olen));
- ENDIF;
-
- IF ((LENGTH (token_1) > 1) AND (vi$leading_str (token_1, "upper") OR
- vi$leading_str (token_1, "lower") OR
- vi$leading_str (token_1, "invert"))) THEN
- RETURN (vi$do_case (token_1, whole_range));
- ENDIF;
-
- IF (token_1 = "s") THEN
- RETURN (vi$do_substitute (start_line, end_line, whole_range, i, cmd));
- ENDIF;
-
- IF (token_1 = "d") THEN
- RETURN (vi$do_delete (start_mark, whole_range, olen));
- ENDIF;
-
- ! Do the write file command. You can write either a buffer, or a
- ! portion of one.
-
- IF (vi$leading_str (token_1, "write")) THEN
- RETURN (vi$do_write (cmd, i, no_spec, token_1, whole_range));
- ENDIF;
-
- IF (token_1 = "wq") THEN
- RETURN (vi$do_wq (cmd, i, no_spec, token_1, whole_range));
- ENDIF;
-
- ! Read in a file to the current buffer.
-
- IF (vi$leading_str (token_1, "read")) THEN
- RETURN (vi$do_read (cmd, i, start_line, olen));
- ENDIF;
-
- IF (vi$leading_str (token_1, "file")) THEN
- RETURN (vi$do_file_ex (cmd, i));
- ENDIF;
-
- IF (vi$leading_str (token_1, "buffer")) THEN
- RETURN (vi$do_buffer (cmd, i, token_1));
- ENDIF;
-
- IF (token_1 = "so") THEN
- RETURN (vi$do_file (vi$rest_of_line (cmd, i), 1));
- ENDIF;
-
- IF (vi$leading_str (token_1, "messages")) THEN
- RETURN (vi$do_messages);
- ENDIF;
-
- IF (vi$leading_str (token_1, "delbuf")) THEN
- RETURN (vi$do_delbuf (cmd, i));
- ENDIF;
-
- IF (vi$leading_str (token_1, "xit")) THEN
- RETURN (vi$_ZZ);
- ENDIF;
-
- IF (token_1 = "rew") THEN
- RETURN (vi$_first_file);
- ENDIF;
-
- IF (vi$leading_str (token_1, "prev")) THEN
- RETURN (vi$_previous_file);
- ENDIF;
-
- IF (vi$leading_str (token_1, "next")) THEN
- RETURN (vi$_next_file);
- ENDIF;
-
- IF (token_1 = "tag") OR (token_1 = "ta") THEN
- vi$skip_white (cmd, i);
- IF (vi$rest_of_line (cmd, i) = "") THEN
- RETURN (vi$do_tag (0));
- ELSE
- RETURN (vi$do_tag (vi$rest_of_line (cmd, i)));
- ENDIF;
- ENDIF;
-
- IF (token_1 = "map") THEN
- RETURN (vi$map_keys (cmd, i));
- ENDIF;
-
- IF (token_1 = "unmap") THEN
- RETURN (vi$unmap_keys (cmd, i));
- ENDIF;
-
- IF (token_1 = "set") THEN
- RETURN (vi$set_commands (cmd, i));
- ENDIF;
-
- IF (token_1 = "tpu") THEN
- RETURN (vi$do_tpu (cmd, i, no_spec, whole_range));
- ENDIF;
-
- IF (token_1 = "cd") OR (token_1 = "chdir") THEN
- RETURN (vi$do_cd (cmd, i));
- ENDIF;
-
- ! Quit the current editor session.
-
- IF (vi$leading_str (token_1, "quit")) THEN
- RETURN (vi$do_quit (cmd, token_1));
- ENDIF;
-
- MESSAGE ("Unrecognized command!");
- RETURN (1);
- ENDPROCEDURE;
-
- !
- !
- !
- PROCEDURE vi$do_unlearn (cmd, i)
- LOCAL
- keyn,
- com;
-
- MESSAGE ("Press the key you want to unlearn: ");
- keyn := vi$read_a_key;
-
- IF (keyn = F11) OR (ASCII (27) = ASCII (keyn)) THEN
- MESSAGE ("UNLEARN aborted!");
- RETURN (1);
- ENDIF;
-
- com := LOOKUP_KEY (keyn, COMMENT, vi$cmd_keys);
- IF (com <> "learn_sequence") THEN
- MESSAGE ("That key is not a learned KEY!");
- RETURN (1);
- ENDIF;
-
- UNDEFINE_KEY (keyn, vi$cmd_keys);
- ENDPROCEDURE;
-
- !
- !
- !
- PROCEDURE vi$do_learn (cmd, i)
- LOCAL
- keyn,
- strg;
-
- MESSAGE ("Type KEY sequence, and press CTRL-R to remember sequence");
- vi$in_learn := 1;
- LEARN_BEGIN (EXACT);
- RETURN (1);
- ENDPROCEDURE;
-
- !
- ! Remember the keystrokes that have been typed.
- !
- PROCEDURE vi$remember
-
- LOCAL
- key,
- keyn,
- com;
-
- ON_ERROR
- RETURN (1);
- ENDON_ERROR;
-
- IF (vi$in_learn = 0) THEN
- RETURN (0);
- ENDIF;
-
- MESSAGE ("Press key to bind sequence to: ");
- keyn := vi$read_a_key;
-
- IF (keyn = F11) OR (ASCII (27) = ASCII (keyn)) THEN
- MESSAGE ("LEARN aborted!");
- com := LEARN_END;
- vi$in_learn := 0;
- RETURN (1);
- ENDIF;
-
- com := LOOKUP_KEY (keyn, COMMENT, vi$cmd_keys);
- IF (com = "active_macro") THEN
- MESSAGE ("That key is a mapped key, you must unmap it first");
- RETURN (1);
- ENDIF;
-
- key := "vi$ls_"+vi$key_map_name (keyn);
- EXECUTE (COMPILE (key+":=LEARN_END"));
- vi$in_learn := 0;
- DEFINE_KEY ("vi$play_back("+key+")", keyn, "learn_sequence", vi$cmd_keys);
- MESSAGE ("Sequence bound to key");
- RETURN (1);
- ENDPROCEDURE;
-
- !
- !
- !
- PROCEDURE vi$play_back (prog)
- LOCAL
- old_play_back,
- old_global;
-
- IF (vi$m_level > 30) THEN
- MESSAGE ("Infinite loop detected in key macro sequence!");
- RETURN;
- ENDIF;
- vi$m_level := vi$m_level + 1;
-
- IF vi$undo_map THEN
- old_global := vi$in_global;
- vi$in_global := 0;
- IF (NOT old_global) THEN
- vi$save_for_undo (CURRENT_BUFFER, VI$LINE_MODE, 1);
- vi$in_global := 1;
- ENDIF;
- ENDIF;
-
- old_play_back := vi$playing_back;
- vi$playing_back := 1;
- EXECUTE (prog);
- vi$playing_back := old_play_back;
- vi$m_level := vi$m_level - 1;
-
- vi$in_global := old_global;
- ENDPROCEDURE;
-
- !
- ! Remove an abbreviation
- !
- PROCEDURE vi$do_unabbr (cmd, i)
- LOCAL
- separ,
- junk,
- idx,
- ch,
- abbr,
- abbrn;
-
- abbr := "";
- abbrn := "";
-
- junk := vi$skip_separ (cmd, i, " ", separ);
- IF (LENGTH (junk) = 0) THEN
- MESSAGE ("Abbreviation name required!");
- RETURN (1);
- ENDIF;
-
- idx := 1;
- LOOP
- EXITIF idx > LENGTH (junk);
- ch := SUBSTR (junk, idx, 1);
- IF (INDEX (vi$_alpha_chars, ch) = 0) THEN
- MESSAGE ("Invalid character in UNABBR name, '"+ch+
- "', is not valid.");
- RETURN (1);
- ENDIF;
- IF (INDEX (vi$_upper_chars, ch) <> 0) THEN
- abbrn := abbrn + "_";
- ENDIF;
- abbrn := abbrn + ch;
- idx := idx + 1;
- ENDLOOP;
- EXECUTE (COMPILE ("VI$ABBR_"+abbrn+":=0;"));
- RETURN (0);
- ENDPROCEDURE;
-
- !
- ! Create an abbreviation
- !
- PROCEDURE vi$do_abbr (cmd, i)
- LOCAL
- separ,
- abbr,
- junk,
- idx,
- ch,
- abbrn;
-
- abbr := "";
- abbrn := "";
-
- junk := vi$skip_separ (cmd, i, " ", separ);
- IF (LENGTH (junk) = 0) THEN
- vi$show_abbrevs;
- RETURN (0);
- ENDIF;
-
- idx := 1;
- LOOP
- EXITIF idx > LENGTH (junk);
- ch := SUBSTR (junk, idx, 1);
- IF (INDEX (vi$_alpha_chars, ch) = 0) THEN
- MESSAGE ("Invalid character in ABBR name, '"+ch+"', is not valid.")
- ;
- RETURN (1);
- ENDIF;
- IF (INDEX (vi$_upper_chars+"_", ch) <> 0) THEN
- abbrn := abbrn + "_";
- ENDIF;
- abbrn := abbrn + ch;
- idx := idx + 1;
- ENDLOOP;
- abbr := vi$rest_of_line (cmd, i);
- EXECUTE (COMPILE ("VI$ABBR_"+abbrn+":="""+abbr+""""));
- RETURN (0);
- ENDPROCEDURE;
-
- !
- ! Execute the contents of the buffers named following an '@'.
- !
- PROCEDURE vi$do_macro_buffer (cmd, i)
- LOCAL
- line,
- mode,
- buf_name,
- pos,
- buf,
- ch;
-
- ON_ERROR
- ENDON_ERROR;
-
- vi$skip_white (cmd, i);
-
- LOOP
- ch := vi$next_char (cmd, i);
- EXITIF (ch = "");
-
- IF (INDEX ("123456789", ch) <> 0) THEN
-
- ! Selected a deletion buffer.
-
- buf_name := "vi$del_buf_" + ch;
- ELSE
- IF (INDEX (vi$_letter_chars, ch) <> 0) THEN
-
- ! Selected a named buffer.
-
- CHANGE_CASE (ch, LOWER);
-
- buf_name := "vi$ins_buf_" + ch;
- ELSE
- vi$message ("Invalid buffer!");
- RETURN;
- ENDIF;
- ENDIF;
-
- vi$global_var := 0;
- EXECUTE (COMPILE ("vi$global_var := "+buf_name+";"));
- buf := vi$global_var;
- IF (buf = 0) THEN
- vi$message ("There is no text in that buffer!");
- RETURN;
- ENDIF;
-
- pos := MARK (NONE);
- POSITION (BEGINNING_OF (buf));
-
- ! Skip the buffer mode indicator.
-
- mode := INT (vi$current_line);
- MOVE_VERTICAL (1);
- line := vi$current_line;
-
- IF mode = VI$LINE_MODE THEN
- line := line + ASCII (13);
- ENDIF;
-
- POSITION (pos);
- vi$do_macro (line, 1);
- ENDLOOP;
-
- ENDPROCEDURE;
-
- !
- !
- !
- PROCEDURE vi$do_global (cmd, i)
- LOCAL
- cmd_str,
- sch_str,
- subs_str,
- sch,
- ch,
- nsubs,
- lpos,
- olen,
- fpos;
-
- olen := GET_INFO (CURRENT_BUFFER, "RECORD_COUNT");
- vi$skip_white (cmd, i);
- IF NOT vi$parse_next_ch (i, cmd, "/") THEN
- MESSAGE ("/ Search string must follow global!");
- RETURN (1);
- ENDIF;
-
- sch := SUBSTR (cmd, i-1, 1);
- sch_str := "";
- LOOP
- EXITIF (vi$parse_next_ch (i, cmd, sch));
- EXITIF (LENGTH (cmd) < i);
- ch := SUBSTR (cmd, i, 1);
- IF (ch = "\") THEN
- sch_str := sch_str + SUBSTR (cmd, i, 2);
- i := i + 1;
- ELSE
- sch_str := sch_str + ch;
- ENDIF;
- i := i + 1;
- ENDLOOP;
-
- IF (LENGTH (cmd) < i) THEN
- MESSAGE ("Incomplete command!");
- RETURN (1);
- ENDIF;
-
- vi$save_for_undo (CURRENT_BUFFER, VI$LINE_MODE, 1);
- cmd_str := vi$rest_of_line (cmd, i);
-
- SET (FORWARD, CURRENT_BUFFER);
- POSITION (BEGINNING_OF (CURRENT_BUFFER));
-
- nsubs := 0;
- subs_str := SUBSTR (cmd_str, 2, 255);
-
- LOOP
- fpos := vi$find_str (sch_str, 1);
- EXITIF fpos = 0;
-
- POSITION (fpos);
- IF cmd_str = "d" THEN
- ERASE_LINE;
- ELSE
- IF SUBSTR (cmd_str, 1, 1) = "s" THEN
- lpos := vi$global_subs (subs_str, nsubs);
- MOVE_HORIZONTAL (-CURRENT_OFFSET);
- MOVE_VERTICAL (1);
- ELSE
- MESSAGE ("Bad command for global: "+cmd_str);
- vi$kill_undo;
- vi$undo_end := 0;
- $$EOD$$
-