summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/emacs-lisp')
-rw-r--r--lisp/emacs-lisp/debug.el3
-rw-r--r--lisp/emacs-lisp/elp.el2
-rw-r--r--lisp/emacs-lisp/nadvice.el32
-rw-r--r--lisp/emacs-lisp/trace.el2
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))