Comment supprimer un conseil sans nom?

12

Je m'amusais à ajouter quelques conseils à une fonction:

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

Aïe, une faute de frappe. Corrigé et évalué à nouveau le code ci-dessus. Mais maintenant, j'ai les deux, les conseils "corrigés" et "cassés" autour de cette fonction.

Comment puis-je m'en débarrasser? Étant donné qu'il a advice-removebesoin de l'objet fonction ou du conseil autour (qui est vide ici)?

(Évidemment, je peux simplement quitter et redémarrer, mais il y a une autre façon, n'est-ce pas?)

Daniel Jour
la source

Réponses:

7

Vous pouvez également appeler advice-removeavec la même expression lambda, c'est-à-dire remplacer advice-addpar advice-removeet supprimer :around, puis C-x C-e.

xuchunyang
la source
Cela marche! Je pensais que ce ne serait pas le cas, j'ai supposé que (1) chaque fois que vous évaluez une forme lambda, vous obtenez une nouvelle fonction et non eqles précédentes, (2) Advice-Remove comparerait la fonction que vous lui transmettez aux conseils jusqu'à ce qu'elle trouve celui qui est eqà lui et à supprimer cela, (3) même si Advice-Remove a utilisé un test différent, comme equal, cela ne fonctionnerait toujours pas, car différentes évaluations d'une forme lambda ne se feraient pas equalmutuellement. Il s'avère que (1) est correct, mais (2) et (3) sont faux: conseils-supprimer les utilisations equal, et les évaluer lambdadeux fois donne des equalrésultats!
Omar
J'ai remarqué que je n'ai pas accepté de réponse quand j'ai posé la question. Je choisis le vôtre parce que c'est l'OMI la plus utile dans la situation.
Daniel Jour
11

Il y a advice-mapc, qui nous permet d'itérer sur tous les conseils d'une fonction, en appliquant une fonction donnée à chacun. Avec lui, il est facile de supprimer tous les conseils:

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

Cela pourrait être étendu pour supprimer uniquement les conseils qui n'ont pas de namepropriété en recherchant dans le second propsargument () (qui est une liste) ceux qui n'ont rien associé à la clé name.

Daniel Jour
la source
Oui. Et l'utilisation d'un namefacilite le retrait.
Drew
1

Voici du code pour vous aider à faire exactement cela, de manière interactive.

Cela définit deux fonctions. La première fonction obtient la liste de tous les conseils sur un symbole donné, la seconde fonction demande de manière interactive un symbole et un conseil sur ce symbole, puis supprime ce dernier du premier. Comme tout cela se produit à la fin, il est plus facile (pour moi) que de copier-coller l'expression 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))
YoungFrog
la source