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.
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).