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

lawlist
  • 18,826
  • 5
  • 37
  • 118
  • 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… –  Jan 02 '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 02 '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 02 '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`: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=19495 – lawlist Jan 03 '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 03 '15 at 22:14
  • @phils -- Those are two great points, and that function `messages-buffer` also puts it in the proper mode -- i.e., `messages-buffer-mode`. I'll revise the draft answer shortly to also check for `bolp` and if not, then insert new line before inserting the string. – lawlist Jan 03 '15 at 22:24

3 Answers3

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"))))))
lawlist
  • 18,826
  • 5
  • 37
  • 118
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))
glucas
  • 20,175
  • 1
  • 51
  • 83
  • 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 03 '15 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

Iqbal Ansari
  • 7,468
  • 1
  • 28
  • 31
  • 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 03 '15 at 16:23