Bagaimana saya bisa menghapus saran yang tidak disebutkan namanya?

12

Saya bersenang-senang menambahkan beberapa saran ke fungsi:

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

Aduh, salah ketik. Memperbaikinya dan mengevaluasi kode di atas lagi. Tapi sekarang saya memiliki keduanya, saran "diperbaiki" dan "rusak" di sekitar fungsi itu.

Bagaimana saya menyingkirkan ini? Mengingat bahwa advice-removeperlu objek fungsi atau saran sekitar (yang kosong di sini)?

(Jelas saya bisa berhenti dan memulai kembali, tetapi ada cara lain, bukan?)

Daniel Jour
sumber

Jawaban:

7

Anda juga dapat memanggil advice-removedengan ekspresi lambda yang sama, yaitu, ganti advice-adddengan advice-removedan hapus :around, lalu C-x C-e.

xuchunyang
sumber
Ini bekerja! Saya pikir itu tidak akan, saya berasumsi bahwa (1) setiap kali Anda mengevaluasi formulir lambda Anda mendapatkan fungsi baru tidak eqdengan yang sebelumnya, (2) saran-hapus akan membandingkan fungsi yang Anda berikan ke saran sampai menemukan salah satunya adalah equntuk itu dan menghapus itu, (3) bahkan jika saran-hapus menggunakan tes yang berbeda, seperti equal, itu masih tidak akan berhasil, karena evaluasi yang berbeda dari bentuk lambda tidak akan equalsaling. Ternyata (1) benar, tetapi (2) dan (3) salah: penggunaan saran-hapus equal, dan mengevaluasi yang sama lambdadua kali menghasilkan equalhasil!
Omar
Melihat saya tidak menerima jawaban kembali ketika saya mengajukan pertanyaan. Saya memilih Milik Anda karena IMO paling membantu dalam situasi tersebut.
Daniel Jour
11

Ada advice-mapc, yang mari kita mengulangi semua saran dari beberapa fungsi, menerapkan fungsi yang diberikan untuk masing-masing. Dengan itu, mudah untuk menghapus semua saran:

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

Ini dapat diperluas untuk menghapus hanya saran yang tidak memiliki nameproperti dengan melihat pada propsargumen kedua ( ) (yang merupakan daftar) untuk mereka yang tidak memiliki sesuatu yang terkait dengan kunci name.

Daniel Jour
sumber
Iya. Dan menggunakan namemenghapus membuat lebih mudah.
Drew
1

Berikut beberapa kode untuk membantu melakukan hal itu, secara interaktif.

Ini mendefinisikan dua fungsi. Fungsi pertama mendapatkan daftar semua saran pada simbol yang diberikan, fungsi kedua secara interaktif meminta simbol dan saran tentang simbol itu, kemudian menghapus yang terakhir dari yang sebelumnya. Karena ini semua terjadi dengan selesai, lebih mudah (bagi saya) daripada menyalin menempelkan ekspresi 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
sumber