mike3996
mike3996

Reputation: 17517

How to redirect message/echo output to a buffer in Emacs?

I'm writing a couple of helper functions for my use. They first call up org-publish-project and then call external scripts on that output. I'd like to collect all output from the execution in a temp buffer that pops up.

The external stuff is easier. The function shell-command accepts a second argument about a buffer where to send stdout. But org-publish-project only echoes stuff to minibuffer and it shows on *Messages* if anywhere. Could I somehow redirect all echoes to a given buffer?

Upvotes: 5

Views: 2056

Answers (3)

ens
ens

Reputation: 1098

To temporarily redirect all message output to the current buffer, do the following:

(defvar orig-message (symbol-function 'message))

(defun message-to-buffer (format-string &rest args)
  (insert (apply 'format format-string args) "\n"))

(defmacro with-messages-to-buffer (&rest body)
  `(progn (fset 'message (symbol-function 'message-to-buffer))
          (unwind-protect
              (progn ,@body)
            (fset 'message orig-message))))

;; Usage
(with-messages-to-buffer
 (message "hello"))

Upvotes: 0

Stefan
Stefan

Reputation: 28541

No, there's no such redirect, sadly. You can try to advise the message function, which will catch many of those messages, tho not necessarily all of them.

(defvar my-message-output-buffer nil)

(defadvice message (around my-redirect activate)
  (if my-message-output-buffer
      (with-current-buffer my-message-output-buffer
        (insert (apply #'format (ad-get-args 0))))
    ad-do-it))

Upvotes: 6

Depending on what org-publish-project internally uses to display messages, the following might work:

(with-output-to-temp-buffer "*foo*"
  (do-stuff))
(pop-to-buffer "*foo*")

Upvotes: 4

Related Questions