|
|
BSD 4.3
CHAPTER 16
The LISP Editor
16.1. The Editors
It is quite possible to use VI, Emacs or other stan-
dard editors to edit your lisp programs, and many peo-
ple do just that. However there is a lisp structure
editor which is particularly good for the editing of
lisp programs, and operates in a rather different
fashion, namely within a lisp environment. applica-
tion. It is handy to know how to use it for fixing
problems without exiting from the lisp system (e.g.
from the debugger so you can continue to execute
rather than having to start over.) The editor is not
quite like the top-level and debugger, in that it
expects you to type editor commands to it. It will
not evaluate whatever you happen to type. (There is
an editor command to evaluate things, though.)
The editor is available (assuming your system is set
up correctly with a lisp library) by typing (load
'cmufncs) and (load 'cmuedit).
The most frequent use of the editor is to change
function definitions by starting the editor with one
of the commands described in section 16.14. (see
_e_d_i_t_f), values (_e_d_i_t_v), properties (_e_d_i_t_p), and
expressions (_e_d_i_t_e). The beginner is advised to
start with the following (very basic) commands: _o_k,
_u_n_d_o, _p, #, under which are explained two different
basic commands which start with numbers, and f.
This documentation, and the editor, were imported from
PDP-10 CMULisp by Don Cohen. PDP-10 CMULisp is based
on UCILisp, and the editor itself was derived from an
early version of Interlisp. Lars Ericson, the author
of this section, has provided this very concise sum-
mary. Tutorial examples and implementation details
may be found in the Interlisp Reference Manual, where
a similar editor is described.
9
9The LISP Editor 16-1
The LISP Editor 16-2
16.2. Scope of Attention
Attention-changing commands allow you to look at a
different part of a Lisp expression you are editing.
The sub-structure upon which the editor's attention is
centered is called "the current expression". Chang-
ing the current expression means shifting attention
and not actually modifying any structure.
____________________________________________________________
_S_C_O_P_E _O_F _A_T_T_E_N_T_I_O_N _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
_n (_n>_0) . Makes the nth element of the current expression be
the new current expression.
-_n (_n>_0). Makes the nth element from the end of the current
expression be the new current expression.
_0. Makes the next higher expression be the new correct
expression. If the intention is to go back to the next
higher left parenthesis, use the command !0.
_u_p . If a p command would cause the editor to type ...
before typing the current expression, (the current expres-
sion is a tail of the next higher expression) then has no
effect; else, up makes the old current expression the first
element in the new current expression.
!_0 . Goes back to the next higher left parenthesis.
^ . Makes the top level expression be the current expres-
sion.
_n_x . Makes the current expression be the next expression.
(_n_x _n) equivalent to n nx commands.
!_n_x . Makes current expression be the next expression at a
higher level. Goes through any number of right parentheses
to get to the next expression.
_b_k . Makes the current expression be the previous expres-
sion in the next higher expression.
(_n_t_h _n) _n>_0 . Makes the list starting with the nth element
of the current expression be the current expression.
(_n_t_h $) - _g_e_n_e_r_a_l_i_z_e_d _n_t_h _c_o_m_m_a_n_d. nth locates $, and then
backs up to the current level, where the new current expres-
sion is the tail whose first element contains, however dee-
ply, the expression that was the terminus of the location
operation.
Printed: July 21, 1983
The LISP Editor 16-3
:: . (pattern :: . $) e.g., (cond :: return). finds a
cond that contains a return, at any depth.
(_b_e_l_o_w _c_o_m _x) . The below command is useful for locating a
substructure by specifying something it contains. (below
cond) will cause the cond clause containing the current
expression to become the new current expression. Suppose
you are editing a list of lists, and want to find a sublist
that contains a foo (at any depth). Then simply executes f
foo (below ).
(_n_e_x _x) . same as (_b_e_l_o_w _x) followed by nx. For example,
if you are deep inside of a selectq clause, you can advance
to the next clause with (_n_e_x _s_e_l_e_c_t_q).
_n_e_x. The atomic form of _n_e_x is useful if you will be
performing repeated executions of (_n_e_x _x). By simply
marking the chain corresponding to x, you can use _n_e_x to
step through the sublists.
____________________________________________________________
16.3. Pattern Matching Commands
Many editor commands that search take patterns. A
pattern _p_a_t matches with x if:
____________________________________________________________
_P_A_T_T_E_R_N _S_P_E_C_I_F_I_C_A_T_I_O_N _S_U_M_M_A_R_Y
- _p_a_t is _e_q to x.
- _p_a_t is &.
- _p_a_t is a number and equal to x.
- if (car _p_a_t) is the atom *any*, (cdr _p_a_t) is a list of
patterns, and _p_a_t matches x if and only if one of the pat-
terns on (cdr _p_a_t) matches x.
- if _p_a_t is a literal atom or string, and (nthchar _p_a_t -1)
is @, then _p_a_t matches with any literal atom or string which
has the same initial characters as _p_a_t, e.g. ver@ matches
with verylongatom, as well as "verylongstring".
- if (car _p_a_t) is the atom --, _p_a_t matches x if (a) (cdr
_p_a_t)=nil, i.e. _p_a_t=(--), e.g., (a --) matches (a) (a b c)
and (a . b) in other words, -- can match any tail of a
list. (b) (cdr _p_a_t) matches with some tail of x, e.g. (a
Printed: July 21, 1983
The LISP Editor 16-4
-- (&)) will match with (a b c (d)), but not (a b c d), or
(a b c (d) e). however, note that (a -- (&) --) will match
with (a b c (d) e). in other words, -- will match any inte-
rior segment of a list.
- if (car _p_a_t) is the atom ==, _p_a_t matches x if and only if
(cdr _p_a_t) is _e_q to x. (this pattern is for use by programs
that call the editor as a subroutine, since any non-atomic
expression in a command typed in by the user obviously can-
not be _e_q to existing structure.) - otherwise if x is a
list, _p_a_t matches x if (car _p_a_t) matches (car x), and (cdr
_p_a_t) matches (cdr x).
- when searching, the pattern matching routine is called
only to match with elements in the structure, unless the
pattern begins with :::, in which case cdr of the pattern is
matched against tails in the structure. (in this case, the
tail does not have to be a proper tail, e.g. (::: a --)
will match with the element (a b c) as well as with cdr of
(x a b c), since (a b c) is a tail of (a b c).)
____________________________________________________________
16.3.1. Commands That Search
____________________________________________________________
_S_E_A_R_C_H _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
_f _p_a_t_t_e_r_n . f informs the editor that the next command is
to be interpreted as a pattern. If no pattern is given on
the same line as the f then the last pattern is used. f
pattern means find the next instance of pattern.
(_f _p_a_t_t_e_r_n _n). Finds the next instance of pattern.
(_f _p_a_t_t_e_r_n _t). similar to f pattern, except, for example,
if the current expression is (cond ..), f cond will look for
the next cond, but (f cond t) will 'stay here'.
(_f _p_a_t_t_e_r_n _n) _n>_0. Finds the nth place that pattern
matches. If the current expression is (foo1 foo2 foo3), (f
f00@ 3) will find foo3.
(_f _p_a_t_t_e_r_n) _o_r (_f _p_a_t_t_e_r_n _n_i_l). only matches with elements
at the top level of the current expression. If the current
expression is (_p_r_o_g _n_i_l (_s_e_t_q _x (_c_o_n_d & &)) (_c_o_n_d &) ...) f
(cond --) will find the cond inside the setq, whereas (f
(cond --)) will find the top level cond, i.e., the second
one.
Printed: July 21, 1983
The LISP Editor 16-5
(_s_e_c_o_n_d . $) . same as (lc . $) followed by another (lc .
$) except that if the first succeeds and second fails, no
change is made to the edit chain.
(_t_h_i_r_d . $) . Similar to second.
(_f_s _p_a_t_t_e_r_n_1 ... _p_a_t_t_e_r_n_n) . equivalent to f pattern1 fol-
lowed by f pattern2 ... followed by f pattern n, so that if
f pattern m fails, edit chain is left at place pattern m-1
matched.
(_f= _e_x_p_r_e_s_s_i_o_n _x) . Searches for a structure eq to expres-
sion.
(_o_r_f _p_a_t_t_e_r_n_1 ... _p_a_t_t_e_r_n_n) . Searches for an expression
that is matched by either pattern1 or ... patternn.
_b_f _p_a_t_t_e_r_n . backwards find. If the current expression is
(_p_r_o_g _n_i_l (_s_e_t_q _x (_s_e_t_q _y (_l_i_s_t _z))) (_c_o_n_d ((_s_e_t_q _w --) --))
--) f list followed by bf setq will leave the current
expression as (setq y (list z)), as will f cond followed by
bf setq
(_b_f _p_a_t_t_e_r_n _t). backwards find. Search always includes
current expression, i.e., starts at end of current expres-
sion and works backward, then ascends and backs up, etc.
____________________________________________________________
16.3.1.1. Location Specifications Many editor
commands use a method of specifying position
called a location specification. The meta-
symbol $ is used to denote a location specifica-
tion. $ is a list of commands interpreted as
described above. $ can also be atomic, in which
case it is interpreted as (list $). a location
specification is a list of edit commands that
are executed in the normal fashion with two
exceptions. first, all commands not recognized
by the editor are interpreted as though they had
been preceded by f. The location specification
(cond 2 3) specifies the 3rd element in the
first clause of the next cond.
the if command and the ## function provide a way
of using in location specifications arbitrary
predicates applied to elements in the current
expression.
In insert, delete, replace and change, if $ is
Printed: July 21, 1983
The LISP Editor 16-6
nil (empty), the corresponding operation is per-
formed on the current edit chain, i.e. (replace
with (car x)) is equivalent to (:(car x)). for
added readability, here is also permitted, e.g.,
(insert (print x) before here) will insert
(print x) before the current expression (but not
change the edit chain). It is perfectly legal
to ascend to insert, replace, or delete. for
example (insert (_r_e_t_u_r_n) after ^ prog -1) will
go to the top, find the first prog, and insert a
(_r_e_t_u_r_n) at its end, and not change the current
edit chain.
The a, b, and : commands all make special
checks in e1 thru em for expressions of the form
(## . coms). In this case, the expression used
for inserting or replacing is a copy of the
current expression after executing coms, a list
of edit commands. (insert (## f cond -1 -1)
after3) will make a copy of the last form in
the last clause of the next cond, and insert it
after the third element of the current expres-
sion.
$. In descriptions of the editor, the meta-
symbol $ is used to denote a location specifica-
tion. $ is a list of commands interpreted as
described above. $ can also be atomic.
____________________________________________________________
_L_O_C_A_T_I_O_N _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
(_l_c . $) . Provides a way of explicitly invoking the loca-
tion operation. (lc cond 2 3) will perform search.
(_l_c_l . $) . Same as lc except search is confined to current
expression. To find a cond containing a _r_e_t_u_r_n, one might
use the location specification (cond (lcl _r_e_t_u_r_n) ) where
the would reverse the effects of the lcl command, and make
the final current expression be the cond.
____________________________________________________________
16.3.2. The Edit Chain The edit-chain is a list of
which the first element is the the one you are now
editing ("current expression"), the next element is
what would become the current expression if you
were to do a 0, etc., until the last element which
is the expression that was passed to the editor.
Printed: July 21, 1983
The LISP Editor 16-7
____________________________________________________________
_E_D_I_T _C_H_A_I_N _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
_m_a_r_k . Adds the current edit chain to the front of the list
marklst.
_ . Makes the new edit chain be (car marklst).
(_ _p_a_t_t_e_r_n) . Ascends the edit chain looking for a link
which matches pattern. for example:
__ . Similar to _ but also erases the mark.
\ . Makes the edit chain be the value of unfind. unfind is
set to the current edit chain by each command that makes a
"big jump", i.e., a command that usually performs more than
a single ascent or descent, namely ^, _, __, !nx, all com-
mands that involve a search, e.g., f, lc, ::, below, et al
and and themselves.
if the user types f cond, and then f car, would take him
back to the cond. another would take him back to the car,
etc.
\_p . Restores the edit chain to its state as of the last
print operation. If the edit chain has not changed since
the last printing, \p restores it to its state as of the
printing before that one. If the user types p followed by 3
2 1 p, \p will return to the first p, i.e., would be
equivalent to 0 0 0. Another \p would then take him back to
the second p.
____________________________________________________________
16.4. Printing Commands
____________________________________________________________
_P_R_I_N_T_I_N_G _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
_p Prints current expression in abbreviated form. (p m)
prints mth element of current expression in abbreviated
form. (p m n) prints mth element of current expression as
though printlev were given a depth of n. (p 0 n) prints
current expression as though printlev were given a depth of
n. (p cond 3) will work.
? . prints the current expression as though printlev were
given a depth of 100.
9
9 Printed: July 21, 1983
The LISP Editor 16-8
_p_p . pretty-prints the current expression.
_p_p*. is like pp, but forces comments to be shown.
____________________________________________________________
16.5. Structure Modification Commands
All structure modification commands are undoable. See
_u_n_d_o.
____________________________________________________________
_S_T_R_U_C_T_U_R_E _M_O_D_I_F_I_C_A_T_I_O_N _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
# [_e_d_i_t_o_r _c_o_m_m_a_n_d_s] (n) n>1 deletes the corresponding ele-
ment from the current expression.
(_n _e_1 ... _e_m) _n,_m>_1 replaces the nth element in the current
expression with e1 ... em.
(-_n _e_1 ... _e_m) _n,_m>_1 inserts e1 ... em before the n ele-
ment in the current expression.
(_n _e_1 ... _e_m) (the letter "n" for "next" or "nconc", not a
number) m>1 attaches e1 ... em at the end of the current
expression.
(_a _e_1 ... _e_m) . inserts e1 ... em after the current
expression (or after its first element if it is a tail).
(_b _e_1 ... _e_m) . inserts e1 ... em before the current
expression. to insert foo before the last element in the
current expression, perform -1 and then (b foo).
(: _e_1 ... _e_m) . replaces the current expression by e1 ...
em. If the current expression is a tail then replace its
first element.
_d_e_l_e_t_e _o_r (:) . deletes the current expression, or if the
current expression is a tail, deletes its first element.
(_d_e_l_e_t_e . $). does a (lc . $) followed by delete. current
edit chain is not changed.
(_i_n_s_e_r_t _e_1 ... _e_m _b_e_f_o_r_e . $) . similar to (lc. $) fol-
lowed by (b e1 ... em).
(_i_n_s_e_r_t _e_1 ... _e_m _a_f_t_e_r . $). similar to insert before
Printed: July 21, 1983
The LISP Editor 16-9
except uses a instead of b.
(_i_n_s_e_r_t _e_1 ... _e_m _f_o_r . $). similar to insert before
except uses : for b.
(_r_e_p_l_a_c_e $ _w_i_t_h _e_1 ... _e_m) . here $ is the segment of the
command between replace and with.
(_c_h_a_n_g_e $ _t_o _e_1 ... _e_m) . same as replace with.
____________________________________________________________
16.6. Extraction and Embedding Commands
____________________________________________________________
_E_X_T_R_A_C_T_I_O_N _A_N_D _E_M_B_E_D_D_I_N_G _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
(_x_t_r . $) . replaces the original current expression with
the expression that is current after performing (lcl . $).
(_m_b_d _x) . x is a list, substitutes the current expression
for all instances of the atom * in x, and replaces the
current expression with the result of that substitution.
(mbd x) : x atomic, same as (mbd (x *)).
(_e_x_t_r_a_c_t $_1 _f_r_o_m $_2) . extract is an editor command which
replaces the current expression with one of its subexpres-
sions (from any depth). ($1 is the segment between extract
and from.) example: if the current expression is (print
(cond ((null x) y) (t z))) then following (extract y from
cond), the current expression will be (print y). (extract 2
-1 from cond), (extract y from 2), (extract 2 -1 from 2)
will all produce the same result.
(_e_m_b_e_d $ _i_n . _x) . embed replaces the current expression
with a new expression which contains it as a subexpression.
($ is the segment between embed and in.) example: (embed
print in setq x), (embed 3 2 in _r_e_t_u_r_n), (embed cond 3 1 in
(or * (null x))).
____________________________________________________________
16.7. Move and Copy Commands
9
9 Printed: July 21, 1983
The LISP Editor 16-10
____________________________________________________________
_M_O_V_E _A_N_D _C_O_P_Y _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
(_m_o_v_e $_1 _t_o _c_o_m . $_2) . ($1 is the segment between move and
to.) where com is before, after, or the name of a list com-
mand, e.g., :, n, etc. If $2 is nil, or (here), the current
position specifies where the operation is to take place. If
$1 is nil, the move command allows the user to specify some
place the current expression is to be moved to. if the
current expression is (a b d c), (move 2 to after 4) will
make the new current expression be (a c d b).
(_m_v _c_o_m . $) . is the same as (move here to com . $).
(_c_o_p_y $_1 _t_o _c_o_m . $_2) is like move except that the source
expression is not deleted.
(_c_p _c_o_m . $). is like mv except that the source expression
is not deleted.
____________________________________________________________
16.8. Parentheses Moving Commands The commands
presented in this section permit modification of the
list structure itself, as opposed to modifying com-
ponents thereof. their effect can be described as
inserting or removing a single left or right
parenthesis, or pair of left and right parentheses.
____________________________________________________________
_P_A_R_E_N_T_H_E_S_E_S _M_O_V_I_N_G _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
(_b_i _n _m) . both in. inserts parentheses before the nth
element and after the mth element in the current expression.
example: if the current expression is (a b (c d e) f g),
then (bi 2 4) will modify it to be (a (b (c d e) f) g). (bi
n) : same as (bi n n). example: if the current expression
is (a b (c d e) f g), then (bi -2) will modify it to be (a b
(c d e) (f) g).
(_b_o _n) . both out. removes both parentheses from the nth
element. example: if the current expression is (a b (c d
e) f g), then (bo d) will modify it to be (a b c d e f g).
(_l_i _n) . left in. inserts a left parenthesis before the
nth element (and a matching right parenthesis at the end of
the current expression). example: if the current expres-
sion is (a b (c d e) f g), then (li 2) will modify it to be
Printed: July 21, 1983
The LISP Editor 16-11
(a (b (c d e) f g)).
(_l_o _n) . left out. removes a left parenthesis from the
nth element. all elements following the nth element are
deleted. example: if the current expression is (a b (c d e)
f g), then (lo 3) will modify it to be (a b c d e).
(_r_i _n _m) . right in. move the right parenthesis at the
end of the nth element in to after the mth element. inserts
a right parenthesis after the mth element of the nth ele-
ment. The rest of the nth element is brought up to the
level of the current expression. example: if the current
expression is (a (b c d e) f g), (ri 2 2) will modify it to
be (a (b c) d e f g).
(_r_o _n) . right out. move the right parenthesis at the end
of the nth element out to the end of the current expres-
sion. removes the right parenthesis from the nth element,
moving it to the end of the current expression. all elements
following the nth element are moved inside of the nth
element. example: if the current expression is (a b (c d e)
f g), (ro 3) will modify it to be (a b (c d e f g)).
(_r _x _y) replaces all instances of x by y in the current
expression, e.g., (r caadr cadar). x can be the s-
expression (or atom) to be substituted for, or can be a pat-
tern which specifies that s-expression (or atom).
(_s_w _n _m) switches the nth and mth elements of the current
expression. for example, if the current expression is (list
(cons (car x) (car y)) (cons (cdr y))), (sw 2 3) will
modify it to be (list (cons (cdr x) (cdr y)) (cons (car x)
(car y))). (sw car cdr) would produce the same result.
____________________________________________________________
16.8.1. Using to and thru
to, thru, extract, embed, delete, replace, and move
can be made to operate on several contiguous ele-
ments, i.e., a segment of a list, by using the to
or thru command in their respective location
specifications. thru and to are intended to be
used in conjunction with extract, embed, delete,
replace, and move. to and thru can also be used
directly with xtr (which takes after a location
specification), as in (xtr (2 thru 4)) (from the
current expression).
9
9 Printed: July 21, 1983
The LISP Editor 16-12
____________________________________________________________
_T_O _A_N_D _T_H_R_U _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
($_1 _t_o $_2) . same as thru except last element not
included.
($_1 _t_o). same as ($1 thru -1)
($_1 _t_h_r_u $_2) . If the current expression is (a (b (c d)
(e) (f g h) i) j k), following (c thru g), the current
expression will be ((c d) (e) (f g h)). If both $1 and $2
are numbers, and $2 is greater than $1, then $2 counts from
the beginning of the current expression, the same as $1. in
other words, if the current expression is (a b c d e f g),
(3 thru 4) means (c thru d), not (c thru f). in this case,
the corresponding bi command is (bi 1 $2-$1+1).
($_1 _t_h_r_u). same as ($_1 _t_h_r_u -_1).
____________________________________________________________
16.9. Undoing Commands each command that causes struc-
ture modification automatically adds an entry to the
front of undolst containing the information required
to restore all pointers that were changed by the com-
mand. The undo command undoes the last, i.e., most
recent such command.
____________________________________________________________
_U_N_D_O _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
_u_n_d_o . the undo command undoes most recent, structure
modification command that has not yet been undone, and
prints the name of that command, e.g., mbd undone. The edit
chain is then exactly what it was before the 'undone' com-
mand had been performed.
!_u_n_d_o . undoes all modifications performed during this
editing session, i.e., this call to the editor.
_u_n_b_l_o_c_k . removes an undo-block. If executed at a non-
blocked state, i.e., if undo or !undo could operate, types
not blocked.
_t_e_s_t . adds an undo-block at the front of undolst. note
that test together with !undo provide a 'tentative'
mode for editing, i.e., the user can perform a number of
changes, and then undo all of them with a single !undo
Printed: July 21, 1983
The LISP Editor 16-13
command.
_u_n_d_o_l_s_t [_v_a_l_u_e]. each editor command that causes structure
modification automatically adds an entry to the front of
undolst containing the information required to restore all
pointers that were changed by the command.
?? prints the entries on undolst. The entries are listed
most recent entry first.
____________________________________________________________
16.10. Commands that Evaluate
____________________________________________________________
_E_V_A_L_U_A_T_I_O_N _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
_e . only when typed in, (i.e., (insert d before e) will
treat e as a pattern) causes the editor to call the
lisp interpreter giving it the next input as argument.
(_e _x) evaluates x, and prints the result. (e x t) same
as (e x) but does not print.
(_i _c _x_1 ... _x_n) same as (c y1 ... yn) where yi=(eval xi).
example: (i 3 (cdr foo)) will replace the 3rd element of
the current expression with the cdr of the value of foo. (i
n foo (car fie)) will attach the value of foo and car of the
value of fie to the end of the current expression. (i f=
foo t) will search for an expression eq to the value of foo.
If c is not an atom, it is evaluated as well.
(_c_o_m_s _x_1 ... _x_n) . each xi is evaluated and its value
executed as a command. The i command is not very convenient
for computing an entire edit command for execution, since
it computes the command name and its arguments separately.
also, the i command cannot be used to compute an atomic
command. The coms and comsq commands provide more gen-
eral ways of computing commands. (coms (cond (x (list 1
x)))) will replace the first element of the current expres-
sion with the value of x if non-nil, otherwise do nothing.
(nil as a command is a nop.)
(_c_o_m_s_q _c_o_m_1 ... _c_o_m_n) . executes com1 ... comn. comsq is
mainly useful in conjunction with the coms command. for
example, suppose the user wishes to compute an entire list
of commands for evaluation, as opposed to computing each
command one at a time as does the coms command. he would
then write (coms (cons (quote comsq) x)) where x computed
Printed: July 21, 1983
The LISP Editor 16-14
the list of commands, e.g., (coms (cons (quote comsq)
(get foo (quote commands))))
____________________________________________________________
16.11. Commands that Test
____________________________________________________________
_T_E_S_T_I_N_G _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
(_i_f _x) generates an error unless the value of (eval x) is
non-nil, i.e., if (eval x) causes an error or (eval x)=nil,
if will cause an error. (if x coms1 coms2) if (eval x) is
non-nil, execute coms1; if (eval x) causes an error or is
equal to nil, execute coms2. (if x coms1) if (eval x)
is non-nil, execute coms1; otherwise generate an error.
(_l_p . _c_o_m_s) . repeatedly executes coms, a list of commands,
until an error occurs. (lp f print (n t)) will
attach a t at the end of every print expression. (lp f
print (if (## 3) nil ((n t)))) will attach a t at the end
of each print expression which does not already have a
second argument. (i.e. the form (## 3) will cause an
error if the edit command 3 causes an error, thereby select-
ing ((n t)) as the list of commands to be executed. The if
could also be written as (if (cddr (##)) nil ((n t))).).
(_l_p_q . _c_o_m_s) same as lp but does not print n occurrences.
(_o_r_r _c_o_m_s_1 ... _c_o_m_s_n) . orr begins by executing coms1, a
list of commands. If no error occurs, orr is finished.
otherwise, orr restores the edit chain to its original
value, and continues by executing coms2, etc. If none of
the command lists execute without errors, i.e., the orr
"drops off the end", orr generates an error. otherwise, the
edit chain is left as of the completion of the first command
list which executes without error.
____________________________________________________________
16.12. Editor Macros
Many of the more sophisticated branching commands in
the editor, such as orr, if, etc., are most often
used in conjunction with edit macros. The macro
feature permits the user to define new commands and
Printed: July 21, 1983
The LISP Editor 16-15
thereby expand the editor's repertoire. (however,
built in commands always take precedence over mac-
ros, i.e., the editor's repertoire can be expanded,
but not modified.) macros are defined by using the m
command.
(_m _c . _c_o_m_s) for c an atom, m defines c as an atomic
command. (if a macro is redefined, its new defini-
tion replaces its old.) executing c is then the same
as executing the list of commands coms. macros
can also define list commands, i.e., commands that
take arguments. (m (c) (arg[1] ... arg[n]) . coms) c
an atom. m defines c as a list command. executing (c
e1 ... en) is then performed by substituting e1
for arg[1], ... en for arg[n] throughout coms,
and then executing coms. a list command can be
defined via a macro so as to take a fixed or
indefinite number of 'arguments'. The form given
above specified a macro with a fixed number of argu-
ments, as indicated by its argument list. if the of
arguments. (m (c) args . coms) c, args both atoms,
defines c as a list command. executing (c e1 ...
en) is performed by substituting (e1 ... en), i.e.,
cdr of the command, for args throughout coms, and then
executing coms.
(m bp bk up p) will define bp as an atomic command
which does three things, a bk, an up, and a p. note
that macros can use commands defined by macros as well
as built in commands in their definitions. for
example, suppose z is defined by (m z -1 (if (null
(##)) nil (p))), i.e. z does a -1, and then if the
current expression is not nil, a p. now we can define
zz by (m zz -1 z), and zzz by (m zzz -1 -1 z) or (m
zzz -1 zz). we could define a more general bp by (m
(bp) (n) (bk n) up p). (bp 3) would perform (bk
3), followed by an up, followed by a p. The com-
mand second can be defined as a macro by (m (2nd) x
(orr ((lc . x) (lc . x)))).
Note that for all editor commands, 'built in' com-
mands as well as commands defined by macros, atomic
definitions and list definitions are completely
independent. in other words, the existence of an
atomic definition for c in no way affects the treat-
ment of c when it appears as car of a list command,
and the existence of a list definition for c in no way
affects the treatment of c when it appears as an
atom. in particular, c can be used as the name of
either an atomic command, or a list command, or both.
in the latter case, two entirely different defini-
tions can be used. note also that once c is
defined as an atomic command via a macro definition,
Printed: July 21, 1983
The LISP Editor 16-16
it will not be searched for when used in a location
specification, unless c is preceded by an f. (insert
-- before bp) would not search for bp, but instead
perform a bk, an up, and a p, and then do the inser-
tion. The corresponding also holds true for list com-
mands.
(_b_i_n_d . _c_o_m_s) bind is an edit command which is
useful mainly in macros. it binds three dummy vari-
ables #1, #2, #3, (initialized to nil), and then exe-
cutes the edit commands coms. note that these
bindings are only in effect while the commands are
being executed, and that bind can be used recursively;
it will rebind #1, #2, and #3 each time it is
invoked.
_u_s_e_r_m_a_c_r_o_s [_v_a_l_u_e]. this variable contains the
users editing macros . if you want to save your mac-
ros then you should save usermacros. you should
probably also save editcomsl.
_e_d_i_t_c_o_m_s_l [_v_a_l_u_e]. editcomsl is the list of "list
commands" recognized by the editor. (these are the
ones of the form (command arg1 arg2 ...).)
16.13. Miscellaneous Editor Commands
____________________________________________________________
_M_I_S_C_E_L_L_A_N_E_O_U_S _E_D_I_T_O_R _C_O_M_M_A_N_D _S_U_M_M_A_R_Y
_o_k . Exits from the editor.
_n_i_l . Unless preceded by f or bf, is always a null opera-
tion.
_t_t_y: . Calls the editor recursively. The user can then
type in commands, and have them executed. The tty: command
is completed when the user exits from the lower editor
(with ok or stop). the tty: command is extremely use-
ful. it enables the user to set up a complex operation,
and perform interactive attention-changing commands part
way through it. for example the command (move 3 to after
cond 3 p tty:) allows the user to interact, in effect,
within the move command. he can verify for himself
that the correct location has been found, or complete the
specification "by hand". in effect, tty: says "I'll tell you
what you should do when you get there."
_s_t_o_p . exits from the editor with an error. mainly for use
Printed: July 21, 1983
The LISP Editor 16-17
in conjunction with tty: commands that the user wants to
abort. since all of the commands in the editor are errset
protected, the user must exit from the editor via a command.
stop provides a way of distinguishing between a successful
and unsuccessful (from the user's standpoint) editing ses-
sion.
_t_l . tl calls (top-level). to return to the editor just
use the _r_e_t_u_r_n top-level command.
_r_e_p_a_c_k . permits the 'editing' of an atom or string.
(_r_e_p_a_c_k $) does (lc . $) followed by repack, e.g. (repack
this@).
(_m_a_k_e_f_n _f_o_r_m _a_r_g_s _n _m) . makes (car form) an expr with the
nth through mth elements of the current expression with
each occurrence of an element of (cdr form) replaced by
the corresponding element of args. The nth through mth
elements are replaced by form.
(_m_a_k_e_f_n _f_o_r_m _a_r_g_s _n). same as (makefn form args n n).
(_s _v_a_r . $) . sets var (using setq) to the current expres-
sion after performing (lc . $). (s foo) will set
foo to the current expression, (s foo -1 1) will set foo to
the first element in the last element of the current expres-
sion.
____________________________________________________________
16.14. Editor Functions
(editf s_x1 ...)
SIDE EFFECT: edits a function. s_x1 is the name of the
function, any additional arguments are an
optional list of commands.
RETURNS: s_x1.
NOTE: if s_x1 is not an editable function, editf gen-
erates an fn not editable error.
9
9 Printed: July 21, 1983
The LISP Editor 16-18
(edite l_expr l_coms s_atm))
edits an expression. its value is the last element of
(editl (list l_expr) l_coms s_atm nil nil).
(editracefn s_com)
is available to help the user debug complex edit macros, or
subroutine calls to the editor. editracefn is to be
defined by the user. whenever the value of editracefn is
non-nil, the editor calls the function editracefn
before executing each command (at any level), giving it
that command as its argument. editracefn is initially equal
to nil, and undefined.
(editv s_var [ g_com1 ... ])
SIDE EFFECT: similar to editf, for editing values.
editv sets the variable to the value
returned.
RETURNS: the name of the variable whose value was
edited.
(editp s_x)
SIDE EFFECT: similar to editf for editing property
lists. used if x is nil.
RETURNS: the atom whose property list was edited.
(editl coms atm marklst mess)
SIDE EFFECT: editl is the editor. its first argument
is the edit chain, and its value is an
edit chain, namely the value of l at the
time editl is exited. (l is a special
variable, and so can be examined or set by
edit commands. ^ is equivalent to (e
(setq l(last l)) t).) coms is an optional
list of commands. for interactive edit-
ing, coms is nil. in this case, editl
types edit and then waits for input from
the teletype. (if mess is not nil editl
types it instead of edit. for example,
the tty: command is essentially (setq l
(editl l nil nil nil (quote tty:))).)
exit occurs only via an ok, stop, or save
command. If coms is not nil, no message
is typed, and each member of coms is
treated as a command and executed. If an
Printed: July 21, 1983
The LISP Editor 16-19
error occurs in the execution of one of
the commands, no error message is printed
, the rest of the commands are ignored,
and editl exits with an error, i.e., the
effect is the same as though a stop com-
mand had been executed. If all commands
execute successfully, editl returns the
current value of l. marklst is the list
of marks. on calls from editf, atm is the
name of the function being edited; on
calls from editv, the name of the vari-
able, and calls from editp, the atom of
which some property of its property list
is being edited. The property list of atm
is used by the save command for saving the
state of the edit. save will not save
anything if atm=nil i.e., when editing
arbitrary expressions via edite or editl
directly.
(editfns s_x [ g_coms1 ... ])
fsubr function, used to perform the same editing operations
on several functions. editfns maps down the list of func-
tions, prints the name of each function, and calls the edi-
tor (via editf) on that function.
EXAMPLE: editfns foofns (r fie fum)) will change every
fie to fum in each of the functions on
foofns.
NOTE: the call to the editor is errset protected,
so that if the editing of one function causes an
error, editfns will proceed to the next func-
tion. in the above example, if one of the
functions did not contain a fie, the r command
would cause an error, but editing would con-
tinue with the next function. The value of
editfns is nil.
(edit4e pat y)
SIDE EFFECT: is the pattern match routine.
RETURNS: t if pat matches y. see edit-match for defini-
tion of 'match'.
NOTE: before each search operation in the editor
begins, the entire pattern is scanned for
atoms or strings that end in at-signs. These
are replaced by patterns of the form (cons
(quote /@) (explodec atom)). from the
Printed: July 21, 1983
The LISP Editor 16-20
standpoint of edit4e, pattern type 5, atoms or
strings ending in at-signs, is really "if
car[pat] is the atom @ (at-sign), pat will match
with any literal atom or string whose ini-
tial character codes (up to the @) are the same
as those in cdr[pat]." if the user wishes to
call edit4e directly, he must therefore convert
any patterns which contain atoms or strings
ending in at-signs to the form recognized by
edit4e. this can be done via the function
editfpat.
(editfpat pat flg)
makes a copy of pat with all patterns of type 5 (see edit-
match) converted to the form expected by edit4e. flg should
be passed as nil (flg=t is for internal use by the editor).
(editfindp x pat flg)
NOTE: Allows a program to use the edit find command as
a pure predicate from outside the editor. x is
an expression, pat a pattern. The value of edit-
findp is t if the command f pat would succeed,
nil otherwise. editfindp calls editfpat to con-
vert pat to the form expected by edit4e, unless
flg=t. if the program is applying editfindp to
several different expressions using the same pat-
tern, it will be more efficient to call editfpat
once, and then call editfindp with the converted
pattern and flg=t.
(## g_com1 ...)
RETURNS: what the current expression would be after
executing the edit commands com1 ... starting
from the present edit chain. generates an
error if any of comi cause errors. The
current edit chain is never changed. example:
(i r (quote x) (## (cons ..z))) replaces all
x's in the current expression by the first
cons containing a z.
9
9 Printed: July 21, 1983
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.