Function: ad-add-advice
ad-add-advice is an autoloaded and byte-compiled function defined in
advice.el.gz.
Signature
(ad-add-advice FUNCTION ADVICE CLASS POSITION)
Documentation
Add a piece of ADVICE to FUNCTION's list of advices in CLASS.
ADVICE has the form (NAME PROTECTED ENABLED DEFINITION), where NAME is the advice name; PROTECTED is a flag specifying whether to protect against non-local exits; ENABLED is a flag specifying whether to initially enable the advice; and DEFINITION has the form (advice . LAMBDA), where LAMBDA is a lambda expression.
If FUNCTION already has a piece of advice with the same name, then POSITION is ignored, and the old advice is overwritten with the new one.
If FUNCTION already has one or more pieces of advice of the
specified CLASS, then POSITION determines where the new piece
goes. POSITION can either be first, last or a number (where
0 corresponds to first, and numbers outside the valid range are
mapped to the closest extremal position).
If FUNCTION was not advised already, its advice info will be initialized. Redefining a piece of advice whose name is part of the cache-id will clear the cache.
Source Code
;; Defined in /usr/src/emacs/lisp/emacs-lisp/advice.el.gz
;;;###autoload
(defun ad-add-advice (function advice class position)
"Add a piece of ADVICE to FUNCTION's list of advices in CLASS.
ADVICE has the form (NAME PROTECTED ENABLED DEFINITION), where
NAME is the advice name; PROTECTED is a flag specifying whether
to protect against non-local exits; ENABLED is a flag specifying
whether to initially enable the advice; and DEFINITION has the
form (advice . LAMBDA), where LAMBDA is a lambda expression.
If FUNCTION already has a piece of advice with the same name,
then POSITION is ignored, and the old advice is overwritten with
the new one.
If FUNCTION already has one or more pieces of advice of the
specified CLASS, then POSITION determines where the new piece
goes. POSITION can either be `first', `last' or a number (where
0 corresponds to `first', and numbers outside the valid range are
mapped to the closest extremal position).
If FUNCTION was not advised already, its advice info will be
initialized. Redefining a piece of advice whose name is part of
the cache-id will clear the cache."
(when (and (featurep 'native-compile)
(subr-primitive-p (symbol-function function)))
(comp-subr-trampoline-install function))
(cond ((not (ad-is-advised function))
(ad-initialize-advice-info function)
(ad-set-advice-info-field
function 'advicefunname (ad-make-advicefunname function))))
(let* ((previous-position
(ad-advice-position function class (ad-advice-name advice)))
(advices (ad-get-advice-info-field function class))
;; Determine a numerical position for the new advice:
(position (cond (previous-position)
((eq position 'first) 0)
((eq position 'last) (length advices))
((numberp position)
(max 0 (min position (length advices))))
(t 0))))
;; Check whether we have to clear the cache:
(if (memq (ad-advice-name advice) (ad-get-cache-class-id function class))
(ad-clear-cache function))
(if previous-position
(setcar (nthcdr position advices) advice)
(if (= position 0)
(ad-set-advice-info-field function class (cons advice advices))
(setcdr (nthcdr (1- position) advices)
(cons advice (nthcdr position advices)))))))