nadvice.el, I am trying to add a
:filter-args advice to an interactive function. Is it somehow possible for it to detect, whether the advised function has been called interactively?
I was trying to use
M-x describe-function called-interactively-p says:
This function is very brittle, it may fail to return the intended result when the code is debugged, advised, or instrumented in some form. [...]
Instead of using this function, it is cleaner and more reliable to give your function an extra optional argument whose ‘interactive’ spec specifies non-nil unconditionally ("p" is a good way to do this), or via
(not (or executing-kbd-macro noninteractive)).
Sadly, neither works:
- The brittleness of
called-interactively-pmakes it useless here; Only around advise will detect interactiveness correctly with
called-interactively-p, but then the original function doesn't see the interactive call that way anymore.
- The suggested workaround is actually wrong.
noninteractivedetermines whether the emacs session is interactive, not whether the command was called interactively.
Minimal working example for
(defun tmpdemo-command (&rest args) (interactive '(was called interactively)) (message "tmpdemo-command: %-3S %-3S" (called-interactively-p) (not (or executing-kbd-macro noninteractive))) (message "%S" args)) (advice-add #'tmpdemo-command :around #'tmpdemo-around) (advice-add #'tmpdemo-command :filter-args #'tmpdemo-filter-args) (defun tmpdemo-around (oldfun &rest args) (message "tmpdemo-around: %-3S %-3S" (called-interactively-p) (not (or executing-kbd-macro noninteractive))) (apply oldfun args)) (defun tmpdemo-filter-args (args) (message "tmpdemo-filter-args: %-3S %-3S" (called-interactively-p) (not (or executing-kbd-macro noninteractive))) args)
When executing it interactively as
tmpdemo-filter-args: nil t tmpdemo-around: t t <-- Only the around advise sees the tmpdemo-command: nil t expected result. (was called interactively)
When running it non-interactively as
tmpdemo-filter-args: nil t <-- the suggested workaround gives tmpdemo-around: nil t the wrong result!! tmpdemo-command: nil t (noninteractive)