Advising an emacs interactive function: before

advising-functions, defadvice, emacs

Solution

artscan answered his own question with a workable answer, but it's a bit incomplete and misleading. This also involves `'interactive`, which can be confusing in and of itself - in that it looks like it is defined inside the body of the command, but is actually used before the function is entered - and before any advice is executed (unless that advice has `'interactive` calls...)

The documentation for advice lacks a number of details that would help in this situation, so the better place to look is actually the source: `advice.el`. Look at that and find the comment section `@ Foo games: An advice tutorial`. You can also find the source in your Emacs itself with M-x find-library advice RET.

Specifically, for this problem, look at the section in `advice.el` labeled `@@ Advising interactive behavior:` - because that's exactly what you're trying to do.

If you read it closely, you'll notice that the advice does not need to be of the form `around`, but can be `before` as well, and it can be `after` - though that's just asking for trouble. This is because the `interactive` is (and has to be) treated special.

So, the following code works (note the `before`):

(defadvice find-dired (before eab-find-dired (dir args) activate)
  "ignore find-args, hard code \"-iname '**'\""
  (interactive
   (list (read-directory-name "Run find in directory: " nil "" t)
         (read-string "Run find (with args): " '("-iname '**'" . 10)
                      '(find-args-history . 1)))))

Probably a cleaner way to do this, as others suggested, is writing your own function, and I think the easiest is Lindydancer's answer.

Advice is a pretty enticing tool, but is easy to overuse. I wouldn't go as far as saying it is dangerous, but should be used sparingly. It seems to be best used when writing your own function doesn't work - for instance, changing the behavior of a function that is called by code you can't modify. I think good examples of this situation can be found here, here, and here (to toot my own horn).

Problem

I want to before-advice some function, which uses interactive arguments, e.g. `find-dired`: ``` (defadvice find-dired (before eab-find-dired activate) (message "before!") (setq find-args '("-iname '**'" . 10))) ``` But emacs executes this advice only after `find-dired` interactive session and I can't setup `find-args` before. How to resolve the contradiction? Upd. Note that `defadvice` macro is deprecated.

Original source

Related problems