7

Whenever a buffer is saved, a message is displayed in minibuffer.

Wrote foo.bar

I use real-auto-save to save modified buffers every 5 seconds. Due to this minibuffer is getting spammed. Sometimes, when I am looking at useful info(like signature, errors or something else), this message overrides it.

Is there a way to disable printing this message in minibuffer?

Chillar Anand
  • 4,042
  • 1
  • 23
  • 52

4 Answers4

7

As was pointed out by @phils the "Wrote file" comes from write-region. If you don't use the inhibit-message variable introduced in Emacs 25, you could replace the original write-region with a function that sets VISIT to neither t nor nil nor a string. As the docstring of write-region tells us, this will avoid displaying the message. In the following example the write-region is replaced temporarily using cl-letf:

(require 'cl-lib)

(fset 'original-write-region (symbol-function 'write-region))
(defun silent-write-region (start end filename &optional append
                                  visit lockname mustbenew)
  "Suppress the \"Wrote file\" message in `write-region'."
  (original-write-region start end filename append 'nomsg lockname mustbenew))

(cl-letf (((symbol-function 'write-region)
           #'silent-write-region))
  (save-buffer (current-buffer))
  ;; take care of mtime changes
  (set-visited-file-modtime)
  (set-buffer-modified-p nil))
mutbuerger
  • 3,434
  • 14
  • 22
  • 1
    Huh. The overloading of `VISIT` isn't the most obvious thing, but I'm *really* not sure how I missed it in the C code -- where it's clearly labelled `quietly` (and has been for 22 years...) – phils Sep 29 '15 at 11:47
  • 1
    For people skimming: `inhibit-message` is the key in Emacs 25+ – Hatshepsut Jun 14 '18 at 06:27
  • I added it into my init file but still save message shows up – alper Jul 23 '20 at 13:27
4

You can use following

(defmacro with-suppressed-message (&rest body)
  "Suppress new messages temporarily in the echo area and the `*Messages*' buffer while BODY is evaluated."
  (declare (indent 0))
  (let ((message-log-max nil))
    `(with-temp-message (or (current-message) "") ,@body)))

(with-suppressed-message (save-buffer))

instead of (save-buffer)

3

There is a var named save-silently in files.el. if you set the var to t I think the message will not show again.

(defvar save-silently nil
  "If non-nil, avoid messages when saving files.
  Error-related messages will still be printed, but all other
  messages will not.")
carlos
  • 151
  • 1
1

Summary:

To suppress messages in the code you write:

  • use with-temp-message.
    • problem of let-binding inhibit-message to nil: current message is still cleared.
  • let-bind message-log-max to nil if you want to disable message logging in *Messages*.

(You can write a wrapper as suggested in @Haruyasu Ueda's answer)

To suppress messages from any single function:

(defun suppress-message-advice-around (fun &rest args)
  (let (message-log-max)
    (with-temp-message (or (current-message) "")
      (apply fun args))))
;; example: suppress any messages from `save-buffer'
(advice-add 'save-buffer :around 'suppress-message-advice-around)
;; undo:
(advice-remove 'save-buffer 'suppress-message-advice-around)

(If you want to know where does a message come from: use debug-on-message.)



the original answer

Just clear the minibuffer afterward.

Don't need to suppress, just clear the minibuffer afterward, if you just don't want to see the message showing in minibuffer.

(defun clear-message ()
  (message nil))
(advice-add 'real-auto-save-buffers :after 'clear-message)
;; replace `real-auto-save-buffers' with the function whose messages
;; should not show in the minibuffer.

From the manual of message:

If the first argument is nil or the empty string, the function clears any existing message;

Basically, what (message nil) does is clearing the current message from the echo area, and it doesn't affect the messages in *Messages*. It works out well when you don't want to see the annoying messages keep showing in the minibuffer.

And, a good thing is, when you are editing the minibuffer (e.g M-x or find-file) and a message shows up, normally you need to type something to make the message disappear. If (message nil) is called, the message will disappear immediately and you can see the original content of the minibufer.


In general, if you don't want to see a particular function showing messages in the minibuffer, you don't need to suppress the messages when it is called, just call (message nil) afterward to clear the current message in minibuffer.


if you want to suppress the messages

Replacing the message function temporarily is much more straight forward:

(defmacro no-message (&rest body)
  "Eval BODY, with `message' doing nothing."
  `(cl-letf (((symbol-function 'message)
              (lambda (&rest args)
                nil)))
     (progn ,@body)))

(no-message
 (message "meaningless")  ; do nothing
 (print [1 2 3])  ; not affected
 (save-buffer))  ; won't display messages in minibuffer
K.Kit
  • 111
  • 3
  • It seems like ChillarAnand wants to see the message that was previously there, not just that they don't want to see the "Wrote foo.bar" message. – zck Oct 06 '17 at 14:51
  • `(message nil)` doesn't touch the existing messages, it just clears the current message from the minibuffer. I have edited my answer. @zck – K.Kit Oct 09 '17 at 00:55
  • Oh, I see now, `(message nil)` doesn't bring back the message that was in the minibuffer when the save message shows up. In this case, maybe `current-messge` can help. – K.Kit Oct 09 '17 at 13:32