Function: defadvice

defadvice is an autoloaded macro defined in advice.el.gz.

Signature

(defadvice FUNCTION ARGS &rest BODY)

Documentation

Define a piece of advice for FUNCTION (a symbol).

The syntax of defadvice is as follows:

  (defadvice FUNCTION (CLASS NAME [POSITION] [ARGLIST] FLAG...)
    [DOCSTRING] [INTERACTIVE-FORM]
    BODY...)

FUNCTION ::= Name of the function to be advised. CLASS ::= before | around | after | activation | deactivation. NAME ::= Non-nil symbol that names this piece of advice. POSITION ::= first | last | NUMBER. Optional, defaults to first,
    see also ad-add-advice.
ARGLIST ::= An optional argument list to be used for the advised function
    instead of the argument list of the original. The first one found in
    before/around/after-advices will be used.
FLAG ::= protect|disable|activate|compile|preactivate.
    All flags can be specified with unambiguous initial substrings.
DOCSTRING ::= Optional documentation for this piece of advice. INTERACTIVE-FORM ::= Optional interactive form to be used for the advised
    function. The first one found in before/around/after-advices will be used.
BODY ::= Any s-expression.

Semantics of the various flags: protect: The piece of advice will be protected against non-local exits in any code that precedes it. If any around-advice of a function is protected then automatically all around-advices will be protected (the complete onion).

activate: All advice of FUNCTION will be activated immediately if FUNCTION has been properly defined prior to this application of defadvice.

compile: In conjunction with activate specifies that the resulting advised function should be compiled.

disable: The defined advice will be disabled, hence, it will not be used during activation until somebody enables it.

preactivate: Preactivates the advised FUNCTION at macro-expansion/compile time. This generates a compiled advised definition according to the current advice state that will be used during activation if appropriate. Only use this if the defadvice gets actually compiled.

usage: (defadvice FUNCTION (CLASS NAME [POSITION] [ARGLIST] FLAG...)
          [DOCSTRING] [INTERACTIVE-FORM]
          BODY...)

Probably introduced at or before Emacs version 22.1.

Source Code

;; Defined in /usr/src/emacs/lisp/emacs-lisp/advice.el.gz
;;;###autoload
(defmacro defadvice (function args &rest body)
  "Define a piece of advice for FUNCTION (a symbol).
The syntax of `defadvice' is as follows:

  (defadvice FUNCTION (CLASS NAME [POSITION] [ARGLIST] FLAG...)
    [DOCSTRING] [INTERACTIVE-FORM]
    BODY...)

FUNCTION ::= Name of the function to be advised.
CLASS ::= `before' | `around' | `after' | `activation' | `deactivation'.
NAME ::= Non-nil symbol that names this piece of advice.
POSITION ::= `first' | `last' | NUMBER.  Optional, defaults to `first',
    see also `ad-add-advice'.
ARGLIST ::= An optional argument list to be used for the advised function
    instead of the argument list of the original.  The first one found in
    before/around/after-advices will be used.
FLAG ::= `protect'|`disable'|`activate'|`compile'|`preactivate'.
    All flags can be specified with unambiguous initial substrings.
DOCSTRING ::= Optional documentation for this piece of advice.
INTERACTIVE-FORM ::= Optional interactive form to be used for the advised
    function.  The first one found in before/around/after-advices will be used.
BODY ::= Any s-expression.

Semantics of the various flags:
`protect': The piece of advice will be protected against non-local exits in
any code that precedes it.  If any around-advice of a function is protected
then automatically all around-advices will be protected (the complete onion).

`activate': All advice of FUNCTION will be activated immediately if
FUNCTION has been properly defined prior to this application of `defadvice'.

`compile': In conjunction with `activate' specifies that the resulting
advised function should be compiled.

`disable': The defined advice will be disabled, hence, it will not be used
during activation until somebody enables it.

`preactivate': Preactivates the advised FUNCTION at macro-expansion/compile
time.  This generates a compiled advised definition according to the current
advice state that will be used during activation if appropriate.  Only use
this if the `defadvice' gets actually compiled.

usage: (defadvice FUNCTION (CLASS NAME [POSITION] [ARGLIST] FLAG...)
          [DOCSTRING] [INTERACTIVE-FORM]
          BODY...)"
  (declare (doc-string 3) (indent 2)
           (debug (&define name  ;; thing being advised.
                           (name ;; class is [&or "before" "around" "after"
                                 ;;               "activation" "deactivation"]
                            name ;; name of advice
                            &rest sexp ;; optional position and flags
                            )
                           [&optional stringp]
                           [&optional ("interactive" interactive)]
                           def-body)))
  (if (not (ad-name-p function))
      (error "defadvice: Invalid function name: %s" function))
  (let* ((class (car args))
	 (name (if (not (ad-class-p class))
		   (error "defadvice: Invalid advice class: %s" class)
                   (nth 1 args)))
	 (position (if (not (ad-name-p name))
		       (error "defadvice: Invalid advice name: %s" name)
                       (setq args (nthcdr 2 args))
                       (if (ad-position-p (car args))
                           (prog1 (car args)
                             (setq args (cdr args))))))
	 (arglist (if (listp (car args))
		      (prog1 (car args)
			(setq args (cdr args)))))
	 (flags
	  (mapcar
           (lambda (flag)
             (let ((completion
                    (try-completion (symbol-name flag) ad-defadvice-flags)))
               (cond ((eq completion t) flag)
                     ((member completion ad-defadvice-flags)
                      (intern completion))
                     (t (error "defadvice: Invalid or ambiguous flag: %s"
                               flag)))))
	   args))
	 (advice (ad-make-advice
		  name (memq 'protect flags)
		  (not (memq 'disable flags))
		  `(advice lambda ,arglist ,@body)))
	 (preactivation (if (memq 'preactivate flags)
			    (ad-preactivate-advice
			     function advice class position))))
    ;; Now for the things to be done at evaluation time:
    `(progn
       (ad-add-advice ',function ',advice ',class ',position)
       ,@(if preactivation
             `((ad-set-cache
                ',function
                ;; the function will get compiled:
                ,(cond ((macrop (car preactivation))
                        `(ad-macrofy
                          (function
                           ,(ad-lambdafy
                             (car preactivation)))))
                       (t `(function
                            ,(car preactivation))))
                ',(car (cdr preactivation)))))
       ,@(if (memq 'activate flags)
             `((ad-activate ',function
                            ,(if (memq 'compile flags) t))))
       ',function)))