From 164a7ebdbc7a28bdfb684101f9bbe3b1e67b825b Mon Sep 17 00:00:00 2001 From: Juri Linkov Date: Sat, 23 Apr 2022 17:17:15 +0200 Subject: [PATCH] Allow not clearing the echo area * doc/lispref/display.texi (Displaying Messages): Document it. * lisp/minibuffer.el (clear-minibuffer-message): Return nil. * src/xdisp.c (clear_message): Respect the dont-clear-message value. --- doc/lispref/display.texi | 5 ++++- etc/NEWS | 5 +++++ lisp/minibuffer.el | 6 +++++- src/xdisp.c | 27 ++++++++++++++++++++------- 4 files changed, 34 insertions(+), 9 deletions(-) diff --git a/doc/lispref/display.texi b/doc/lispref/display.texi index 2bd0a81fadc..0dd84514793 100644 --- a/doc/lispref/display.texi +++ b/doc/lispref/display.texi @@ -336,7 +336,10 @@ functions call it with no arguments when their argument message is 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}. +@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. The default value is the function that clears the message displayed in an active minibuffer. diff --git a/etc/NEWS b/etc/NEWS index 57bcef36f13..f7d81335cc3 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1462,6 +1462,11 @@ functions. * Lisp Changes in Emacs 29.1 ++++ +** The return value of 'clear-message-function' is not ignored anymore. +If the function returns 'dont-clear-message', then the message is not +cleared, with the assumption that the function cleared it itself. + +++ ** The local variable section now supports defining fallback modes. This was previously only available when using a property line (i.e., diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index d52084afc3c..ef71b4e6be6 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -864,7 +864,11 @@ Intended to be called via `clear-message-function'." (setq minibuffer-message-timer nil)) (when (overlayp minibuffer-message-overlay) (delete-overlay minibuffer-message-overlay) - (setq minibuffer-message-overlay nil)))) + (setq minibuffer-message-overlay nil))) + + ;; Return nil telling the caller that the message + ;; should be also handled by the caller. + nil) (setq clear-message-function 'clear-minibuffer-message) diff --git a/src/xdisp.c b/src/xdisp.c index a3a4338eb4f..dccff9f2ea6 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -12681,18 +12681,23 @@ 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); - safe_call (1, Vclear_message_function); + preserve = 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) @@ -36557,12 +36562,20 @@ message displayed by this function), and `command-error-function' (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. -The function is called without arguments. It is expected to clear the -message displayed by its counterpart function specified by -`set-message-function'. */); +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. */); Vclear_message_function = Qnil; DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause, -- 2.39.2