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?

  • 1
    Try (let (message-log-max) (save-buffer)) to disable all messages during save-buffer. – xuchunyang Aug 13 '15 at 7:40
  • You should submit a feature request to the github issue queue for that package. – phils Aug 13 '15 at 7:51
  • 1
    @xuchunyang let binding is not suppressing message. – ChillarAnand Aug 13 '15 at 9:09
  • 2
    @phils I wrote that package and dont know how to suppress messages – ChillarAnand Aug 13 '15 at 9:15

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)


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)
  (save-buffer (current-buffer))
  ;; take care of mtime changes
  (set-buffer-modified-p nil))
  • 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
  • For people skimming: inhibit-message is the key in Emacs 25+ – Hatshepsut Jun 14 '18 at 6:27
  • I added it into my init file but still save message shows up – alper Jul 23 '20 at 13:27

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.")
  • This did not work – alper Jul 23 '20 at 13:26
  • maybe the message you saw is error message. Error-related messages will still be printed, – carlos Jul 27 '20 at 7:19

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.

Bonus: if you really 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)
     (progn ,@body)))

 (message "meaningless")  ; do nothing
 (print [1 2 3])  ; not affected
 (save-buffer))  ; won't display messages in minibuffer
  • 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 6 '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 9 '17 at 0: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 9 '17 at 13:32
(defmacro save-message (&rest body)
  "Save the message in minibuffer; execute BODY; restore the message."
  (let ((saved-message-symbol (make-symbol "saved-message")))
    `(let ((,saved-message-symbol (current-message)))
       (progn ,@body)
       (message ,saved-message-symbol))))

Try it out:

(defun try-out-save-message ()
  "See how `save-message' works out."
  (message (format (propertize "The message I am staring at (with property)."
                               'face 'warning)))
   (message "Message from the auto save function.")))
;; M-x try-out-save-message

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.