X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/8241495da57ca0efed1b2e86ff693b5614e0aebd..171920a66145032a61fab9458ec6104000ff8dd8:/lispref/advice.texi diff --git a/lispref/advice.texi b/lispref/advice.texi index 6ff9349544..2006474fc6 100644 --- a/lispref/advice.texi +++ b/lispref/advice.texi @@ -1,23 +1,25 @@ @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 @@ -34,7 +36,7 @@ function (or a new command) which uses the existing function. * 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 @@ -44,11 +46,13 @@ function (or a new command) which uses the existing function. 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 @@ -125,6 +129,9 @@ form) to be advised. From now on, we will write just ``function'' when 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 @@ -150,9 +157,6 @@ the pieces of advice in a particular class for a particular @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 @@ -168,14 +172,15 @@ definition that is generated in order to run the advice (@pxref{Combined 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. +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 @@ -189,7 +194,7 @@ function; this flag says to do so, for @var{function}, immediately after 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. @@ -239,6 +244,14 @@ expanded when a program is compiled, not when a compiled program is run. 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 @@ -261,9 +274,9 @@ Its effect is to make sure that case is ignored in 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 @@ -319,12 +332,13 @@ replaced with the new one. @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 @@ -339,18 +353,19 @@ are combined with the original definition to make a new definition. @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 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}. @@ -358,6 +373,12 @@ 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 @@ -366,6 +387,12 @@ This command activates the advice for all functions. 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 @@ -392,8 +419,7 @@ last time it was activated. @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 @@ -404,6 +430,18 @@ redefined. @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'' @@ -619,16 +657,23 @@ will be 3, and @var{r} will be @code{(2 1 0)} inside the body of 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 @@ -647,10 +692,11 @@ specifies the argument list for the function @code{fset}. @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} @@ -658,20 +704,20 @@ implement the advice for a function looks like this: (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 @@ -680,7 +726,7 @@ the beginning of the combined definition. 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. @@ -688,7 +734,7 @@ The body forms of the various advice in each class are assembled 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} @@ -706,3 +752,7 @@ pieces of advice is the same. The only difference is that 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