Re: Advicing the `interactive' form of a command
Stéphane Marks <[email protected]>
| Newsgroups | gmane.emacs.help |
|---|---|
| Message-ID | <CAN+1Hbr7eRM+JCEKMbPJDVa7M_yLfdzVRy6uVCo6CHFrXaUY7Q@mail.gmail.com> |
On Sun, May 3, 2026 at 12:03 AM Roland Winkler <[email protected]> wrote: > The following message is a courtesy copy of an article > that has been posted to gmane.emacs.help as well. > > How can one advice the `interactive' form of a command with advice-add? > The elisp manual describes the different values for the WHERE argument > of `add-function' and `advice-add' and how they are equivalent to > lambda forms. For example, :around advice is equivalent to > > (lambda (&rest r) (apply FUNCTION OLDFUN r)) > > This is clear for non-interactive functions. But what happens > if I want to modify the interactive form of OLDFUN? > > My slightly nontrivial example is `switch-to-buffer' where the > interactive form depends on `confirm-nonexistent-file-or-buffer'. > Indeed, the same var affects `switch-to-buffer' and `find-file'. > So I thought I could fine-tune things with something like > > (setq confirm-nonexistent-file-or-buffer nil) ; for `find-file' > (advice-add > 'switch-to-buffer :around > (lambda (fun &rest args) > (let ((confirm-nonexistent-file-or-buffer t)) > (apply fun args)))) > > But this does not work. It seems that the `interactive' form of the > advice'd command `switch-to-buffer' is run outside the let binding. > Actually, how does the lambda form in the above example work for a command > if the lambda form does not have an `interactive' form? I looked into > nadvice.el, but something like `advice-eval-interactive-spec' is beyond > my understanding of things. > Advising functions, interactive or not, works under lexical scope. Be sure you're running your tests in a buffer with lexical binding. Run the command elisp-enable-lexical-binding in your test buffer if you're not sure. The example you gave definitely works for my use cases. The "interactivity" of a function is tested by the command loop for the presence of the 'interactive-form property on the function symbol. You can see that property by invoking (interactive-form 'switch-to-buffer). It does not impact the advice chain that I've seen. Separately, as a matter of hygiene, I advise using named functions in hooks and advice. You can easily remove them and experiment without trouble.