Subject: Re: bug#77257: inhibit-message should inhibit echo area clearing too

From: Eli Zaretskii <[email-masked]>
Date: Sun, 30 Mar 2025 09:41:18 +0300

> From: Daniel Colascione <[email-masked]>
> Date: Tue, 25 Mar 2025 14:58:35 -0400
> 
> 
> (let ((inhibit-message t)) (message "blah")) has the effect of clearing
> the echo area.  I'd expect the semantic of inhibit-message to be
> preventing all visible side effects of message --- not just some
> of them.

We need to preserve the current meaning of t as the value of
inhibit-message, to avoid backward-incompatible changes.  So I added a
third value to mean suppress clearing of the echo-area as well.  Does
the patch below look right?

diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index de06391..6eba3d7 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -405,7 +405,10 @@ Displaying Messages
 @defvar inhibit-message
 When this variable is non-@code{nil}, @code{message} and related functions
 will not display any messages in the Echo Area.  Echo-area messages
-are still logged in the @file{*Messages*} buffer, though.
+are still logged in the @file{*Messages*} buffer, though.  If the value
+is the symbol @code{all}, it also suppresses the clearing of the
+echo-area, such as when @code{message} is called with a @code{nil} or
+empty argument.
 @end defvar
 
 @defmac with-temp-message message &rest body
diff --git a/etc/NEWS b/etc/NEWS
index afa45c5..d3e7903 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -2045,6 +2045,12 @@ This function inserts the special EVENT into the input event queue.
 This event is sent when the device running Emacs enters or leaves the
 sleep state.
 
++++
+** 'inhibit-message' can now inhibit clearing of the echo-area.
+Binding 'inhibit-message' to the special value 'all' will suppress both
+the display of messages and the clearing of the echo-area, such as
+caused by calling 'message' with a nil argument.
+
 ** Function aliases obsolete since Emacs 23.2 have been removed:
 'advertised-undo', 'advertised-widget-backward', and
 'dired-advertised-find-file'.
diff --git a/src/xdisp.c b/src/xdisp.c
index f2b158f..7b894cd 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -12386,7 +12386,7 @@ message3 (Lisp_Object m)
       message_dolog (buffer, nbytes, true, multibyte);
       SAFE_FREE ();
     }
-  if (! inhibit_message)
+  if (NILP (Vinhibit_message))
     message3_nolog (m);
 }
 
@@ -13405,7 +13405,7 @@ clear_message (bool current_p, bool last_displayed_p)
 {
   Lisp_Object preserve = Qnil;
 
-  if (current_p)
+  if (current_p && !EQ (Vinhibit_message, Qall))
     {
       if (FUNCTIONP (Vclear_message_function)
           /* FIXME: (bug#63253) Same as for `set-message-function` above.  */
@@ -37582,15 +37582,17 @@ syms_of_xdisp (void)
 settings of `scroll-conservatively'.  */);
   scroll_minibuffer_conservatively = true; /* bug#44070 */
 
-  DEFVAR_BOOL ("inhibit-message", inhibit_message,
-              doc:  /* Non-nil means calls to `message' are not displayed.
-They are still logged to the *Messages* buffer.
+  DEFVAR_LISP ("inhibit-message", Vinhibit_message,
+              doc:  /* Non-nil means suppress display of `message' text.
+The messages are still logged to the *Messages* buffer.
+If the value is `all', also suppress clearing the echo-area when
+the `message' function is called with an empty or nil argument.
 
 Do NOT set this globally to a non-nil value, as doing that will
 disable messages everywhere, including in I-search and other
 places where they are necessary.  This variable is intended to
 be let-bound around code that needs to disable messages temporarily. */);
-  inhibit_message = false;
+  Vinhibit_message = Qnil;
 
   message_dolog_marker1 = Fmake_marker ();
   staticpro (&message_dolog_marker1);