Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

In Emacs, there are some cases where I would like to prevent messages from appearing in the minibuffer, mainly pertaining to "Beginning/End of buffer" and "Text is read-only".

Is there any way I can prevent these messages from appearing in the minibuffer?

Also, is there some significant reason I might not want to disable these? At face value, I can just as easily look at the row number and buffer write status on the modeline.

share|improve this question

2 Answers 2

up vote 3 down vote accepted

You can sort of do this from Lisp code. Why "sort of"? Because MESSAGE is a primitive, defined in C, instead of a Lisp function, and, per the Emacs Lisp reference manual, calls to primitives from C code ignore advice.

Therefore, in order to really do a proper job of implementing the functionality you desire, you would need to redefine the MESSAGE primitive as a Lisp function; once you've done so, you can then advise it with code which obtains the string MESSAGE would echo to the minibuffer, compares it with a list of messages you don't want to see, and then calls or doesn't call MESSAGE depending on the result. In theory, this could be accomplished by e.g. (defvar *message-prim* (symbol-function 'message)), and then (defun message (format &rest args) ... (funcall '*message-prim* format args)) -- but SYMBOL-FUNCTION given a primitive argument returns something that isn't actually callable, so the FUNCALL signals a VOID-FUNCTION condition.

However, even if that worked, it still wouldn't really do the trick, because redefining a primitive only guarantees that the redefinition will be used when the function is called from Lisp code; calls in C code may still use the primitive definition. (It is possible for C code to call into Emacs Lisp, and such cases will see the redefinition; it is also, of course, possible for C code to call C code, and such cases will see the original definition.)

I'm vaguely contemplating patching the C code and recompiling Emacs to provide proper message suppression functionality; I don't really need that functionality, but it might prove an interesting exercise, especially since I'm not a C hacker. In the meantime, here's something I whipped up which, when dropped into a file, included from one of your init files, and customized to your taste, will suppress messages originating from Lisp code which exactly match the strings you list for suppression. As long as suppression is enabled, these messages will never appear in the minibuffer; you have the option of whether to suppress them from the *Messages* buffer as well.

;; message-suppression.el
;; a quick hack by Aaron (me@aaron-miller.me), 2013-11-12
;; half a solution for http://superuser.com/questions/669701/emacs-disable-some-minibuffer-messages
;; NB this does nothing until you 
;; M-x customize-group RET message-suppression RET
;; and adjust to taste

(defgroup message-suppression nil
  "Customization options for selective message suppression."
  :prefix "message-suppression")

(defcustom message-suppression-enabled nil
  "Whether or not to suppress messages listed in
`message-suppress-these'."
  :group 'message-suppression
  :tag "Suppress some messages?"
  :type '(choice (const :tag "No" nil)
                 (const :tag "Yes" t)))

(defcustom message-suppression-to-messages-buffer t
  "Whether or not to insert messages suppressed from the
minibuffer into the *Messages* buffer."
  :group 'message-suppression
  :tag "Insert suppressed messages into *Messages* buffer?"
  :type '(choice (const :tag "No" nil)
                 (const :tag "Yes" t)))

(defcustom message-suppression-these nil
  "A list of messages which the `message-except-these' advice
should suppress from being echoed in the minibuffer. Messages
are matched by `member', i.e., only exact strings match.

NB! Per the Emacs manual, calls from C code to primitives (such
as `message') ignore advice entirely, which means some messages
cannot be suppressed by this mechanism. ('Advising
Functions' in the Emacs Lisp Reference Manual, q.v.)"
  :group 'message-suppression
  :tag "Messages to suppress"
  :type '(repeat (string))
  :link '(info-link "(elisp)Advising Functions"))

(defadvice message (around message-suppress-advice)
  "Suppress messages listed in `message-suppress-these' from being
  echoed in the minibuffer."
  (let ((message-string nil)
        (current-buffer nil))
    (if (and message-suppression-enabled
             (length (ad-get-args 0))
             (stringp (car (ad-get-args 0)))
             ;; message-string doesn't get set until here because `format'
             ;; will complain if its first argument isn't a string
             (setq message-string (apply 'format (ad-get-args 0)))
             (member message-string
                     message-suppression-these))
        ;; we won't call `message', but we might echo to *Messages*
        (and message-suppression-to-messages-buffer
             (progn
               (setq current-buffer (current-buffer))
               (switch-to-buffer (get-buffer-create "*Messages*"))
               (goto-char (point-max))
               (insert (make-string 1 10))
               (insert message-string)
               (switch-to-buffer current-buffer)))
      ad-do-it)))

(ad-activate 'message)

I've tested this to work with messages which are actually generated from Lisp code, e.g. the "You didn't specify a function" complaint echoed by DESCRIBE-FUNCTION when you give it an empty string argument. Unfortunately, the messages you mention wanting to suppress, such as "Beginning of buffer", "End of buffer", and "Text is read-only", appear all to originate from C code, which means you won't be able to suppress them by this method.

If I ever do get around to the source patch, it'll (probably) be against Emacs 24.3, and I'll update this answer with information on how to go about using it.

share|improve this answer

You are apparently asking for a way to selectively inhibit certain messages. The answer for that is that you would need to redefine or advise the code that issues those particular messages.

To prevent all messages, for example for the duration of some code, you can use flet or cl-flet to redefine function message locally to (function) ignore. Or use the technique used in edt-electric-helpify: save the original definition of message, fset to ignore, re-fset it back to the original def (though it is better to use unwind-protect if you do that).

share|improve this answer
    
Sorry, but would you be able to help me on how I can search for these error messages? At this point, it almost feels like it's more trouble disabling the messages than there is from keeping them. –  mellowmaroon Nov 5 '13 at 19:50
    
To search for "these error messages", use grep or A in Dired. Search for the error message text in the Emacs Lisp source files (and possibly also in the Emacs C files, if you have them available). HTH. –  Drew Nov 5 '13 at 21:13

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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