Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Extension languages

1 view
Skip to first unread message

c70:editor-people

unread,
Oct 11, 1982, 11:41:37 PM10/11/82
to
>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'
-------

c70:editor-people

unread,
Oct 11, 1982, 11:56:33 PM10/11/82
to
>From Margolin.Multics@MIT-MULTICS Wed Aug 25 02:57:45 1982
Remailed-date: 25 Aug 1982 0014-PDT
Remailed-from: J.Q. Johnson <Admin.JQJ at SU-SCORE>
Remailed-to: Editor People: ;

While you are comparing Teco and Pascal, how about considering a Lisp
version? Remember, Lisp interpreters are already known technology,
and much easier to implement than interpreters of strongly-typed
languages like Pascal. The Pascal version was very nice looking, but
can you read that into a buffer, make a minor modification, type
esc-^C, and then be executing the new version right in the same Emacs
invocation? Well, here's our code (Multics Emacs):

;;;
;;; Query replace by Carl Hoffman
;;;


(defcom query-replace
&arguments ((old &default
&eval (get-search-string "Query replace old string: "))
(new &prompt "Query replace new string: " NL))
(assert-minor-mode '|query replace|)
(if (not (forward-search old))
(minibuffer-print "No occurrences of old string found.")
else
(query-replace-execute old new)
(minibuffer-print "Done."))
(negate-minor-mode '|query replace|))

; This function does all of the work. When it is invoked, the point
; is to the right of the first occurrence of the old string.

(defun query-replace-execute (old new)
(catch (do-forever
(redisplay)
(query-replace-dispatch old new (get-char))
(if (not (forward-search old)) (stop-doing)))
done))

(defun query-replace-dispatch (old new response)
(do-forever
(cond ((= response #/,)
(query-replace-swap-strings old new)
(redisplay)
(stop-doing))
((= response #/ )
(query-replace-swap-strings old new)
(stop-doing)) ;don't redisplay 10/15/80
((or (= response #^M) ;return = 15
(= response 177)) ;rubout = 177
(stop-doing))
((= response #/!) ;! is replace to end
(query-replace-swap-strings old new)
(do-forever
(if (forward-search old) (query-replace-swap-strings old new)
else (throw t done))))
((= response #/.)
(query-replace-swap-strings old new)
(throw t done))
((or (= response #^G) (= response 33)) ;altmode
(throw t done))
((= response #^J)) ;newline = 12
(t (display-error-noabort "Unknown query replace response.")
(redisplay)))
(setq response (get-char))))

(defun query-replace-swap-strings (old new)
(with-mark m
(reverse-search old)
(without-saving (wipe-point-mark m))
(insert-string new)))

0 new messages