1

Is it possible to use advice to not only run your function first, but also prevent the advised function from running at all?

For example, say a command ordinarily calls read-from-minibuffer to get a return value:

(defun get-name ()
  (read-from-minibuffer "Enter your name: "))

Let's say, in this example, my name never canges. Entering it manually is time-consuming. Can I use the advice system to intercept the call to read-from-minibuffer and return my own value?

For example, something like:

(defun return-my-name (&rest args)
  "Jack")

(defun quick-get-name ()
  ;; Add the intercepting advice, call the function, then remove the advice.
  (advice-add 'read-from-minibuffer :intercept 'return-my-name)
  (get-name)
  (advice-remove 'read-from-minibuffer 'return-my-name))

The key behaviour I need is to be able to fall back on the original function depending on the input. For example, I might want to intercept the command if the prompt is asking for a name, but not if it is asking for some other information, like age:

(defun return-my-name (prompt &rest args)
  (if (eq prompt "Enter your name: ")
      "Jack"
    (read-from-minibuffer prompt))

Anyone know if the advice system is capable of this? Can it be done some other way, for example using aliases?

JCC
  • 989
  • 5
  • 15

1 Answers1

5

Of course you can. You can do it with:

(advice-add 'read-from-minibuffer :around #'return-my-name)
(defun return-my-name (orig-fun &rest args)
  (let ((orig-val (apply orig-fun args)))
    <return-the-new-value>))

Or you can do it with

(advice-add 'read-from-minibuffer :filter-return #'return-my-name)
(defun return-my-name (orig-val)
  <return-the-new-value>)

depending on how much control you want to have.

Stefan
  • 26,154
  • 3
  • 46
  • 84
  • In the filter-return version, the original function will still prompt iiuc – YoungFrog Aug 25 '16 at 07:37
  • I am stating the obvious but in the :around version you are free to not use orig-fun. – YoungFrog Aug 25 '16 at 07:40
  • Yes, in the `:filter-return` case you only get to modify the return value (and only based on the default return value, i.e. without knowing what were the arguments), whereas in the `:around` you get to do whatever you want, including calling the `orig-fun` as many times as you want (including 0 times), with whatever other parameters you like and combine the result however you please. – Stefan Aug 25 '16 at 12:07
  • This is perfect! Thank you Stefan. YoungFrog, I think that's a helpful caveat. Makes it easier to understand the meaning of the snippets. Cheers guys! – JCC Aug 25 '16 at 13:17