10

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:

https://superuser.com/questions/669701/emacs-disable-some-minibuffer-messages

6
  • 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…
    – user227
    Jan 2, 2015 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, 2015 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, 2015 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, 2015 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, 2015 at 22:14

3 Answers 3

4

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"))))))
3

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))
    (toggle-some-mode))
1
  • 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, 2015 at 17:23
2

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

1
  • 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, 2015 at 16:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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