如何删除未命名的建议?


12

我很乐意向函数添加一些建议:

(advice-add 'executable-find :around
            (lambda (f &rest args)
              (apply g args)))
               ;;;   ^

哎呀,错字了 修复它并再次评估以上代码。但是,现在我同时收到有关该功能的“更正”和“破损”建议。

我该如何摆脱这些?鉴于advice-remove需要功能对象或周围建议(此处为空)?

(显然,我可以退出并重新启动,但是还有另一种方法,对吗?)

Answers:


7

您还可以advice-remove使用相同的lambda表达式进行调用,即,先替换advice-addadvice-removeand delete :around,然后再进行C-x C-e


这可行!我以为不会,我假设(1)每次评估Lambda表单时,都会得到一个新函数,而不是eq以前的函数;(2)建议删除会比较将其传递给建议的函数,直到找到为止一个是eq它并删除,(3)即使意见-删除使用不同的测试,比如equal,它仍然是行不通的,因为lambda形式的不同的评价不会equal彼此。事实证明(1)是正确的,但是(2)和(3)是错误的:advice-remouse使用equal,并对它进行lambda两次评估会产生equal结果!
奥马尔(Omar)

请注意,当我提出问题时,我没有接受答复。我选择您的原因是因为它是IMO在这种情况下最有用的方法。
Daniel Jour

11

advice-mapc,它让我们迭代某个功能的所有建议,然后将给定功能应用于每个建议。有了它,很容易删除所有建议:

(advice-mapc
  (lambda (adv prop)
    (advice-remove 'executable-find adv))
  'executable-find)

name通过将第二个(props)参数(这是一个列表)查找那些与key无关的建议,可以扩展该方法以仅删除没有属性的建议name


是。并且使用name使得删除变得更加容易。
Drew

1

这是一些代码,可帮助以交互方式完成此任务。

这定义了两个功能。第一个功能获取有关给定符号的所有建议的列表,第二个功能以交互方式询问一个符号和该符号的建议,然后从前一个中删除后者。由于这一切都是在完成时发生的,(对我而言)比复制粘贴lambda表达式容易。

(defun yf/advice-list (symbol)
  (let (result)
    (advice-mapc
     (lambda (ad props)
       (push ad result))
     symbol)
    (nreverse result)))

(defun yf/kill-advice (symbol advice)
  "Kill ADVICE from SYMBOL."
  (interactive (let* ((sym (intern (completing-read "Function: " obarray #'yf/advice-list t)))
                      (advice (let ((advices-and-their-name
                                     (mapcar (lambda (ad) (cons (prin1-to-string ad)
                                                                ad))
                                             (yf/advice-list sym))))
                                (cdr (assoc (completing-read "Remove advice: " advices-and-their-name nil t)
                                            advices-and-their-name)))))
                 (list sym advice)))
  (advice-remove symbol advice))
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.