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.
Emacs picks up the interactive
specification before it calls the function.
In general, it is a bad idea to use defadvice
, so instead I would suggest that you define your own function and bind it to an appropriate key. For example:
(defun my-find-dired ()
(interactive)
(let ((find-args '("-iname '**'" . 10)))
(call-interactively 'find-dired)))
Of course, you can also simply do the following, if you think that this setting is something that you want for all calls to find-dired
:
(setq find-args '("-iname '**'" . 10))
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With