diff options
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r-- | lisp/emacs-lisp/debug.el | 3 | ||||
-rw-r--r-- | lisp/emacs-lisp/elp.el | 2 | ||||
-rw-r--r-- | lisp/emacs-lisp/nadvice.el | 32 | ||||
-rw-r--r-- | lisp/emacs-lisp/trace.el | 2 |
4 files changed, 25 insertions, 14 deletions
diff --git a/lisp/emacs-lisp/debug.el b/lisp/emacs-lisp/debug.el index dbd0f092446..77abbc96d2d 100644 --- a/lisp/emacs-lisp/debug.el +++ b/lisp/emacs-lisp/debug.el @@ -798,7 +798,8 @@ Redefining FUNCTION also cancels it." (not (special-form-p symbol)))) t nil nil (symbol-name fn))) (list (if (equal val "") fn (intern val))))) - (advice-add function :before #'debug--implement-debug-on-entry) + (advice-add function :before #'debug--implement-debug-on-entry + '((depth . -100))) function) (defun debug--function-list () diff --git a/lisp/emacs-lisp/elp.el b/lisp/emacs-lisp/elp.el index f1321eb4e6d..1187169b034 100644 --- a/lisp/emacs-lisp/elp.el +++ b/lisp/emacs-lisp/elp.el @@ -251,7 +251,7 @@ FUNSYM must be a symbol of a defined function." ;; Set the symbol's new profiling function definition to run ;; ELP wrapper. (advice-add funsym :around (elp--make-wrapper funsym) - `((name . ,elp--advice-name))))) + `((name . ,elp--advice-name) (depth . -99))))) (defun elp--instrumented-p (sym) (advice-member-p elp--advice-name sym)) diff --git a/lisp/emacs-lisp/nadvice.el b/lisp/emacs-lisp/nadvice.el index 0352164caf5..9f539338b59 100644 --- a/lisp/emacs-lisp/nadvice.el +++ b/lisp/emacs-lisp/nadvice.el @@ -129,8 +129,6 @@ Each element has the form (WHERE BYTECODE STACK) where: ;; TODO: make it so that interactive spec can be a constant which ;; dynamically checks the advice--car/cdr to do its job. ;; For that, advice-eval-interactive-spec needs to be more faithful. - ;; FIXME: The calls to interactive-form below load autoloaded functions - ;; too eagerly. (let ((fspec (cadr (interactive-form function)))) (when (eq 'function (car-safe fspec)) ;; Macroexpanded lambda? (setq fspec (nth 1 fspec))) @@ -147,19 +145,29 @@ Each element has the form (WHERE BYTECODE STACK) where: (apply #'make-byte-code 128 byte-code (vector #'apply function main props) stack-depth advice--docstring - (when (or (commandp function) (commandp main)) - (list (advice--make-interactive-form - function main)))))) + (and (or (commandp function) (commandp main)) + (not (and (symbolp main) ;; Don't autoload too eagerly! + (autoloadp (symbol-function main)))) + (list (advice--make-interactive-form + function main)))))) (when adv-sig (puthash advice adv-sig advertised-signature-table)) advice)) (defun advice--make (where function main props) "Build a function value that adds FUNCTION to MAIN at WHERE. WHERE is a symbol to select an entry in `advice--where-alist'." - (let ((desc (assq where advice--where-alist))) - (unless desc (error "Unknown add-function location `%S'" where)) - (advice--make-1 (nth 1 desc) (nth 2 desc) - function main props))) + (let ((fd (or (cdr (assq 'depth props)) 0)) + (md (if (advice--p main) + (or (cdr (assq 'depth (advice--props main))) 0)))) + (if (and md (> fd md)) + ;; `function' should go deeper. + (let ((rest (advice--make where function (advice--cdr main) props))) + (advice--make-1 (aref main 1) (aref main 3) + (advice--car main) rest (advice--props main))) + (let ((desc (assq where advice--where-alist))) + (unless desc (error "Unknown add-function location `%S'" where)) + (advice--make-1 (nth 1 desc) (nth 2 desc) + function main props))))) (defun advice--member-p (function name definition) (let ((found nil)) @@ -216,8 +224,6 @@ different, but `function-equal' will hopefully ignore those differences.") ;;;###autoload (defmacro add-function (where place function &optional props) ;; TODO: - ;; - provide some kind of control over ordering. E.g. debug-on-entry, ELP - ;; and tracing want to stay first. ;; - maybe let `where' specify some kind of predicate and use it ;; to implement things like mode-local or eieio-defmethod. ;; Of course, that only makes sense if the predicates of all advices can @@ -245,6 +251,10 @@ If FUNCTION was already added, do nothing. PROPS is an alist of additional properties, among which the following have a special meaning: - `name': a string or symbol. It can be used to refer to this piece of advice. +- `depth': a number indicating a preference w.r.t ordering. + The default depth is 0. By convention, a depth of 100 means that + the advice should be innermost (i.e. at the end of the list), + whereas a depth of -100 means that the advice should be outermost. If PLACE is a simple variable, only its global value will be affected. Use (local 'VAR) if you want to apply FUNCTION to VAR buffer-locally. diff --git a/lisp/emacs-lisp/trace.el b/lisp/emacs-lisp/trace.el index 3a2c44a8da6..cbbfd268445 100644 --- a/lisp/emacs-lisp/trace.el +++ b/lisp/emacs-lisp/trace.el @@ -256,7 +256,7 @@ be printed along with the arguments in the trace." function :around (trace-make-advice function (or buffer trace-buffer) background (or context (lambda () ""))) - `((name . ,trace-advice-name)))) + `((name . ,trace-advice-name) (depth . -100)))) (defun trace-is-traced (function) (advice-member-p trace-advice-name function)) |