Following on from an answer to another question about the new advice system:
In old-style advice.el
, it was possible to manipulate individual members of an advised function's argument list, without making any assertions regarding those members not so manipulated. For example, the following advice:
(defadvice ansi-term (around prompt-for-name last)
(let ((name (read-from-minibuffer "Tag: ")))
(and (not (string= name ""))
(ad-set-arg 1 (concat "Term: " name)))
ad-do-it))
allows the (optional) provision of a buffer-name argument to an ansi-term
call, while ansi-term
will still obtain its first argument by prompting according to its own interactive form.
(For later reference, ansi-term
's signature is (PROGRAM &optional BUFFER-NAME)
, and its interactive form prompts for PROGRAM with several possible defaults, but does nothing regarding BUFFER-NAME.)
I'm not sure whether or not this is possible in nadvice.el
. If it is, I'm not certain how it can be done. I've found a couple of ways to replace an advised function's argument list.
For example, from *info* (elisp) Advice combinators:
`:filter-args' Call FUNCTION first and use the result (which should be a list) as the new arguments to pass to the old function. More specifically, the composition of the two functions behaves like: (lambda (&rest r) (apply OLDFUN (funcall FUNCTION r)))
Other combinators provide similar capabilities, and the common thread among them is that, while a function's argument list may be replaced, truncated, extended, et al, there's no apparent way for function advice to modify the argument at a given position in the list without asserting anything about the rest of it.
In the case under discussion, it appears impossible for the advice author to pass ansi-term
only a buffer name, because it's not possible to construct a list which has a value in position 1 but nothing, not even nil
, in position 0. In the general case, it appears impossible for the advice author to arbitrarily modify arguments beyond position 0.
This seems unfortunate in that, in order to produce a similar effect, it's necessary to copy-paste code: specifically, either I can copy ansi-term
's interactive form and extend it to my taste, or I can copy ansi-term
altogether and extend it likewise. In either case, I now must redefine part of the Emacs Lisp distribution in my init file, which strikes me as undesirable in terms of both durability and aesthetics.
My question, then, is: Can this sort of argument list mangling be done with nadvice.el
? If so, how?