Як можна видалити неназвану пораду?


12

Мені було весело, додаючи поради до функції:

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

О, друкарська справа. Виправлено і знову оцінено вищезгаданий код. Але тепер у мене є обидві, "виправлені" і "зламані" поради навколо цієї функції.

Як я можу позбутися від них? Враховуючи, що advice-removeпотрібен або об’єкт функції, або поради навколо (який тут порожній)?

(Очевидно, що я можу просто кинути і перезапустити, але є інший спосіб, чи не так?)

Відповіді:


7

Ви також можете зателефонувати advice-removeз тим же лямбда - вираження, тобто, замінити advice-addз advice-removeі видалити :around, а потім C-x C-e.


Це працює! Я думав, що це не станеться, я припускав, що (1) кожного разу, коли ви оцінюєте лямбда-форму, ви отримуєте нову функцію, а не eqпопередню, (2) порада-видалення порівнюватиме функцію, яку ви передаєте її порадам, поки не знайде той, який є eqйому, і видаліть це (3), навіть якщо порада для видалення використовувала інший тест, як-от equal, він все одно не буде працювати, оскільки різні оцінки лямбда-форми не будуть equalміж собою. Виявляється, що (1) є правильним, але (2) та (3) помиляються: поради щодо видалення використання equalта оцінювання одного і того ж lambdaдвічі дають equalрезультати!
Омар

Помітив, що я не прийняв відповіді, коли поставив запитання. Я обираю Твоє, бо саме ІМО найбільше допомагає в цій ситуації.
Даніель Жур

11

Там advice-mapcми допоможемо повторити всі поради певної функції, застосувавши дану функцію до кожного. З його допомогою легко видалити всі поради:

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

Це може бути розширено, щоб видалити лише поради, які не мають nameвластивості, переглянувши другий propsаргумент () (який є списком) для тих, у кого немає ключа, пов'язаного з ключем name.


Так. А використання засобів nameполегшує видалення.
Дрю

1

Ось якийсь код, який допоможе робити саме це, інтерактивно.

Це визначає дві функції. Перша функція отримує список усіх порад щодо даного символу, друга функція інтерактивно запитує символ та поради щодо цього символу, потім видаляє останню з першої. Оскільки це все відбувається із завершенням, це простіше (мені), ніж копіювати вставлення лямбда-виразу.

(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))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.