Search code examples
elispdefadvice

Advicing message not working


(defun my-message (format-string &rest args)
  (apply 'message
         (concat "my-message: " format-string)
         args))

(my-message "abc %d" 123)
;; ==> "my-message: abc 123"
(message "abc %d" 123)
;; ==> "abc 123"

(advice-add 'message :around 'my-message)
;;(advice-remove 'message 'my-message)

After advice-add to message, an error Wrong type argument: sequencep, #<subr message> is signaled. What is the problem?


Solution

  • Since you're using :around advice, your my-message function is getting the original function as its first argument. Your code is missing this argument and is instead treating the first argument as the message format string. Change your my-message to specify the additional argument:

    (defun my-message (orig-fun format-string &rest args)
      (apply orig-fun
             (concat "my-message: " format-string)
             args))
    

    and then the advice will work as expected. Note how this version calls orig-fun instead of hard-coding 'message as the apply target.

    You don't need :around advice for this case, though. All you're doing is modifying the format string, so you could instead use :filter-args, which allows you to modify arguments before they're passed to the original function. Here's an example that works for your case:

    (defun my-message (args)
      (nconc (list (concat "my-message: " (car args))) (cdr args)))
    (advice-add 'message :filter-args #'my-message)