Subject: 29.0.50; [PATCH] Respect inhibit-message

From: [email-masked]
Date: Tue, 25 Oct 2022 17:03:53 -0400

It's borderline criminal that the echo area gets cleared
when inhibit-message is true.

emacs -Q -l cl-lib --eval " \
(let ((dont \"dont clear me\!\")) \
  (message dont) \
  (let ((inhibit-message t)) \
    (message \"nice try\") \
    (cl-assert (equal (current-message) dont) t)))"

>From 79e43be851ffd51e7353900207c254afd6123e84 Mon Sep 17 00:00:00 2001
From: dickmao <[email-masked]>
Date: Tue, 25 Oct 2022 16:47:09 -0400
Subject: [PATCH] Respect inhibit-message

That means not blithely clearing the echo area.

* doc/lispref/display.texi (Displaying Messages): Revert 164a7eb.
* lisp/minibuffer.el (clear-minibuffer-message): Revert 164a7eb.
* src/xdisp.c (message3): Remove errant clear_message() from 2004.
(clear_message): Revert 164a7eb.
(syms_of_xdisp): Revert 164a7eb.
* test/src/xdisp-tests.el (xdisp-tests--respect-inhibit-message):
Test it.
---
 doc/lispref/display.texi |  5 +----
 lisp/minibuffer.el       |  6 +-----
 src/xdisp.c              | 28 +++++++---------------------
 test/src/xdisp-tests.el  |  9 +++++++++
 4 files changed, 18 insertions(+), 30 deletions(-)

diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi
index 15cd5518d91..b7e39679bcb 100644
--- a/doc/lispref/display.texi
+++ b/doc/lispref/display.texi
@@ -337,10 +337,7 @@ Displaying Messages
 Usually this function is called when the next input event arrives
 after displaying an echo-area message.  The function is expected to
 clear the message displayed by its counterpart function specified by
-@code{set-message-function}, but doesn't have to.  If the function
-wants the echo area to remain uncleared, it should return the symbol
-@code{dont-clear-message}; any other value will result in the echo
-area being cleared.
+@code{set-message-function}.
 
 The default value is the function that clears the message displayed in
 an active minibuffer.
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index a9f72d600de..98b68443c38 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -861,11 +861,7 @@ clear-minibuffer-message
       (setq minibuffer-message-timer nil))
     (when (overlayp minibuffer-message-overlay)
       (delete-overlay minibuffer-message-overlay)
-      (setq minibuffer-message-overlay nil)))
-
-  ;; Return nil telling the caller that the message
-  ;; should be also handled by the caller.
-  nil)
+      (setq minibuffer-message-overlay nil))))
 
 (setq clear-message-function 'clear-minibuffer-message)
 
diff --git a/src/xdisp.c b/src/xdisp.c
index 1f7ac269e4e..24e129f13f8 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -11948,7 +11948,6 @@ message_log_check_duplicate (ptrdiff_t prev_bol_byte, ptrdiff_t this_bol_byte)
 void
 message3 (Lisp_Object m)
 {
-  clear_message (true, true);
   cancel_echoing ();
 
   /* First flush out any partial line written with print.  */
@@ -12966,23 +12965,18 @@ set_message_1 (void *a1, Lisp_Object string)
 void
 clear_message (bool current_p, bool last_displayed_p)
 {
-  Lisp_Object preserve = Qnil;
-
   if (current_p)
     {
+      echo_area_buffer[0] = Qnil;
+      message_cleared_p = true;
+
       if (FUNCTIONP (Vclear_message_function))
         {
           specpdl_ref count = SPECPDL_INDEX ();
           specbind (Qinhibit_quit, Qt);
-          preserve = safe_call (1, Vclear_message_function);
+          safe_call (1, Vclear_message_function);
           unbind_to (count, Qnil);
         }
-
-      if (!EQ (preserve, Qdont_clear_message))
-        {
-          echo_area_buffer[0] = Qnil;
-          message_cleared_p = true;
-        }
     }
 
   if (last_displayed_p)
@@ -37171,20 +37165,12 @@ syms_of_xdisp (void)
 (which controls how error messages are displayed).  */);
   Vset_message_function = Qnil;
 
-  DEFSYM (Qdont_clear_message, "dont-clear-message");
   DEFVAR_LISP ("clear-message-function", Vclear_message_function,
 	       doc: /* If non-nil, function to clear echo-area messages.
 Usually this function is called when the next input event arrives.
-It is expected to clear the message displayed by its counterpart
-function specified by `set-message-function'.
-
-The function is called without arguments.
-
-If this function returns a value that isn't `dont-clear-message', the
-message is cleared from the echo area as usual.  If this function
-returns `dont-clear-message', this means that the message was already
-handled, and the original message text will not be cleared from the
-echo area.  */);
+The function is called without arguments.  It is expected to clear the
+message displayed by its counterpart function specified by
+`set-message-function'.  */);
   Vclear_message_function = Qnil;
 
   DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
diff --git a/test/src/xdisp-tests.el b/test/src/xdisp-tests.el
index 6ff64d0431a..9e3ad3bd6eb 100644
--- a/test/src/xdisp-tests.el
+++ b/test/src/xdisp-tests.el
@@ -179,4 +179,13 @@ test-messages-buffer-name
         (buffer-string)))
     "foo\n")))
 
+(ert-deftest xdisp-tests--respect-inhibit-message ()
+  "It's borderline criminal that inhibit-message still clears echo area."
+  (skip-unless (not noninteractive))
+  (let ((dont "dont clear me!"))
+    (message dont)
+    (let ((inhibit-message t))
+      (message "nice try")
+      (should (equal (current-message) dont)))))
+
 ;;; xdisp-tests.el ends here
-- 
2.36.1

In Commercial Emacs 0.3.1snapshot 7273a2a in dev (upstream 29.0.50,
x86_64-pc-linux-gnu) built on dick
Repository revision: 7273a2a596b43da83866e42dbbbe4ea28cabf7bd
Repository branch: dev
Windowing system distributor 'The X.Org Foundation', version 11.0.12013000
System Description: Ubuntu 20.04.4 LTS

Configured using:
 'configure WERROR_CFLAGS=-Werror --prefix=/home/dick/.local
 --with-tree-sitter CC=gcc-10
 PKG_CONFIG_PATH=/home/dick/.local/lib/pkgconfig CXX=gcc-10'
Configured features:
CAIRO DBUS FREETYPE GIF GLIB GMP GNUTLS GSETTINGS HARFBUZZ JPEG JSON
TREE_SITTER LCMS2 LIBSELINUX LIBXML2 MODULES NOTIFY INOTIFY PDUMPER PNG
RSVG SECCOMP SOUND THREADS TIFF TOOLKIT_SCROLL_BARS WEBP X11 XDBE XIM
XINPUT2 XPM GTK3 ZLIB
Important settings:
  value of $LANG: en_US.UTF-8
  locale-coding-system: utf-8-unix

Major mode: Magit

Minor modes in effect:
  global-git-commit-mode: t
  shell-dirtrack-mode: t
  projectile-mode: t
  flx-ido-mode: t
  global-hl-line-mode: t
  hl-line-mode: t
  winner-mode: t
  override-global-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  show-paren-mode: t
  mouse-wheel-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  buffer-read-only: t
  column-number-mode: t
  line-number-mode: t
  transient-mark-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t

Load-path shadows:
/home/dick/xlsp/scratch hides /home/dick/org-gcal.el/scratch
/home/dick/gomacro-mode/gomacro-mode hides /home/dick/.emacs.d/elpa/gomacro-mode-20200326.1103/gomacro-mode
/home/dick/.emacs.d/elpa/go-rename-20190805.2101/go-rename hides /home/dick/.emacs.d/elpa/go-mode-1.6.0/go-rename
/home/dick/.emacs.d/elpa/go-guru-20181012.330/go-guru hides /home/dick/.emacs.d/elpa/go-mode-1.6.0/go-guru
/home/dick/.emacs.d/elpa/hydra-20170924.2259/lv hides /home/dick/.emacs.d/elpa/lv-0.1.0.1snapshot20200507.1518/lv
/home/dick/org-gcal.el/org-gcal hides /home/dick/.emacs.d/elpa/org-gcal-0.3/org-gcal
/home/dick/.emacs.d/elpa/request-deferred-0.2.0/request-deferred hides /home/dick/.emacs.d/elpa/request-0.3.3/request-deferred
/home/dick/.emacs.d/elpa/chess-2.0.5/_pkg hides /home/dick/.local/share/emacs/site-lisp/_pkg
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-pos hides /home/dick/.local/share/emacs/site-lisp/chess-pos
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-module hides /home/dick/.local/share/emacs/site-lisp/chess-module
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ucb hides /home/dick/.local/share/emacs/site-lisp/chess-ucb
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-scid hides /home/dick/.local/share/emacs/site-lisp/chess-scid
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-puzzle hides /home/dick/.local/share/emacs/site-lisp/chess-puzzle
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-irc hides /home/dick/.local/share/emacs/site-lisp/chess-irc
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-network hides /home/dick/.local/share/emacs/site-lisp/chess-network
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-autosave hides /home/dick/.local/share/emacs/site-lisp/chess-autosave
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-engine hides /home/dick/.local/share/emacs/site-lisp/chess-engine
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-tutorial hides /home/dick/.local/share/emacs/site-lisp/chess-tutorial
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-german hides /home/dick/.local/share/emacs/site-lisp/chess-german
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-file hides /home/dick/.local/share/emacs/site-lisp/chess-file
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-random hides /home/dick/.local/share/emacs/site-lisp/chess-random
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-stockfish hides /home/dick/.local/share/emacs/site-lisp/chess-stockfish
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-pgn hides /home/dick/.local/share/emacs/site-lisp/chess-pgn
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-kibitz hides /home/dick/.local/share/emacs/site-lisp/chess-kibitz
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-eco hides /home/dick/.local/share/emacs/site-lisp/chess-eco
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-display hides /home/dick/.local/share/emacs/site-lisp/chess-display
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-var hides /home/dick/.local/share/emacs/site-lisp/chess-var
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-test hides /home/dick/.local/share/emacs/site-lisp/chess-test
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ply hides /home/dick/.local/share/emacs/site-lisp/chess-ply
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-message hides /home/dick/.local/share/emacs/site-lisp/chess-message
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ics1 hides /home/dick/.local/share/emacs/site-lisp/chess-ics1
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-phalanx hides /home/dick/.local/share/emacs/site-lisp/chess-phalanx
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-game hides /home/dick/.local/share/emacs/site-lisp/chess-game
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-log hides /home/dick/.local/share/emacs/site-lisp/chess-log
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-plain hides /home/dick/.local/share/emacs/site-lisp/chess-plain
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-perft hides /home/dick/.local/share/emacs/site-lisp/chess-perft
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-glaurung hides /home/dick/.local/share/emacs/site-lisp/chess-glaurung
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ai hides /home/dick/.local/share/emacs/site-lisp/chess-ai
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-fruit hides /home/dick/.local/share/emacs/site-lisp/chess-fruit
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-uci hides /home/dick/.local/share/emacs/site-lisp/chess-uci
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-epd hides /home/dick/.local/share/emacs/site-lisp/chess-epd
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-database hides /home/dick/.local/share/emacs/site-lisp/chess-database
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-link hides /home/dick/.local/share/emacs/site-lisp/chess-link
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-transport hides /home/dick/.local/share/emacs/site-lisp/chess-transport
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-none hides /home/dick/.local/share/emacs/site-lisp/chess-none
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-polyglot hides /home/dick/.local/share/emacs/site-lisp/chess-polyglot
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-crafty hides /home/dick/.local/share/emacs/site-lisp/chess-crafty
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-chat hides /home/dick/.local/share/emacs/site-lisp/chess-chat
/home/dick/.emacs.d/elpa/chess-2.0.5/chess hides /home/dick/.local/share/emacs/site-lisp/chess
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-images hides /home/dick/.local/share/emacs/site-lisp/chess-images
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-gnuchess hides /home/dick/.local/share/emacs/site-lisp/chess-gnuchess
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-fen hides /home/dick/.local/share/emacs/site-lisp/chess-fen
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ics hides /home/dick/.local/share/emacs/site-lisp/chess-ics
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-ics2 hides /home/dick/.local/share/emacs/site-lisp/chess-ics2
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-common hides /home/dick/.local/share/emacs/site-lisp/chess-common
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-input hides /home/dick/.local/share/emacs/site-lisp/chess-input
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-announce hides /home/dick/.local/share/emacs/site-lisp/chess-announce
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-clock hides /home/dick/.local/share/emacs/site-lisp/chess-clock
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-sound hides /home/dick/.local/share/emacs/site-lisp/chess-sound
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-sjeng hides /home/dick/.local/share/emacs/site-lisp/chess-sjeng
/home/dick/.emacs.d/elpa/chess-2.0.5/chess-algebraic hides /home/dick/.local/share/emacs/site-lisp/chess-algebraic
/home/dick/.emacs.d/elpa/transient-0.3.7snapshot/transient hides /home/dick/.local/share/emacs/0.3.1/lisp/transient

Features:
(shadow emacsbug texinfo texinfo-loaddefs emacs-news-mode goto-addr ivy
delsel colir ivy-overlay ffap scheme nndoc debbugs-gnu debbugs-compat
debbugs soap-client rng-xsd rng-dt rng-util xsd-regexp skeleton
ibuf-macs loaddefs-gen tar-mode arc-mode archive-mode tramp-archive
tramp-gvfs tramp-cache time-stamp zeroconf tramp tramp-loaddefs trampver
tramp-integration tramp-compat ls-lisp elpaso-disc web-server
web-server-status-codes ghub-graphql treepy gsexp ghub cc-mode cc-fonts
cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs
completion dumb-jump canlock bbdb-message footnote nnselect whitespace
flow-fill ag find-dired jka-compr cus-start files-x git-rebase
magit-extras face-remap magit-patch-changelog magit-patch
magit-submodule magit-obsolete magit-blame magit-stash magit-reflog
magit-bisect magit-push magit-pull magit-fetch magit-clone magit-remote
magit-commit magit-sequence magit-notes magit-worktree magit-tag
magit-merge magit-branch magit-reset magit-files magit-refs magit-status
magit magit-repos magit-apply magit-wip magit-log which-func imenu
edebug magit-diff git-commit log-edit add-log magit-core magit-margin
magit-transient magit-process with-editor shell pcomplete server
magit-mode transient smerge-mode diff bug-reference gnus-html pulse
elpaso elpaso-admin elpaso-milky elpaso-defs timer-list novice disass
mule-util display-line-numbers shortdoc help-fns radix-tree cl-print
debug backtrace url-queue google-translate misearch multi-isearch qp
sort smiley shr-color mm-archive gnus-async gnus-ml gravatar dns
mail-extr textsec uni-scripts idna-mapping ucs-normalize uni-confusable
textsec-check gnus-notifications gnus-fun notifications gnus-kill
gnus-dup disp-table utf-7 url-cache benchmark nnrss nnfolder nndiscourse
rbenv nnhackernews nntwitter nntwitter-api bbdb-gnus gnus-demon nntp
nnmairix nnml nnreddit gnus-topic url-http url-auth url-gw
network-stream nsm request virtualenvwrapper gud s json-rpc python
gnus-score score-mode gnus-bcklg gnus-srvr gnus-cite anaphora bbdb-mua
bbdb-com bbdb bbdb-site timezone gnus-delay gnus-draft gnus-cache
gnus-agent gnus-msg gnus-art mm-uu mml2015 mm-view mml-smime smime
gnutls dig gnus-sum shr pixel-fill kinsoku url-file svg dom nndraft nnmh
gnus-group mm-url gnus-undo use-package use-package-delight
use-package-diminish gnus-start gnus-dbus dbus xml gnus-cloud nnimap
nnmail mail-source utf7 nnoo parse-time iso8601 gnus-spec gnus-int
gnus-range message sendmail yank-media puny dired-x dired dired-loaddefs
rfc822 mml mml-sec epa epg rfc6068 epg-config mm-decode mm-bodies
mm-encode mail-parse rfc2231 rfc2047 rfc2045 ietf-drums mailabbrev
gmm-utils mailheader gnus-win vc-hg vc-bzr vc-src vc-sccs vc-svn vc-cvs
vc-rcs log-view pcvs-util tree-sitter vc company-oddmuse
company-keywords company-etags company-gtags company-dabbrev-code
company-dabbrev company-files company-clang company-capf company-cmake
company-semantic company-template company-bbdb rust-utils rust-mode
rust-rustfmt rust-playpen rust-compile rust-cargo vc-git diff-mode
vc-dispatcher paredit-ext paredit inf-ruby ruby-mode smie company
haskell-interactive-mode haskell-presentation-mode haskell-process
haskell-session haskell-compile haskell-mode haskell-cabal haskell-utils
haskell-font-lock haskell-indentation haskell-string
haskell-sort-imports haskell-lexeme haskell-align-imports
haskell-complete-module haskell-ghc-support noutline outline
flymake-proc flymake etags fileloop generator dabbrev haskell-customize
hydra lv use-package-ensure solarized-theme solarized-definitions
projectile lisp-mnt ibuf-ext ibuffer ibuffer-loaddefs thingatpt
magit-autorevert autorevert magit-git magit-base magit-section
format-spec crm dash rx compat-27 compat-26 compat grep compile comint
ansi-osc ansi-color gnus nnheader range mail-utils mm-util mail-prsvr
gnus-util text-property-search time-date flx-ido flx xlsp xlsp-server
xlsp-company xlsp-handle-notification xlsp-handle-request xlsp-struct
let-alist xlsp-utils jsonrpc pcase warnings filenotify
google-translate-default-ui google-translate-core-ui facemenu color ido
google-translate-core google-translate-tk google-translate-backend
auto-complete advice popup cus-edit pp cus-load icons wid-edit
emms-player-mplayer emms-player-simple emms emms-compat hl-line winner
edmacro kmacro cl-extra help-mode xref project ring use-package-bind-key
bind-key easy-mmode use-package-core derived company-go-autoloads
corfu-autoloads debbugs-autoloads elpaso-disc-autoloads elpaso-autoloads
find-func company-autoloads flycheck-autoloads finder-inf
go-mode-autoloads json-reformat-autoloads json-snatcher-autoloads
lsp-bridge-autoloads lsp-mode-autoloads lv-autoloads magit-autoloads
nnreddit-autoloads epl-autoloads posframe-autoloads projectile-autoloads
markdown-mode-autoloads rust-mode-autoloads sml-mode-autoloads
tornado-template-mode-autoloads typescript-mode-autoloads
request-autoloads info wordnut-autoloads yasnippet-autoloads package
browse-url url url-proxy url-privacy url-expand url-methods url-history
url-cookie generate-lisp-file url-domsuf url-util mailcap url-handlers
url-parse auth-source cl-seq eieio eieio-core cl-macs password-cache
json subr-x map byte-opt gv bytecomp byte-compile cconv cldefs url-vars
cl-loaddefs cl-lib rmc iso-transl tooltip eldoc paren electric uniquify
ediff-hook vc-hooks lisp-float-type elisp-mode mwheel term/x-win x-win
term/common-win x-dnd tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode lisp-mode prog-mode register
page tab-bar menu-bar rfn-eshadow isearch easymenu timer select
scroll-bar mouse jit-lock font-lock syntax font-core term/tty-colors
frame minibuffer nadvice seq simple cl-generic indonesian philippine
cham georgian utf-8-lang misc-lang vietnamese tibetan thai tai-viet lao
korean japanese eucjp-ms cp51932 hebrew greek romanian slovak czech
european ethiopic indian cyrillic chinese composite emoji-zwj charscript
charprop case-table epa-hook jka-cmpr-hook help abbrev obarray oclosure
cl-preloaded button loaddefs theme-loaddefs faces cus-face macroexp
files window text-properties overlay sha1 md5 base64 format env
code-pages mule custom widget keymap hashtable-print-readable backquote
threads dbusbind inotify lcms2 dynamic-setting system-font-setting
font-render-setting cairo move-toolbar gtk x-toolkit xinput2 x multi-tty
make-network-process emacs)

Memory information:
((conses 16 2619625 543846)
 (symbols 48 63468 69)
 (strings 32 410020 80927)
 (string-bytes 1 14668125)
 (vectors 16 156883)
 (vector-slots 8 3734166 214130)
 (floats 8 4034 2969)
 (intervals 56 115001 13059)
 (buffers 1008 90))