@c -*-texinfo-*-
@c This is part of the GNU Emacs Lisp Reference Manual.
-@c Copyright (C) 1998 Free Software Foundation, Inc.
+@c Copyright (C) 1998, 1999 Free Software Foundation, Inc.
@c See the file elisp.texi for copying conditions.
@setfilename ../info/advising
@node Advising Functions, Debugging, Byte Compilation, Top
@chapter Advising Emacs Lisp Functions
@cindex advising functions
- The @dfn{advice} feature lets you add to the existing definition of a
-function, by @dfn{advising the function}. This is a clean method for a
-library to customize functions defined by other parts of Emacs---cleaner
+ The @dfn{advice} feature lets you add to the existing definition of
+a function, by @dfn{advising the function}. This is a clean method
+for a library to customize functions defined within Emacs---cleaner
than redefining the whole function.
@cindex piece of advice
Each function can have multiple @dfn{pieces of advice}, separately
-defined. Each defined piece of advice can be enabled or disabled
-explicitly. The enabled pieces of advice for any given function
-actually take effect when you @dfn{activate} advice for that function, or when
-that function is subsequently defined or redefined.
+defined. Each defined piece of advice can be @dfn{enabled} or
+@dfn{disabled} explicitly. All the enabled pieces of advice for any given
+function actually take effect when you @dfn{activate} advice for that
+function, or when you define or redefine the function. Note that
+enabling a piece of advice and activating advice for a function
+are not the same thing.
@strong{Usage Note:} Advice is useful for altering the behavior of
existing calls to an existing function. If you want the new behavior
* Preactivation:: Preactivation is a way of speeding up the
loading of compiled advice.
* Argument Access in Advice:: How advice can access the function's arguments.
-* Subr Arguments:: Accessing arguments when advising a primitive.
+* Advising Primitives:: Accessing arguments when advising a primitive.
* Combined Definition:: How advice is implemented.
@end menu
The command @code{next-line} moves point down vertically one or more
lines; it is the standard binding of @kbd{C-n}. When used on the last
line of the buffer, this command inserts a newline to create a line to
-move to (if @code{next-line-add-newlines} is non-@code{nil}).
+move to if @code{next-line-add-newlines} is non-@code{nil} (its default
+is @code{nil}.)
Suppose you wanted to add a similar feature to @code{previous-line},
which would insert a new line at the beginning of the buffer for the
-command to move to. How could you do this?
+command to move to (when @code{next-line-add-newlines} is
+non-@code{nil}). How could you do this?
You could do it by redefining the whole function, but that is not
modular. The advice feature provides a cleaner alternative: you can
describing the entity being advised, but this always includes macros and
special forms.
+ In place of the argument list in an ordinary definition, an advice
+definition calls for several different pieces of information.
+
@cindex class of advice
@cindex before-advice
@cindex after-advice
@var{function}. The name allows you to refer to the piece of
advice---to redefine it, or to enable or disable it.
-In place of the argument list in an ordinary definition, an advice
-definition calls for several different pieces of information.
-
The optional @var{position} specifies where, in the current list of
advice of the specified @var{class}, this new advice should be placed.
It should be either @code{first}, @code{last} or a number that specifies
Definition}). Therefore, the advice expressions can use the argument
variables in this list to access argument values.
-This argument list must be compatible with the argument list of the
-original function, so that it can handle the ways the function is
-actually called. If more than one piece of advice specifies an argument
-list, then the first one (the one with the smallest position) found in
-the list of all classes of advice is used.
+The argument list used in advice need not be the same as the argument
+list used in the original function, but must be compatible with it, so
+that it can handle the ways the function is actually called. If two
+pieces of advice for a function both specify an argument list, they must
+specify the same argument list.
+
+@xref{Argument Access in Advice}, for more information about argument
+lists and advice, and a more flexible way for advice to access the
+arguments.
The remaining elements, @var{flags}, are symbols that specify further
information about how to use this piece of advice. Here are the valid
defining this piece of advice.
@cindex forward advice
-This flag has no effect if @var{function} itself is not defined yet (a
+This flag has no immediate effect if @var{function} itself is not defined yet (a
situation known as @dfn{forward advice}), because it is impossible to
activate an undefined function's advice. However, defining
@var{function} will automatically activate its advice.
Activate advice for @var{function} when this @code{defadvice} is
compiled or macroexpanded. This generates a compiled advised definition
according to the current advice state, which will be used during
-activation if appropriate.
+activation if appropriate. @xref{Preactivation}.
This is useful only if this @code{defadvice} is byte-compiled.
@end table
All subroutines used by the advice need to be available when the byte
compiler expands the macro.
+@deffn Command ad-unadvise function
+This command deletes the advice from @var{function}.
+@end deffn
+
+@deffn Command ad-unadvise-all
+This command deletes all pieces of advice from all functions.
+@end deffn
+
@node Around-Advice
@section Around-Advice
searches when the original definition of @code{foo} is run.
@defvar ad-do-it
-This is not really a variable, but it is somewhat used like one
-in around-advice. It specifies the place to run the function's
-original definition and other ``earlier'' around-advice.
+This is not really a variable, rather a place-holder that looks like a
+variable. You use it in around-advice to specify the place to run the
+function's original definition and other ``earlier'' around-advice.
@end defvar
If the around-advice does not use @code{ad-do-it}, then it does not run
original definition completely. (It also overrides lower-positioned
pieces of around-advice).
+If the around-advice uses @code{ad-do-it} more than once, the original
+definition is run at each place. In this way, around-advice can execute
+the original definition (and lower-positioned pieces of around-advice)
+several times. Another way to do that is by using @code{ad-do-it}
+inside of a loop.
+
@node Computed Advice
@section Computed Advice
to put the new piece of advice. The value of @var{position} can either
be @code{first}, @code{last}, or a number (counting from 0 at the
beginning of the list). Numbers outside the range are mapped to the
-closest extreme position.
+beginning or the end of the range, whichever is closer. The
+@var{position} value is ignored when redefining an existing piece of
+advice.
If @var{function} already has a piece of @var{advice} with the same
name, then the position argument is ignored and the old advice is
@cindex advice, activating
By default, advice does not take effect when you define it---only when
-you @dfn{activate} advice for the function that was advised. You can
-request the activation of advice for a function when you define the
-advice, by specifying the @code{activate} flag in the @code{defadvice}.
-But normally you activate the advice for a function by calling the
-function @code{ad-activate} or one of the other activation commands
-listed below.
+you @dfn{activate} advice for the function that was advised. However,
+the advice will be activated automatically if you define or redefine
+the function later. You can request the activation of advice for a
+function when you define the advice, by specifying the @code{activate}
+flag in the @code{defadvice}. But normally you activate the advice
+for a function by calling the function @code{ad-activate} or one of
+the other activation commands listed below.
Separating the activation of advice from the act of defining it permits
you to add several pieces of advice to one function efficiently, without
@ref{Enabling Advice}.) This definition is installed, and optionally
byte-compiled as well, depending on conditions described below.
-In all of the commands to activate advice, if @var{compile} is @code{t},
-the command also compiles the combined definition which implements the
-advice.
+In all of the commands to activate advice, if @var{compile} is
+@code{t} (or anything but @code{nil} or a negative number), the
+command also compiles the combined definition which implements the
+advice. If it is @code{nil} or a negative number, what happens
+depends on @code{ad-default-compilation-action} as described below.
@deffn Command ad-activate function &optional compile
-This command activates the advice for @var{function}.
+This command activates all the advice defined for @var{function}.
@end deffn
-To activate advice for a function whose advice is already active is not
-a no-op. It is a useful operation which puts into effect any changes in
-that function's advice since the previous activation of advice for that
-function.
+ Activating advice does nothing if @var{function}'s advice is already
+active. But if there is new advice, added since the previous time you
+activated advice for @var{function}, it activates the new advice.
@deffn Command ad-deactivate function
This command deactivates the advice for @var{function}.
@cindex advice, deactivating
@end deffn
+@deffn Command ad-update function &optional compile
+This command activates the advice for @var{function}
+if its advice is already activated. This is useful
+if you change the advice.
+@end deffn
+
@deffn Command ad-activate-all &optional compile
This command activates the advice for all functions.
@end deffn
This command deactivates the advice for all functions.
@end deffn
+@deffn Command ad-update-all &optional compile
+This command activates the advice for all functions
+whose advice is already activated. This is useful
+if you change the advice of some functions.
+@end deffn
+
@deffn Command ad-activate-regexp regexp &optional compile
This command activates all pieces of advice whose names match
@var{regexp}. More precisely, it activates all advice for any function
@deffn Command ad-start-advice
Turn on automatic advice activation when a function is defined or
-redefined. If you turn on this mode, then advice really does
-take effect immediately when defined.
+redefined. This is the default mode.
@end deffn
@deffn Command ad-stop-advice
@defopt ad-default-compilation-action
This variable controls whether to compile the combined definition
that results from activating advice for a function.
+
+A value of @code{always} specifies to compile unconditionally.
+A value of @code{never} specifies never compile the advice.
+
+A value of @code{maybe} specifies to compile if the byte-compiler is
+already loaded. A value of @code{like-original} specifies to compile
+the advice if the original definition of the advised function is
+compiled or a built-in function.
+
+This variable takes effect only if the @var{compile} argument of
+@code{ad-activate} (or any of the above functions) did not force
+compilation.
@end defopt
If the advised definition was constructed during ``preactivation''
These argument constructs are not really implemented as Lisp macros.
Instead they are implemented specially by the advice mechanism.
-@node Subr Arguments
-@section Definition of Subr Argument Lists
+@node Advising Primitives
+@section Advising Primitives
- When the advice facility constructs the combined definition, it needs
-to know the argument list of the original function. This is not always
-possible for primitive functions. When advice cannot determine the
-argument list, it uses @code{(&rest ad-subr-args)}, which always works
-but is inefficient because it constructs a list of the argument values.
-You can use @code{ad-define-subr-args} to declare the proper argument
-names for a primitive function:
+ Advising a primitive function (also called a ``subr'') is risky.
+Some primitive functions are used by the advice mechanism; advising
+them could cause an infinite recursion. Also, many primitive
+functions are called directly from C code. Calls to the primitive
+from Lisp code will take note of the advice, but calls from C code
+will ignore the advice.
+
+When the advice facility constructs the combined definition, it needs
+to know the argument list of the original function. This is not
+always possible for primitive functions. When advice cannot determine
+the argument list, it uses @code{(&rest ad-subr-args)}, which always
+works but is inefficient because it constructs a list of the argument
+values. You can use @code{ad-define-subr-args} to declare the proper
+argument names for a primitive function:
@defun ad-define-subr-args function arglist
This function specifies that @var{arglist} should be used as the
@node Combined Definition
@section The Combined Definition
- Suppose that a function has @var{n} pieces of before-advice, @var{m}
-pieces of around-advice and @var{k} pieces of after-advice. Assuming no
-piece of advice is protected, the combined definition produced to
-implement the advice for a function looks like this:
+ Suppose that a function has @var{n} pieces of before-advice
+(numbered from 0 through @var{n}@minus{}1), @var{m} pieces of
+around-advice and @var{k} pieces of after-advice. Assuming no piece
+of advice is protected, the combined definition produced to implement
+the advice for a function looks like this:
@example
(lambda @var{arglist}
(let (ad-return-value)
@r{before-0-body-form}...
....
- @r{before-@var{n}-1-body-form}...
+ @r{before-@var{n}@minus{}1-body-form}...
@r{around-0-body-form}...
@r{around-1-body-form}...
....
- @r{around-@var{m}-1-body-form}...
+ @r{around-@var{m}@minus{}1-body-form}...
(setq ad-return-value
@r{apply original definition to @var{arglist}})
- @r{other-around-@var{m}-1-body-form}...
+ @r{end-of-around-@var{m}@minus{}1-body-form}...
....
- @r{other-around-1-body-form}...
- @r{other-around-0-body-form}...
+ @r{end-of-around-1-body-form}...
+ @r{end-of-around-0-body-form}...
@r{after-0-body-form}...
....
- @r{after-@var{k}-1-body-form}...
+ @r{after-@var{k}@minus{}1-body-form}...
ad-return-value))
@end example
The interactive form is present if the original function or some piece
of advice specifies one. When an interactive primitive function is
-advised, a special method is used: to call the primitive with
+advised, advice uses a special method: it calls the primitive with
@code{call-interactively} so that it will read its own arguments.
In this case, the advice cannot access the arguments.
according to their specified order. The forms of around-advice @var{l}
are included in one of the forms of around-advice @var{l} @minus{} 1.
-The innermost part of the around advice onion is
+The innermost part of the around advice onion is
@display
apply original definition to @var{arglist}
executed even if some previous piece of advice had an error or a
non-local exit. If any around-advice is protected, then the whole
around-advice onion is protected as a result.
+
+@ignore
+ arch-tag: 80c135c2-f1c3-4f8d-aa85-f8d8770d307f
+@end ignore