From: utzoo!decvax!harpo!npoiv!npois!ucbvax!ARPAVAX:UNKNOWN:C70:editor-people Newsgroups: fa.editor-p Title: Re: Extension languages Article-I.D.: ucb.1834 Posted: Tue Aug 24 19:16:35 1982 Received: Tue Oct 12 03:41:37 1982 >From JAY@USC-ECLC Tue Aug 24 04:18:51 1982 Verbosity and ease of use are at odds, and for simple hacks to a buffer TECO seams ideal, but an editor is NOT a simple hack. My argument is this: if you were supporting an editor which code would you rather have to work on? 1) Pascal PROCEDURE Query_Replace; VAR Target,Replacement : STRING; Done : BOOLEAN; S : STACK OF INTEGER; PROCEDURE Replace; BEGIN (* Replace *) Buffer.Point := Buffer.Point - Length(Target); Delete(Length(Target)); Insert(Replacement); END; (* Replace *) BEGIN (* Query_Replace *) Done := False; Get_String (TTY,'Target String :',Target); Get_String (TTY,'Replacement String :',Replacement); Initialize_Stack (S); WHILE (Not Done) And (Search(Target)) DO BEGIN Update_Screen; CASE Get_Char(TTY) OF ' ' : BEGIN (* Replace this one *) Push (S,Buffer.Point); (* Save this position *) Replace; END; '.' : BEGIN (* Replace this one and Quit *) Done := TRUE; Replace; END; '!' : BEGIN (* Replace all the rest *) Done := TRUE; REPEAT Replace; UNTIL (NOT Search(Target)); END; ',' : BEGIN (* Replace and pause *) Push (S,Buffer.Point); (* Save this position *) Replace; Update_Screen; Wait_For_A_Character; END; '^' : BEGIN (* Goto the previous occurence of Target *) Pop (S,Buffer.Point); END; Esc : BEGIN (* Quit *) Done := TRUE; END; Del : BEGIN (* Skip this one *) Push (S,Buffer.Point); (* Save this position *) END; C-R : BEGIN (* Recursive edit of the buffer *) Edit(Buffer); END; C-W : BEGIN (* Delete this one, Then recursive edit buffer *) Buffer.Point := Buffer.Point - Length (Target); Delete(Length(Target)) Edit(Buffer) END; OTHERS : BEGIN (* Error *) Ring_Bell; END; END; (* CASE *) END; (* WHILE *) END; (* Query_Replace *) or 2) Teco (This code actualy does a bit more) !Query Replace:! !C Replace string, asking about each occurrence. M-X Query replace$FOO$BAR displays each occurrence of FOO; you then type a character to say what to do. Space => replace it with BAR and show next FOO. Rubout => don't replace, but show next FOO. Comma => replace this FOO and show result, waiting for next command. ^ => return to site of previous FOO (actually, jump to mark). ^W => kill this FOO and enter recursive editing level. ^R => enter recursive editing level. ^L => redisplay screen. Exclamation mark => replace all remaining FOOs without asking. Period => replace this FOO and exit. Altmode => just exit. Any other character exits and is read again. To restart Query Replace after exit, use ^R Re-execute Mini or run the minibuffer with an argument. Numeric arg means only replace FOO when bounded on both sides by delimiter characters (according to syntax table). If Case Replace is nonzero, BAR will be capitalized or all caps if the FOO found was (but only if FOO is typed all lower case). The TECO expression 1,MM Query Replace$FOO$Commands$ executes Commands as TECO commands to perform the replacement. The commands should return a pair of values which delimit the range of the buffer changed. "H" is safe. To include Altmodes in the commands, quote them with ^]'s. The commands can use Q2 and Q4 without saving them.! !* The value upon exit is -1 if it is done, or non-negative if "any other" character was typed.! 1,f Replace:_$[..9 fq..9"e :i*String_to_replace_is_empty$fs err$' 1,f Replace_..9_with:_$[1 !* Get FOO in q0 and BAR in q1! q..9(]..9)[0 !* Keep FOO in Q..9 over F^K to minimize funarg problem.! 10f[%center$ [..j :i..j Query_Replace.__$ 0[..f [2 [4 [5 q1[3 "e !* Q3 gets either replace with BAR or execute BAR.! :i3 1$ fk$ 0u2 -1u4 !* Q4 gets index of first upper case letter in FOO.! fq0< %4:g0"u 0;' q4:g0"a %2'> !* Q2 gets >= 0 if FOO has any letters at all.! Q2"G %4-fq0"e !* If FOO contains letters but they are all lower case,! 0fo..qCase_Replace$"n !* maybe we should try to preserve case.! m.m &_Case_Replace$u3'''' "n :i33$$' !* Make sure user command string ends in altmode.! F0$:"L !* If FOO contains a ^], replace it by two of them.! f[b bind$ g0 j< :s$; i$> hx0 f]b bind$' !* Replace String calls us with an excl in FS REREAD$.! fs reread$-!"e fiw O Excl$' < :s0$"e -1' !* Find next FOO. Return -1 if no more FOOs.! ff&1"N 0,FKA"C !' !* Postcomma arg means delimiter must precede! 0,1A"C !'' !* and follow, or we don't replace it.! 0@v !* Display it.! .+fku5 !* Remember where it starts.! fs rgetty$"e 0tt' !* Make sure can see it on printing tty.! 0f[Helpmac$ @fi:fcu4 f]helpmac$ q4-!"e m3 !* Exclamation mark => replace all remaining FOOs.! !Excl! !* Come straight here, for Replace String.! < :s0$; ff&1"N 0,FKA"C !' !* Postcomma arg means delimiter must precede! 0,1A"C !'' !* and follow, or we don't replace it.! m3 > f -1' q4-,"e m3@V !* Comma => replace with BAR,! !Pause! 0@V @fi:fcu4 !* Display and read another character.! q4-.@; !* which we interpret normally, except that we have! q4-!"e o Excl$' q4fx_,$"g 127u4'' !* already replaced this FOO.! q4-."e m3f 0;' !* Period replaces like Space, then exits.! q4-f.L"e f+ fkc !' !* ^L clears screen and redisplays, showing same FOO.! q4-^"e w O Pause$' !* ^ => go back to previous occurrence and show.! q4-(33.fs ^r init$)@; !* If char would exit ^R, exit query replace.! q4-$@; !* Altmode also exits.! q4-f.W"e fkd 0 !' !* ^W kills the FOO and enters ^R.! q4-f.R"e 0 !' !* ^R enters ^R; on return, move on.! q4-4110."e ?u4' !* Help is like "?".! !* Commands below here set the mark.! q4-?"n q5:' !* except for "?", which is at the bottom for speed.! q4-32"e m3f !' !* If char is space, replace with BAR.! q4-127"e !' !* Rubout => don't replace, move to next FOO.! q4-?"e !* ? or Help requests help.! !<<<"! ft Space_=>_replace,_Rubout_=>_don't,_Comma_=>_replace_and_show, Period_replaces_once_and_exits,_!_replaces_all_the_rest, C-R_enters_editor_recursively,_C-W_does_so_after_killing_FOO, ^_returns_to_previous_locus,_?_gets_help,_C-L_redisplays, Altmode_exits,_anything_else_exits_and_is_reread. $ fs rgetty$"n ft Type_a_space_to_see_buffer_again. $ :fi-32"e fiw' 0u..h @v' fkc !' !* Give him another chance to answer for this occurrence.! q4fs reread$w 0 > !* Random char => exit and re-read it.! -1fs reread$w 0 For me the choice is simple and instant..... Pascal j' -------