Advice only applies in all cases after re-evaluating the function called by the recommended function
In my .emacs file, I have:
(defadvice narrow-to-region (around test activate)
(message "advice")
ad-do-it)
When I call a narrow area, the advice works and prints "advice" before the narrowing.
When I call narrow-defunun it is not.
I found that narrow-defunct is defined - in lisp.el, and re-evaluated the function. At this stage, the council began to work.
What could be causing this?
source to share
The problem appears to be byte-compilation related, and therefore the inability to advise narrowing primitives ( narrow-to-region
is primitive, narrow-to-defun
invocation narrow-to-region
).
The next post in the Null Program ( "Emacs Advice Limitations" ) details this issue in detail. Here's a short version from deep within the post:
It turns out to be
narrow-to-region
so special - perhaps because it is used very often - it gets its own bytecode. A call to a primitive function is compiled into one command. This means that my advice will not count in byte-compiled code. Drain it. The same is true forwiden
(code 126).
As for why the advice started working after re-evaluating narrow-to-defun
: I am guessing it is because you ended up replacing the byte compiled version on re-evaluating.
source to share
@Dan described the problem well. Here's some information to help you get around it.
What you can do is advise (or override) as well narrow-to-defun
(and possibly narrow-to-page
), so it acts similarly.
FWIW, I am doing something similar in a library wide-n.el
(see Multiple Nodes ).
I advise narrow-to-region
. But I also override narrow-to-defun
and narrow-to-page
. In all three cases, I make the same change to record the details of each taper so you can come back to them later. Here's a tip, for example:
(defadvice narrow-to-region (before push-wide-n-restrictions activate)
"Push the region limits to `wide-n-restrictions'.
You can use `C-x n x...' to widen to previous buffer restrictions."
(when (or (interactive-p) wide-n-push-anyway-p)
(wide-n-push (ad-get-arg 0) (ad-get-arg 1)))) ; Args START and END.
And here is the relevant part of the override narrow-to-defun
:
...
(goto-char end)
(re-search-backward "^\n" (- (point) 1) t)
(when (or (interactive-p) wide-n-push-anyway-p) (wide-n-push beg end)) ; <=====
(narrow-to-region beg end))))
source to share