gregg@a.cs.okstate.edu (Gregg Wonderly) (03/16/88)
I appologize to those of you who really don't want this again. My previous posting contained tabs which were promptly removed by the first brain damaged mailer the artical passed through. Some lines were also wrapped :-(. Anyway, here it is again. For those who do not know how to add this to EVE, you can do one of the following. 1) a. Start EVE b. "GET" re.tpu into a buffer c. issue the command "EXTEND *" d. issue the appropriate "SAVE_EXTENDED_TPU" command to put the resulting section file where you want it. e. change your normal invocation of EDIT/TPU to include the /SECTION= qualifier with the value being the path to the section file that you created. i.e. if you issue the command, "SAVE F$DISK:[GREGG.TPUSTUFF]MYEVE.GBL" then you would use /SECTION=F$DISK:[GREGG.TPUSTUFF]MYEVE.GBL. (.GBL is certainly shorter then .TPU$SECTION). * This procedure is advantageous in that you do not have to wait for EVE to load and compile the extension each time you start it. 2) a. Change your usual invocation of EVE to include the /COMMAND= qualifier with the value being the path to RE.TPU. * This procedure is advantageous if you do not have the quota to support a TPU section file, but has the drawback that the startup of EVE will be a lot slower. Gregg Wonderly Department of Mathematics Oklahoma State University UUCP: {cbosgd, ihnp4, rutgers}!okstate!nemo.math.okstate.edu!gregg Internet: gregg@NEMO.MATH.OKSTATE.EDU =========================================================================== $!............................................................................. $! VAX/VMS archive file created by VMS_SHAR V-5.03 07-Oct-1987 $! which was written by Michael Bednarek (U3369429@ucsvc.dn.mu.oz.au) $! To unpack, simply save and execute (@) this file. $! $! This archive was created by GREGG $! on Monday 14-MAR-1988 14:17:23.19 $! $! It contains the following 2 files: $! RE.RNO RE.TPU $!============================================================================= $ Set Symbol/Scope=(NoLocal,NoGlobal) $ Version=F$GetSYI("VERSION") ! See what VMS version we have here: $ If Version.ges."V4.4" then goto Version_OK $ Write SYS$Output "Sorry, you are running VMS ",Version, - ", but this procedure requires V4.4 or higher." $ Exit 44 $Version_OK: CR[0,8]=13 $ Pass_or_Failed="failed!,passed." $ Goto Start $Convert_File: $ Read/Time_Out=0/Error=No_Error1/Prompt="creating ''File_is'" SYS$Command ddd $No_Error1: Define/User_Mode SYS$Output NL: $ Edit/TPU/NoSection/NoDisplay/Command=SYS$Input/Output='File_is' - VMS_SHAR_DUMMY.DUMMY set(Informational, off); set (success, off); f:=Get_Info(Command_Line,"File_Name"); b:=Create_Buffer("",f); o:=Get_Info(Command_Line,"Output_File"); Set(Output_File,b,o); Position(Beginning_of(b)); Loop x:=Erase_Character(1); Loop ExitIf x<>"V"; Move_Vertical(1); x:=Erase_Character(1); Append_Line; Move_Horizontal(-Current_Offset); EndLoop; Move_Vertical(1); ExitIf Mark(None)=End_of(b) EndLoop; Position(Beginning_of(b)); Loop x:=Search("`",Forward,Exact); ExitIf x=0; Position(x); Erase_Character(1); If Current_Character='`' then Move_Horizontal(1); else Copy_Text(ASCII(INT(Erase_Character(3)))); EndIf; EndLoop; Exit; $ Delete VMS_SHAR_DUMMY.DUMMY;* $ Checksum 'File_is $ Success=F$Element(Check_Sum_is.eq.CHECKSUM$CHECKSUM,",",Pass_or_Failed)+CR $ Read/Time_Out=0/Error=No_Error2/Prompt=" CHECKSUM ''Success'" SYS$Command ddd $No_Error2: Return $Start: $ File_is="RE.RNO" $ Check_Sum_is=157000438 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X.I-1 X3 FIND X.br XFIND X.s X.endif manual XSearches for an occurrence of a pattern. FIND uses a very powerful pattern Xmatching mechanism known as a regular expression. Regular expressions use Xspecial characters to denote special patterns such as the beginning of the Vline, and the end of the line. The regular expressions recognized by FIND hav Xe Xthe following form. X.s X.lm +5 XThe character '.' represents any character. Thus, the pattern ".t" matches X"it", "at", "ot", "lt", and other strings of length 2 that end in a "t". X.s XThe character '^' as the first character of a pattern indicates that the Xfollowing characters should be looked for only at the beginning of the line. X.s XThe character '$' as the last character of a pattern indicates that the Vpreceeding characters should be looked for only at the end of a line. Anywher Xe Xelse in the pattern it is taken literally. X.s XThe character '[' starts a list of characters that ends with a ']'. The Xcharacters between the '[' and ']' indicate all the possible characters that Xcan occur ONCE at that position in the pattern. Thus, the pattern "[ai]t" Xmatches ONLY the strings "it" and "at". If the first character following the X'[' is a '^', then the complement of the set of characters that follows is Xassumed. Thus, the pattern "[^ia]t", never matches the strings "it" or "at". XIt is possible to denote a sequence of characters by placing a '-' between two Xcharacters. Thus, "[0-9]" is short for "[0123456789]". X.s XThe character '*' is a multiplicative operator. Its presence indicates that Xthe preceeding character or [...] set might occur zero or more times. Thus, Xthe pattern "i[ai]*t" matches "it", "iat", "iit", "iaat", "iiit", "iait", and Xall other strings starting with "i", ending with "t", and having only the Xcharacters 'a' or 'i' between. X.s XBecause the characters '[', '.', '^', '$', and '*' are special, they must Xbe preceed by a '\' if they are meant literally in a pattern. Thus, '\' Xitself must be indicated as "\\". X.lm -5 X.s XPress the FIND key and then enter the pattern from the main keyboard. End the Xstring by pressing the RETURN key. To search for the previously specified Xpattern, press the FIND key twice, or use the FIND NEXT key on the keypad X(normally PF3). You can press the FIND key, and then press the up-arrow Xkey to edit the previously specified search string. X.s XFIND is case-insensitive if the string contains only lowercase letters; it is Xcase-sensitive if the string contains any uppercase letters. X.s XThe direction of the search (Forward or Reverse) is determined by the current Xdirection of the buffer, as shown in the status line at the bottom of the Xbuffer. If the pattern can be found only by searching in the opposite Xdirection, GWEDIT asks you if you want to move the cursor in that direction. X.s VThe FIND command is bound to the FIND key, and the SHIFT-KEY, PF3 key sequence X. X.I-1 X3 REPLACE X.br XREPLACE X.s X.endif manual XLets you repeatedly substitute one word or phrase for another Xthroughout a buffer. For example, X.s X.I+5 Xreplace good excellent X.s Xinstructs GWEDIT to replace "good" with "excellent" in the current Xbuffer. X.s XEach occurrence of "good" within the current buffer will be highlighted in Vreverse video, and you will be prompted for an action. Typing "YES", "Y", "y" X, X"yes" or just pressing RETURN replaces this occurrence. "NO", "no", "n", or X"N", skips this occurrence. "All" replaces this occurrence and all future Voccurrences without any further prompting. "Last" replaces this occurrence an Xd Xstops the REPLACE command. "Quit" stops the REPLACE command without replacing Xthis occurrence. X.s XIn order to replace multi-word phrases, put the phrases in Xquotation marks. For example, X.s X.I+5 Xreplace "the first one" "the second one" X.s VSpecial notation in the first string allows you to specify regular expressions X. XSee the FIND command for more information. You may also specify groups of Xcharacters in the first string to be placed in the second string when the Vsubstitution occurs. An '&' in the second string will cause all text that was X found Xby the search pattern to be placed in the resultant string. X.s X.lm+5 Xe.g. REPLACE "go[ <TAB>]*" "foo$&" X.s X.lm-5 Xwill cause the string "foo$" to be prepended to all occurrances of the string X"go" followed by zero or more space or tab characters. X.s XIt is also possible to pick portions of the original text to be kept in the Xresultant text. X.s X.lm+5 Xe.g. REPLACE "foo$\(go[ <TAB>]\)" "\1" X.lm-5 X.s Xwould cause the prefix "foo$" to be removed from all occurances of the string X"foo$go" followed by zero or more space or tab characters. The notation Xshown is derived Xfrom the EX(1) editor under UNIX. Up to 9 sets of \( \) pairs may appear Xinside the search string. These are refered to by specifying the relative Xnumber from left to right. E.g. to swap two columns of text that occur at the Xbeginning of a line, you might say X.lm+5 X.s XREPLACE "^\([^ <TAB>]*\)\([ <TAB>]*\)\([^ <TAB>]*\)" "\3\2\1" X.lm -5 X.s Xwhich delimits three groups of characters. The first is a sequence of Xcharacters which are not spaces or tabs, followed by a group of characters Xwhich are spaces or tabs, followed, again, by a sequence of characters which Xare not spaces or tabs. By swapping field 3 with field 1, the columns will be Xswapped. $ GoSub Convert_File $ File_is="RE.TPU" $ Check_Sum_is=1898631914 $ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY X! X! Top-level find command. Calls eve$find, as does the replace command. X! The two commands have slightly different requirements, so they both X! call eve$find and pass it a parameter to indicate the caller. X! X! Parameters: X! X! target String to find - input X XPROCEDURE eve_find (target, compile_it) X X LOCAL X comp_val; X X comp_val := compile_it; X X IF (GET_INFO (compile_it, "TYPE") = STRING) THEN X comp_val := 1; ! Always compile when EVE_FIND is called by EVE_PARSE. X ENDIF; X X eve$find (target, 0, comp_val, 0); X XENDPROCEDURE; X`012 X! X! Search for target in the current direction. If not found in the X! current direction look in the opposite direction, but do not go X! there without prompting the user. Search is case-insensitive if X! target is all lowercase; otherwise is case-sensitive. X! Returns range if target found, otherwise returns false. X! X! Parameters: X! X! target String to find - input X! replacing If true, called by eve_replace; allow a X! match at current cursor position - input X XPROCEDURE eve$find (target, replacing, compile_it, do_parens) X X LOCAL X new_target, ! Local copy of target X lowercase_target, ! Lowercase version of eve$x_target X start_find_key, ! String describing key used to invoke find X old_str, X old_pos, X new_pat, X stop_find_key, ! String describing key used after prompt X this_position, ! Marker for current cursor position X how_exact, ! Keyword to indicate case-sensitivity X find_range, ! Range returned by search X other_direction, ! Keyword for opposite direction X other_direction_string, ! String for message including other_direction X find_reply, ! Reply to inquiry about changing direction X change_direction_key; ! Keyword for key used to end find_reply X X ON_ERROR X IF ERROR = TPU$_STRNOTFOUND THEN X find_range := 0; X ENDIF; X ENDON_ERROR; X X start_find_key := eve$lookup_comment (LAST_KEY); X X IF target <> eve$kt_null THEN X new_target := target; X ELSE X IF CURRENT_DIRECTION = FORWARD THEN X new_target := READ_LINE ("Forward Find: "); X ELSE X new_target := READ_LINE ("Reverse Find: "); X ENDIF; X ENDIF; X X IF (compile_it = 0) AND (GET_INFO (new_target, "TYPE") = STRING) THEN X eve$x_orig_target := new_target; X ENDIF; X X IF (new_target <> "") AND (GET_INFO (new_target, "TYPE") = STRING) AND X (compile_it <> 0) THEN X eve$x_orig_target := new_target; X eve$x_paren_cnt := 0; X new_pat := eve$pattern_gen (new_target, eve$x_paren_cnt, do_parens); X X IF (new_pat = "") THEN X RETURN (0); X ENDIF; X X EXECUTE (COMPILE ("eve$x_find_pat := " + new_pat)); X new_target := eve$x_find_pat; X ENDIF; X X stop_find_key := eve$lookup_comment (LAST_KEY); X X IF new_target = eve$kt_null THEN X IF ((start_find_key = "find") AND X ((stop_find_key = "find") OR (stop_find_key = "return"))) THEN X X IF eve$x_target = eve$kt_null THEN X MESSAGE ("No previous target to find"); X RETURN (0); X ELSE X IF GET_INFO (eve$x_orig_target, "TYPE") = STRING THEN X MESSAGE (FAO ("Finding: !AS", eve$x_orig_target)); X ELSE X MESSAGE ("Finding previous target: "); X ENDIF; X ENDIF; X ELSE X MESSAGE ("Invalid terminator"); X RETURN (0); X ENDIF; X ELSE X eve$x_target := new_target; X IF GET_INFO (eve$x_orig_target, "TYPE") = STRING THEN X MESSAGE (FAO ("Finding: !AS", eve$x_orig_target)); X ELSE X MESSAGE ("Searching..."); X ENDIF; X endif; X X lowercase_target := eve$x_orig_target; X X IF GET_INFO (lowercase_target, "TYPE") = STRING THEN X CHANGE_CASE (lowercase_target, LOWER); X ENDIF; X X IF lowercase_target = eve$x_orig_target THEN X how_exact := NO_EXACT; X ELSE X how_exact := EXACT; X ENDIF; X X this_position := MARK (NONE); X X IF CURRENT_DIRECTION = FORWARD THEN X IF this_position <> END_OF (CURRENT_BUFFER) THEN X IF NOT replacing THEN X MOVE_HORIZONTAL (1); X ENDIF; X find_range := SEARCH (eve$x_target, FORWARD, how_exact); X ELSE X find_range := 0; X ENDIF; X ELSE X IF this_position <> BEGINNING_OF (CURRENT_BUFFER) THEN X MOVE_HORIZONTAL (-1); X find_range := SEARCH (eve$x_target, REVERSE, how_exact); X ELSE X find_range := 0; X ENDIF; X ENDIF; X X IF find_range = 0 THEN X IF CURRENT_DIRECTION = FORWARD THEN X other_direction := REVERSE; X other_direction_string := "reverse"; X ELSE X other_direction := FORWARD; X other_direction_string := "forward"; X ENDIF; X X POSITION (this_position); X X IF other_direction = FORWARD THEN X IF this_position <> END_OF (CURRENT_BUFFER) THEN X MOVE_HORIZONTAL (1); X find_range := SEARCH (eve$x_target, FORWARD, how_exact); X ELSE X find_range := 0; X ENDIF; X ELSE X IF this_position <> BEGINNING_OF (CURRENT_BUFFER) THEN X MOVE_HORIZONTAL (-1); X find_range := SEARCH (eve$x_target, REVERSE, how_exact); X ELSE X find_range := 0; X ENDIF; X ENDIF; X X IF find_range = 0 THEN X IF GET_INFO (eve$x_orig_target, "TYPE") = STRING THEN X MESSAGE (FAO ("Could not find: !AS", eve$x_orig_target)); X ELSE X MESSAGE ("Could not find pattern!"); X ENDIF; X X POSITION (this_position); X RETURN (0); X ELSE X find_reply := X READ_LINE (FAO ("Found in !AS direction. Go there? ", X other_direction_string)); X X ! Hitting return or do means yes; hitting another non-typing X ! key is probably a mistake, so interpret as no. X X IF find_reply = eve$kt_null THEN X change_direction_key := eve$lookup_comment (LAST_KEY); X X IF (change_direction_key = "return") OR X (change_direction_key = "do") THEN X find_reply := "yes"; X ELSE X find_reply := "no"; X ENDIF; X ELSE X CHANGE_CASE (find_reply, LOWER); X ENDIF; X X IF SUBSTR ("yes", 1, LENGTH (find_reply)) = find_reply THEN X SET (other_direction, CURRENT_BUFFER); X eve$update_status_lines; X eve$position_in_middle (BEGINNING_OF (find_range)); X RETURN (find_range); X ELSE X POSITION (this_position); X RETURN (0); X ENDIF; X ENDIF; X ELSE X eve$position_in_middle (BEGINNING_OF (find_range)); X RETURN (find_range); X ENDIF; X X MESSAGE (eve$kt_null); XENDPROCEDURE; X`012 X! X! X! TPU pattern generator. Generates a pattern string from the passed X! regular expression. X! XPROCEDURE eve$pattern_gen (pat, paren_cnt, do_parens) X X LOCAL X first, ! First pattern to be done X part_pat, X chno, X startchar, X haveany, X regular, X tstr, X endchar, X str_pat, X cur_pat, ! The current pattern to be extracted X cur_char, ! The current character in the regular X ! expression being examined X new_pat, ! The output pattern X pos; ! The position within the regular X ! expression string that we are examining X ! currently X X paren_cnt := 0; X X IF ((INDEX (pat, "$") <> 0) OR (INDEX (pat, "[") <> 0) OR X (INDEX (pat, "^") <> 0) OR (INDEX (pat, ".") <> 0) OR X (INDEX (pat, "*") <> 0) OR (INDEX (pat, "\") <> 0) OR X (INDEX (pat, '"') <> 0)) THEN X new_pat := ""; X ELSE X new_pat := '"'+pat+'"'; X RETURN (new_pat); X ENDIF; X X pos := 1; X X IF SUBSTR (pat, pos, 1) = "^" THEN X new_pat := "line_begin"; X pos := pos + 1; X ENDIF; X X LOOP X EXITIF (pos > LENGTH (pat)); X X regular := 0; X cur_pat := ""; X cur_char := substr (pat, pos, 1); X pat_str := ""; X X IF (cur_char = "$") THEN X cur_pat := "line_end"; X IF (pos < LENGTH (pat)) THEN X cur_pat := "'$'"; X ENDIF; X ELSE X IF cur_char = "[" THEN X pos := pos + 1; X X IF SUBSTR (pat, pos, 1) = "^" THEN X pos := pos + 1; X part_pat := "notany('"; X ELSE X part_pat := "any('"; X ENDIF; X X LOOP X EXITIF pos > LENGTH (pat); X EXITIF SUBSTR (pat, pos, 1) = "]"; X X IF SUBSTR (pat, pos, 1) = "\" THEN X pos := pos + 1; X IF pos > LENGTH (pat) THEN X MESSAGE ("Missing character after \"); X RETURN (""); X ENDIF; X ENDIF; X X startchar := SUBSTR (pat, pos, 1); X pat_str := pat_str + startchar; X X IF (SUBSTR (pat, pos+1, 1) = '-') THEN X pos := pos + 2; X IF (pos >= LENGTH (pat)) THEN X MESSAGE ("Missing character after '-'"); X RETURN (""); X ENDIF; X X endchar := SUBSTR (pat, pos, 1); X X chno := 1; X LOOP X EXITIF (ASCII(chno) = startchar); X chno := chno + 1; X ENDLOOP; X X LOOP X chno := chno + 1; X IF (chno > 255) THEN V MESSAGE ("Invalid character sequence for '-'") X; X RETURN (""); X ENDIF; X X EXITIF (ASCII (chno-1) = endchar); X pat_str := pat_str + ASCII (chno); X ENDLOOP; X ENDIF; X pos := pos + 1; X ENDLOOP; X X IF pat_str = "" THEN X MESSAGE ("No text found between []"); X RETURN (""); X ENDIF; X X IF (SUBSTR (pat, pos+1, 1) = "*") THEN X IF (part_pat = "notany('") THEN X cur_pat := cur_pat + "(scan('"+pat_str+"')|"""")"; X ELSE X cur_pat := cur_pat + "(span('"+pat_str+"')|"""")"; X ENDIF; X pos := pos + 1; X ELSE X cur_pat := part_pat + pat_str + "')"; X ENDIF; X ELSE X X ! X ! Process a single character character, either '\', '.', X ! or some literal character. There might be a '*' following X ! a character, in which case that is also handled here. X ! X X tstr := '"'; X haveany := 0; X regular := 1; X X LOOP X cur_char := SUBSTR (pat, pos, 1); X EXITIF (INDEX ("$^[", cur_char) > 0); X EXITIF (pos > LENGTH (pat)); X X IF cur_char = "\" THEN X pos := pos + 1; X cur_char := SUBSTR (pat, pos, 1); X IF (do_parens) THEN X IF (cur_char = "(") THEN X paren_cnt := paren_cnt + 1; X IF tstr = '"' THEN X tstr := '""@o'+STR(paren_cnt)+'&"'; X ELSE X tstr := tstr + '"@o'+STR(paren_cnt)+'&"'; X ENDIF; X ELSE X IF (cur_char = ")") THEN X IF (paren_cnt = 0) THEN X MESSAGE ( X FAO ("No previous ""\("" near: !AS", X SUBSTR (pat, pos, LENGTH(pat)-pos)) X ); X RETURN (0); X ENDIF; X X IF tstr = '"' THEN X tstr := "@p"+STR(paren_cnt)+'&"'; X ELSE X tstr := tstr + '"@p' + X STR(paren_cnt)+'&"'; X ENDIF; X ELSE X tstr:=tstr+cur_char; X ENDIF; X ENDIF; X ELSE X tstr:=tstr+cur_char; X ENDIF; X ELSE X IF (cur_char = ".") THEN X cur_char := "longer_than_1"; X ENDIF; X X ! Check for zero or more X X IF (SUBSTR (pat, pos+1, 1) = '*') THEN X pos := pos + 1; X X IF (LENGTH (cur_char) > 1) THEN X cur_pat := X "''&(span(eve$pch)|'')"; X ELSE X cur_pat := "(span('"+cur_char+"')|"""")"; X ENDIF; X tstr := tstr+'"'+"&"+cur_pat+"&"+'"'; X haveany := 0; X ELSE X IF (LENGTH (cur_char) > 1) THEN X IF (haveany) THEN X tstr := tstr +'"'+"&"+"arb(1)"+"&"+'"'; X haveany := 0; X ELSE V IF (LENGTH (tstr)>0) and (tstr <> '"') THE XN V tstr := tstr +'"'+"&"+"arb(1)"+"&"+'"' X; X ELSE X tstr := "arb(1)"+"&"+'"'; X ENDIF X ENDIF; X ELSE X IF (cur_char = """") THEN X tstr := tstr + '""'; X haveany := haveany + 2; X ELSE X tstr := tstr + cur_char; X haveany := haveany + 1; X ENDIF; X ENDIF; X ENDIF; X ENDIF; X pos := pos + 1; X ENDLOOP; X cur_pat := tstr + '"'; X pos := pos - 1; X ENDIF; X ENDIF; X X IF (regular) THEN X IF new_pat = "" THEN X new_pat := cur_pat; X ELSE X IF (LENGTH (tstr) > 1) THEN X new_pat := new_pat + "&" + cur_pat; X ENDIF; X ENDIF; X ELSE X IF new_pat = "" THEN X new_pat := cur_pat; X ELSE X new_pat := new_pat + "&" + cur_pat; X ENDIF; X ENDIF; X pos := pos + 1; X ENDLOOP; X X pos := INDEX (new_pat, "&"); X LOOP X EXITIF (pos = 0) OR (pos > LENGTH (new_pat)); X IF (SUBSTR (new_pat, pos, 3) = '&""') AND X (SUBSTR (new_pat, pos, 5) <> '&""""') THEN X new_pat := SUBSTR (new_pat, 1, pos-1) + X SUBSTR (new_pat, pos+3, 255); X ELSE X IF SUBSTR (new_pat, pos, 2) = '&@' THEN X new_pat := SUBSTR (new_pat, 1, pos-1) + X SUBSTR (new_pat, pos+1, 255); X ENDIF; X ENDIF; X pos := pos + 1; X ENDLOOP; X X RETURN (new_pat); XENDPROCEDURE; X`012 X! X! X! XPROCEDURE eve$do_substitution (source, dest) X X LOCAL X cur_char, X result, X idx; X X idx := 0; X result := ""; X X LOOP X EXITIF (idx > LENGTH(dest)); X X cur_char := SUBSTR (dest, idx, 1); X IF (cur_char = "&") THEN X result := result + source; X idx := idx + 1; X ELSE X IF (cur_char = '\') THEN X cur_char := SUBSTR(dest, idx+1, 1); X IF (INDEX (eve$x_digit_characters, cur_char) > 0) THEN X EXECUTE (COMPILE ("eve$x_glo_str := SUBSTR (p" + X cur_char +", LENGTH (o"+cur_char+")+1,512);")); X result := result + eve$x_glo_str; X ELSE X result := result + "\" + cur_char; X ENDIF; X idx := idx + 2; X ELSE X result := result + cur_char; X idx := idx + 1; X ENDIF; X ENDIF; X ENDLOOP; X X RETURN (result); XENDPROCEDURE; X`012 X! X! Search and replace procedure. Case-sensitivity of search is X! same as for the find command. If case-insensitive, replacements X! are done to match case of current occurrence. X! X! Parameters: X! X! replace_parameter_1 Old string - input X! replace_parameter_2 New string - input X XPROCEDURE eve_replace (replace_parameter_1, replace_parameter_2) X X LOCAL X replace_text, X source_text, X target, ! Local copy of replace_parameter_1 X replacement, ! Local copy of replace_parameter_2 X this_buffer, ! Current buffer X this_mode, ! Keyword for current mode X lowercase_target, ! Lowercase version of target string X lowercase_replacement, ! Lowercase version of replacement string X uppercase_target, ! Uppercase version of target string X uppercase_replacement, ! Uppercase version of replacement string X capital_target, ! Capitalized version of target string X capital_replacement, ! Capitalized version of replacement string X how_exact, ! Keyword to indicate case-sensitivity X replace_range, ! Range of current occurrence X highlight_range, ! Reverse-video version of replace_range X replace_action, ! String reply to prompt X action_length, ! Length of replace_action X asking, ! True unless "all" option has been chosen X this_occurrence, ! String of replace_range X occurences; X X this_buffer := CURRENT_BUFFER; X this_mode := GET_INFO (CURRENT_BUFFER, "MODE"); X SET (INSERT, this_buffer); X asking := 1; X X IF NOT (eve$prompt_string (replace_parameter_1, target, X "Old string: ", "No string to replace")) THEN X RETURN; X ENDIF; X X replacement := replace_parameter_2; X X IF replacement = eve$kt_null THEN X replacement := READ_LINE ("New string: "); ! empty string is ok here X ENDIF; X X lowercase_target := target; X X IF GET_INFO (lowercase_target, "TYPE") = STRING THEN X CHANGE_CASE (lowercase_target, LOWER); X ENDIF; X X lowercase_replacement := replacement; X CHANGE_CASE (lowercase_replacement, LOWER); X X IF (lowercase_target = target) AND X (lowercase_replacement = replacement) THEN X how_exact := NO_EXACT; X uppercase_target := target; X IF GET_INFO (uppercase_target, "TYPE") = STRING THEN X CHANGE_CASE (uppercase_target, UPPER); X ENDIF; X X capital_target := target; X X IF GET_INFO (capital_target, "TYPE") = STRING THEN X eve$capitalize_string (capital_target); X ENDIF; X X uppercase_replacement := replacement; X CHANGE_CASE (uppercase_replacement, UPPER); X capital_replacement := replacement; X eve$capitalize_string (capital_replacement); X ELSE X how_exact := EXACT; X ENDIF; X X occurrences := 0; X X LOOP X replace_range := eve$find (target, 1, 1, 1); X X EXITIF replace_range = 0; X highlight_range := X CREATE_RANGE (BEGINNING_OF (replace_range), X END_OF (replace_range), eve$x_highlighting); X POSITION (BEGINNING_OF (replace_range)); X UPDATE (CURRENT_WINDOW); X source_text := X CREATE_RANGE (BEGINNING_OF (replace_range), X END_OF (replace_range), NONE); X X source_text := SUBSTR (source_text, 1, LENGTH (source_text)); X X LOOP X IF asking THEN X replace_action := X READ_LINE ("Replace? Type yes, no, all, last, or quit: "); X CHANGE_CASE (replace_action, LOWER); X ELSE X replace_action := "yes"; X ENDIF; X X action_length := LENGTH (replace_action); X IF (replace_action = SUBSTR ("yes", 1, action_length)) OR X (replace_action = SUBSTR ("all", 1, action_length)) OR X (replace_action = SUBSTR ("last", 1, action_length)) OR X (action_length = 0) THEN X highlight_range := 0; X X IF how_exact = EXACT THEN X replace_text := eve$do_substitution ( X source_text, replacement); X ELSE X ! Make sure non-alphabetic target is replaced by lowercase X X IF this_occurrence = lowercase_target THEN X replace_text := eve$do_substitution ( X source_text, lowercase_replacement); X ELSE X IF this_occurrence = uppercase_target THEN X replace_text := eve$do_substitution ( X source_text, uppercase_replacement); X ELSE X IF this_occurrence = capital_target THEN X replace_text := eve$do_substitution ( X source_text, capital_replacement); X ELSE X replace_text := eve$do_substitution ( X source_text, lowercase_replacement); X ENDIF; X ENDIF; X ENDIF; X ENDIF; X this_occurrence := ERASE_CHARACTER (LENGTH (replace_range)); X COPY_TEXT (replace_text); X X IF CURRENT_DIRECTION = REVERSE THEN X MOVE_HORIZONTAL (- LENGTH (replace_text)); X ENDIF; X X occurrences := occurrences + 1; X UPDATE (current_window); X X IF (replace_action = SUBSTR ("all", 1, action_length)) AND X (action_length > 0) THEN X asking := 0; X MESSAGE ("Replacing all occurrences..."); X SET (SCREEN_UPDATE, OFF); X ENDIF; X EXITIF 1; X ELSE X IF (replace_action = SUBSTR ("no", 1, action_length)) OR X (replace_action = SUBSTR ("quit", 1, action_length)) THEN X highlight_range := 0; X IF CURRENT_DIRECTION = FORWARD THEN X POSITION (END_OF (replace_range)); X MOVE_HORIZONTAL (1); X ENDIF; X UPDATE (current_window); X EXITIF 1; X ENDIF; X ENDIF; X ENDLOOP; X X EXITIF (action_length > 0) AND X ((replace_action = SUBSTR ("quit", 1, action_length)) OR X (replace_action = SUBSTR ("last", 1, action_length))); X X ENDLOOP; X X SET (SCREEN_UPDATE, ON); X MESSAGE (FAO ("Replaced !SL occurrence!%S", occurrences)); X SET (this_mode, this_buffer); X XENDPROCEDURE; X X! X! Re and initialize some things. X! Xdefine_key ("eve_find ('',1)", pf1, " find", eve$x_vt100_keys); Xdefine_key ("eve_find ('',1)", e1, " find", eve$x_standard_keys); Xeve$arg2_find := eve$arg1_buffer; Xeve$x_orig_target := eve$kt_null; Xeve$x_paren_cnt := eve$kt_null; Xeve$x_find_pat := eve$kt_null; Xeve$x_glo_str := eve$kt_null; X Xeve$pch := ASCII(9); ! All printable characters. X Xi := 32; XLOOP X EXITIF (i > 255); X eve$pch := eve$pch + ASCII (i); X i := i + 1; XENDLOOP; $ GoSub Convert_File $ Exit