I sometimes want to bypass the advice I have defined on some function. Something like:
(call-without-advice #'fn ...)
I sometimes want to bypass the advice I have defined on some function. Something like:
(call-without-advice #'fn ...)
I can't find a public interface for that. In Emacs 25.5 and Emacs 27.1 and presumably every version in between (I haven't checked older or more recent versions), for new-style advice (define-advice, advice-xxx from nadvice.el), you can use
(advice--cd*r (symbol-function #'fn))
For old-style advice (defadvice, ad-xxx from advice.el):
(ad-get-orig-definition #'fn)
I've thought about this before, and there's a less-than-perfect solution:
you need to store the original definition before any advice-adding.
(defun f ()
(insert "233\n"))
(setq f.backup (symbol-function 'f))
(advice-add 'f :around
(lambda (fobj &rest args)
(insert (format "eq?: %s\n"
(eq f.backup fobj)))
(apply fobj args)))
It is also convenient to store the definition in symbol-plist.
(advice-add 'advice-add :before
(lambda (symbol &rest _)
(unless (get symbol :shynur/original-definition)
(put symbol :shynur/original-definition
(symbol-function symbol)))))
(defun call-without-advice (symbol &rest arguments)
(apply (or (get symbol :shynur/original-definition)
symbol)
arguments))
looks much better now.
Combining the suggestions from @Gilles:
(defun fn-sans-advice (sym)
"Get original function defined at SYM, sans advices."
(if (advice--p (symbol-function sym))
(advice--cd*r (symbol-function sym))
(if (fboundp 'ad-get-orig-definition)
(ad-get-orig-definition sym)
sym)))
I find this more general than a direct "call-without-advice", because you can e.g. let-bind it once before initiating a heavy loop, as in the following example.
(let ((real-delete-file (fn-sans-advice #'delete-file))
(dolist (file (directory-files "."))
(funcall real-delete-file file)))