Is it possible to send the output from a process-filter to the *Messages* buffer and suppress that message output from appearing in the echo area, such that I am able to simultaneously use interactive commands without having the minibuffer-prompt being erased by the ongoing subpress filter output?

(defun rsync-process-filter (proc string)
  (when (not (or
      (string-match "files...\r" string)
      (string-match "files to consider\n" string)))
    (message "%s" string)))

EDIT (January 3, 2015):  The following is a link to a similar question, however, I have not yet been able to make it work with a process string where the exact string is unkown -- the title of the thread is: Emacs - Disable Some Minibuffer Messages:


  • I don't think that you can. Why not just log to a different buffer? That's what most modes that deal with processes do… – lunaryorn Jan 2 '15 at 12:35
  • @lunaryorn -- Thank you for the suggestion -- a dedicated buffer is a valid option to resolve the issue. There are a few process outputs that I have a personal preference for being sent to the *Messages* buffer -- synchronization related projects is one of them. There are still a couple of things I haven't tried (because I thought there may have been a built-in solution), such as making the *Messages* buffer temporarily writable inhibit-read-only and using insert at point-max -- I don't know if that will show up in the echo area as well. I'll work on it again this evening . . . – lawlist Jan 2 '15 at 17:01
  • One note of interest is that the C functions for messaging are very much separated by "echo" and "logging" concerns, but that distinction is not exposed to elisp. Perhaps you could M-x report-emacs-bug and request this as a feature? – phils Jan 2 '15 at 22:30
  • @phils | @lunaryorn: I was able to achieve the desired effect by using (let ((inhibit-read-only t)) (with-current-buffer (get-buffer-create "*Messages*") (goto-char (point-max)) (insert string))) and I posted a draft answer, which will be eligable for acceptance after the mandatory waiting period on a user's own question has lapsed. I filed a feature request with report-emacs-bug: debbugs.gnu.org/cgi/bugreport.cgi?bug=19495 – lawlist Jan 3 '15 at 17:56
  • lawlist: I wasn't going to suggest that approach because you might run afoul of the logic for handling duplicate messages, etc. (But it might also be fine; I don't actually know.) You should probably use (messages-buffer) to obtain the buffer, if you stick with this method, and note that (point-max) won't always be the beginning of a new line (e.g. use C-g). – phils Jan 3 '15 at 22:14

You can suppress display in the minibuffer by setting minibuffer-message-timeout to 0.

For example, I use something like this in a few places where I want to toggle a minor mode while in a minibuffer prompt (like ido find-file) without being interrupted by a 'mode enabled' message:

(let ((minibuffer-message-timeout 0))
  • Thank you for the suggestion; however, this did not achieve the desired affect. The ongoing process output printing with (let ((minibuffer-message-timeout 0)) (message "%s" string)) still displays in the echo-area / minibuffer when typing interactive functions like execute-extended-command or switch-to-buffer-other-window -- i.e., the prompt and suggested completions get erased by the process output messages. – lawlist Jan 3 '15 at 17:23

First Rough Draft (January 3, 2015):  Revised initial draft based on the helpful comment of @phils regarding using the function messages-buffer to locate or create the appropriate buffer (and put it into messages-buffer-mode); and, added a check for whether point-max is at the beginning of the line (if not, then inset a new line before inserting the message string).

EDIT (January 4, 2015):  There are situations where the inserted string may not necessarily end in a new line, and the function message does not have a check to ensure it is at the beginning of a new line, so we take care of that in this function. Thus, at any point when message inserts a new line, said line will begin at flush-left of the buffer.

(defun rsync-process-filter (proc string)
  (let ((inhibit-read-only t))
    (when (not (or
        (string-match "files...\r" string)
        (string-match "files to consider\n" string)))
      (with-current-buffer (messages-buffer)
        (goto-char (point-max))
        (when (not (bolp))
          (insert "\n"))
        (insert string)
        (when (not (bolp))
          (insert "\n"))))))

Going through the docstring of message it seems it should be possible to achieve what you want by calling message with a nil argument immediately after calling message with your desired content. From the docstring of message

If the first argument is nil or the empty string, the function clears any existing message; this lets the minibuffer contents show.

So modifying your function to something like the following should work

(defun rsync-process-filter (proc string)
  (when (not (or
      (string-match "files...\r" string)
      (string-match "files to consider\n" string)))
    (message "%s" string)
    (message nil)))

I tested it by doing the following

(defun test ()
  (message "%s" "Test")
  (message nil))

(run-at-time 5 5 #'test)

And it seems to work

  • Thank you for the suggestion. This idea, when tested with a running process output to the *Messages* buffer and then calling the interactive command execute-extended-command, shows the following: the interactive prompt (i.e., M-x and any partial completions) and the output from the process -- i.e., the two switch back and forth at light speed, but flickering between the two is discernible. This appears to be the case because the particular process at issue is constantly spitting out new messages, and that new message is being displayed for a fraction of a second in the echo area. – lawlist Jan 3 '15 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.