Advice only applies in all cases after function calling advised function is re-evaluated

巧了我就是萌 提交于 2019-12-12 16:21:34

问题


In my .emacs file, I have:

(defadvice narrow-to-region (around test activate)
   (message "advice")
   ad-do-it)

When I call narrow-to-region, the advice runs and prints 'advice' before narrowing.

When I call narrow-to-defun, it does not.

I found where narrow-to-defun is defined - in lisp.el, and re-evaluated the function. At this point, the advice started running.

What could cause this?


回答1:


The problem is, apparently, due to byte-compilation and therefore the inability to advise the narrowing primitives (narrow-to-region is the primitive, narrow-to-defun calls narrow-to-region).

The following post on Null Program ("The Limits of Emacs Advice") goes into detail about this problem. Here's the shortish version from deep in the post:

It turns out narrow-to-region is so special -- probably because it's used very frequently -- that it gets its own bytecode. The primitive function call is being compiled away into a single instruction. This means my advice will not be considered in byte-compiled code. Darnit. The same is true for widen (code 126).

As to why the advice started working after you re-evaluated narrow-to-defun: I'm guessing it's because you ended up replacing the byte-compiled version when you re-evaluated.




回答2:


@Dan described the problem well. Here is some info that might help you work around it.

What you can do is to advise (or to redefine) also narrow-to-defun (and perhaps narrow-to-page), so it acts similarly.

FWIW, I do something similar in library wide-n.el (see Multiple Narrowings).

I advise narrow-to-region. But I also redefine narrow-to-defun and narrow-to-page. In all 3 cases I make the same change, to record the details of each narrowing so you can return to them later. Here is the advice, 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 narrow-to-defun redefinition:

  ...
  (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))))


来源:https://stackoverflow.com/questions/25246901/advice-only-applies-in-all-cases-after-function-calling-advised-function-is-re-e

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!