perm filename EDITOR.S78[206,LSP]1 blob sn#345814
filedate 1978-04-03 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00004 PAGES
C REC PAGE DESCRIPTION
C00002 00002 .s(EDITOR,THE LISP EDITOR)
C00004 00003 .ss How to Use the LISP Editor.
C00027 00004 .ss Example session with the LISP Editor.
.s(EDITOR,THE LISP EDITOR)
The LISP Editor was written by R.P.Gabriel and T.Finin.
It is a structural editor that runs in the MACLISP interpreter.
You may edit functions that are currently defined or get a
function from a file to edit. Editing is done by manipulating
subexpressions of the defining expression for the function.
The editor knows about a top level expression and a current
expression (CE). Initially they are the same. The current
expression is a list.
You can change, add, or delete elements of the list,
move parentheses in and out to change the subexpression
structure, or change the CE by moving up, down or sideways
within the toplevel expression.
.ss How to Use the LISP Editor.
The following is taken from the online documentation of the
LISP editor at the Stanford University AI Lab.
The following is a very brief introduction to the use
of the LISP Editor.
Loading the Editor
------- --- ------
1). To run the LISP Editor, one simply types (EDIT)
or (EDIT FOO) to edit the in-core function "FOO" or
(EDIT FOO FOO BAR DSK (COM RPG)) to edit the function
"FOO" in file FOO.BAR in the directory of COM,RPG.
2). (EDIT) or (EDIT FOO) or (EDIT FOO FOO BAR) or (EDIT FOO
FOO BAR DSK (COM RPG)) can be done in LISP's that have
an autoload property for EDIT. Typing (EDIT) causes the
Editor to be initialized and entered. (EDIT1 <exp>) will make
<exp> the toplevel editable expression. (EDIT2 <var>) will
make (PROG2 (SETQ <var> <current value of var>) T) the
toplevel while (EDIT2 (GET <var> <indicator>)) will make it:
(DEFPROP <var> <value> <indicator>).
3). (EDITV <atom>) edits the value of <atom>; the editted expression
is actually (prog1 (setq <atom> <value of atom>) t).
4). (EDITP <atom> <prop>) edits the <prop> property of <atom>; the
actual editted expression is (defprop <atom> <value> <prop>).
How to Look at the Current Expression (CE)
--- -- ---- -- --- ------- ---------- --
P prints the CE using the current print depth
(sublist cutoff) and print length (length cutoff)
PP pretty-prints the entire CE
PS pretty-prints the CE using the print depth cutoff
W prints the "window" surrounding the CE. Thus if
window size is 2, it prints the 2 preceeding and 2 following
tokens around the CE, where "token" means expression or
changes the window size to n.
(PL n) changes the print length to n (initially 5)
(PD n) changes the print depth to n (initially 2)
Changing the CE
-------- --- --
(CR E1...En) changes the CE to E1...En (i.e. splices in
E1...En), and makes the CE E1.
(n E1...En) n>0, changes the n-th element of the CE to
(n E1...En) n<0 changes the n-th element of the CE from the
end to E1...En
(n) n>0 deletes the n-th element of the CE
(n) n<0, deletes the n-th element from the end
RI moves the right parenthesis in one expression
RO moves the right parenthesis out one expression
LI similar to RI
LO similar to RO
DELETE deletes the CE (if the CE is the toplevel
expression, the Editor assumes that the user
wants to edit a different function and requests:
(function name <file specifications>):
The answer can be of several forms; examples:
1) FOO - loads FOO from core
2) (FOO FOO BAR) - loads FOO from FOO.BAR
3) (FOO BAR DSK (COM RPG)) - loads FOO from FOO.BAR in
the directory of COM,RPG.
4) NEW - gives a fresh top-level expression
5) cntrl-G - quits back to the Editor command decoder
6) UNDO - <see below>.
Moving around within the Expression
------ ------ ------ --- ----------
n n>0 makes the new CE the n-th element of the CE
n n<0, makes the new CE the n-th element from the end
of the CE
↑ makes the CE the immediate parent of the CE
TOP makes the CE the toplevel expression
NX makes the CE the next one after the CE
BK makes the CE the one before the CE
MARK marks the current location so that it can be JUMPed
to by the command JUMP. Note: MARKing and JUMPing
is not guaranteed to work in all cases, since
modification of the thing being edited can render
the MARK meaningless.
JUMP jumps to the last MARKed location
UNMARK forgets where the last MARK was set (speeds
(A n E1...En) puts E1...En after the n-th element of the CE
(B n E1...En) puts E1...En before the n-th element of the CE
(AI E1...En) puts E1...En after the CE and makes E1 the new CE
(BI E1...En) puts E1...En before the CE and makes E1 the new CE
(R exp1 exp2) replaces all occurrences of exp1 with exp2 in the CE, viewed
as a list, returns nil? if no occurrences found
(TR exp1 exp2)replaces all occurrences of exp1 with exp2 in the CE, viewed
as a tree
Finding Expressions (i.e. changing the CE)
------- ----------- --- -------- --- --
(F pat) finds the next occurrence of pat, searching in
(BF pat) finds the next occurrence of pat, searching in
inverse print order
(F pat T) finds the next occurrence of pat but looks at the
topmost elements of the CE first (useful for
getting to PROG tags)
(BF pat T) similar to above
(F pat n) finds the n-th occurrence of pat
(BF pat n) similar to above
F finds the next occurrence of the last search
BF similar to above
Pat, as used above, can contain any of the following:
Element of pat What it matches
------- -- --- ---- -- -------
atom atoms EQ to it
list calls matcher recursively
? any atom or single list
(i.e. an s-expression)
?X any element; binds ?X to
whatever it matched
* any non-empty string of
*X matches as *, but binds *X to
the list of elements it matched
=?X whatever ?X matched last time
=*X whatever *X matched last time
(RESTRICT ? P1...Pn) any element satisfying the
($R ? P1...Pn) same as above.
(RESTRICT ?X P1...Pn) similar to above but binds ?X
to what it matched.
($R ?X P1...Pn) same as above.
Note: (A ?X IS A ?X) matches (a word is a word) but
not (a word is a sentence). Simlarly for (*X is a *X).
Invoking the Matcher
-------- --- -------
(MATCH pat) attempts to match pat against the CE
(MATCH pat var1 ... varn) attempts to match pat against the
CE while retaining the values of the
variables var1,..., varn. (E.g.
(MATCH (* *A *B ?A) *A ?A).
MATCH attempts to match the last pat against the
CE. Like F and BF above.
REMATCH attempts to get the next match of pat against
the CE. Usually this only makes sense if
pat contains some * variables.
(REMATCH var1 ... varn) rematches but will retain var1,...,varn.
Hairy Matching Uses
----- -------- ----
(PR pat) replaces the CE with the instantiation of
pat (substitutes the values of ?-variables
(PA n P1...Pn) similar to (A n E1...En)
(PB n P1...Pn) similar to (B n E1...En)
(PAI P1...Pn) similar to (AI E1...En)
(PRA exp1 pat) similar to (R exp1 exp2)
(TPRA exp1 pat) similar to (TR exp1 exp2)
(SAVE filename <optional ext>)saves the toplevel expression
in the file given by the file
specs (will create files not
[LSP is the default value for the extension.]
SAVE saves the toplevel expression
in the file last saved in. If
there was none, the file spec.
(REFILE FOO <file specs>) replaces the function FOO in
the file given by the file
specs with that found under
the "draft" property of FOO
where <file specs> is of the
form (file <optional ext>).
[NB: <file specs> is a 4-list (filename ext dev dir) or some
initial segment thereof. Thus calls to REFILE are different
in format from those to SAVE or EDIT]
(REFILE (FOO1...FOOn)<file specs>)
similar to above but refiles
(REFILE (FOO1...FOOn)<infile specs><outfile specs>)
(REFILE * <infile><optional outfile>) updates every function
in infile. Note that the
specs are as file specs in the
vanilla refile above.
similar to above but files the
result in the outfile
REMEMBER puts the toplevel expression
under the "draft" property
(preserves DEFUN format and
OK REMEMBER's and EVAL's the
(i.e. defines the function as
well as remembers it)
(COMMENT T) allows comments to be in the
toplevel expression (uses the
(COMMENT NIL) disables above
[note added by editor: if you have comments in your files, use
";;;" rather than ";" to flag them. Then the editor is less
likely to scramble them.]
The Undo Feature
--- ---- -------
The Editor allows the user to "undo" any editing he has
done. Thus if he has made a mistake or simply is
experimenting, he can invoke the undo feature to undo each
step. However the undoer requires a history of the edit to
be kept and so uses a lot of space. Be warned!
(UNDO T) enables undoing
(UNDO n) enables undoing with only the last undoable
commands being saved (initially 6.)
(UNDO NIL) disables undoing and flushes the undoqueue (the
UNDO undoes the last command. Successive UNDO's will
undo prior edit commands.
The following commands can be undone:
↑ TOP RI RO LI LO NX BK BF DELETE F OK REMEMBER (COMMENT
-) (A -) (B -) (R -) (PA -) (PB -) (PAI -) (PBI -) (PL -)
(PD -) (PRA -) (BF -) (F -) (CR -) (PR -) (AI -) (BI -)
(N -) (N) N (EDPROG -).
Exiting and Etc.
------- --- ---
EXIT exits the Editor (to the LISP toplevel)
(EDIT) gets you back to the Editor
(REMEDIT) flushes the Editor.
Any other command is handed to LISP to be EVAL'ed.
.ss Example session with the LISP Editor.
Here are some things you can do using the Editor feature of
LISP. The user types in lower case, LISP replys in upper case, ";;;"
flags a user comment, ";" a LISP comment.
;;;get the function gg from the file abc.def
(edit gg abc def)
← ;;; the "←" means you are in the editor
;;;pretty print the definition
(DEFUN GG (X) (COND ((ATOM X) X) (T (GG (CAR X)))))
← ;;;make gg return the right most atom instead of the left most
;;;first make (CAR X) the CE
4 3 2 2 p
;;;now change CAR to CDR
← (1 cdr)
;;;remember the new definition
;;;update the definition
← (refile gg (abc def))
updated functions are: GG
(ABC DEF DSK (4 1002))
;;;try out a newly defined function---fiddle
;;;note that you can evaluate expressions in the
;;;editor as if you were at the top level of LISP
← (fiddle 'x)
(X . X)
← (fiddle '(x.y))
SPEC PDL OVERFLOW
;;;oops must be a bug
← (edit fiddle)
(DEFUN FIDDLE (X)
(COND ((ATOM X) (DOUBLE X))
(T (FIDDLE (CONS (CDR X) (CAR X))))))
;;;hmmm better fix it
← 4 3 2 (1 cons) pp
(CONS (CONS (CDR X) (CAR X)))
← (2 (fiddle (cdr x)) (fiddle (car x)))
(CONS (FIDDLE #) (FIDDLE #))
;;;remember the new definition and
;;;redefine the function
← (fiddle 'x)
(X . X)
← (fiddle '(x.y))
((Y . Y) X . X)
;;; save it fiddle.lsp
← (save fiddle)
(DSK (4 1002))
;;; copy functions in abc.def into uvw.xyz updating any that the editor
;;;knows have been changed.
← (refile * (abc def) (uvw xyz))
updated functions are: GG GG DOUBLE DOUBLE
(UVW XYZ DSK (4 1002))
;;;abc.def is unchanged