org-icomplete
是一个调用ido-completing-read
(icr)的函数。相反,我希望它调用我的函数:ido-completing-path-like-read
(icplr)。除了icplr调用icr之外,这很容易实现为建议,因此需要在icplr上调用另一个建议来重新调用icr的原始定义,以防止无限递归。
我以两种方式实现了这一点,其中一种方法有效,其中一种方式没有 - icplr进入无限递归,调用自身而不是icr。为什么一个不工作,不工作?
使用:
(defadvice org-icompleting-read (around ido-path-like-completion activate)
(let ((sh/orig-ido-completing-read (symbol-function 'ido-completing-read)))
(unwind-protect
(progn
(defadvice ido-completing-path-like-read
(around save-ido-completing-read activate)
(setf (symbol-function 'ido-completing-read)
sh/orig-ido-completing-read)
ad-do-it
)
(setf (symbol-function 'ido-completing-read)
(symbol-function 'ido-completing-path-like-read))
ad-do-it
)
(setf (symbol-function 'ido-completing-read)
sh/orig-ido-completing-read)
(ad-remove-advice 'ido-completing-path-like-read 'around 'save-ido-completing-read)
))
)
不起作用:
(defadvice org-icompleting-read (around ido-path-like-completion activate)
(let ((sh/orig-ido-completing-read (symbol-function 'ido-completing-read)))
(unwind-protect
(progn
(setf (symbol-function 'ido-completing-read)
(symbol-function 'ido-completing-path-like-read))
(defadvice ido-completing-path-like-read
(around save-ido-completing-read activate)
(setf (symbol-function 'ido-completing-read)
sh/orig-ido-completing-read)
ad-do-it
)
ad-do-it
)
(setf (symbol-function 'ido-completing-read)
sh/orig-ido-completing-read)
(ad-remove-advice 'ido-completing-path-like-read 'around 'save-ido-completing-read)
))
)
修改
我想说清楚所有提到的函数:ido-completed-path-like-read,ido-completed-read和org-icompleting-read将被处理(其中两个在事实是)库函数,我无法控制的定义。
虽然我在这里对替代模式的建议持开放态度并且会很感激,但我只会接受一个实际回答我的问题的答案:为什么第一个代码有效,第二个代码没有? ?谢谢你的理解。
答案 0 :(得分:1)
不要添加/删除建议。只需提出有条件的建议:
(defvar my-inhibit-org-advice nil)
(defadvice org-icompleting-read (around ...)
(if my-inhibit-org-advice ad-do-it
...my advice...))
(defun ido-completing-path-like-read (...)
(let ((my-inhibit-org-advice t))
...(org-icompleting-read ...)...))
答案 1 :(得分:1)
任何可能来搜索的人:
第一个起作用而第二个起作用的原因不是应用建议的顺序 - 它是相对于:
应用内部建议的顺序 (setf (symbol-function 'ido-completing-read)
(symbol-function 'ido-completing-path-like-read))
重要的是,如果在建议之前执行此声明,则不会建议符号'ido-completing-read
,而符号'ido-completing-path-like-read
副本将是。但是,如果首先应用建议,则两个符号都将引用建议的版本。
我不确定这完全有道理。我想象(这就是为什么这个难题)函数对象附加了一些附加信息,以及我们通过操纵这些附加信息来应用的建议。
事实证明这是一个更基本的机制 - 函数实际上是ad-hoc ...