"%s" @var{string})}.
@end defun
+@defvar set-message-function
+When this variable is non-@code{nil}, @code{message} and related functions
+call it as a function with one argument that is the message to show.
+
+When this function returns @code{nil}, the message is displayed in the
+echo area as usual. When the function returns a string, the returned
+string is displayed in the echo area. When this function returns
+other non-@code{nil} values, this means that the message was handled
+specially, so the same message is not displayed in the echo area.
+See also @code{clear-message-function} that can be used to clear the
+message displayed by this function.
+
+The default value is the function that displays the message at the end
+of the minibuffer when the minibuffer is active.
+@end defvar
+
+@defvar clear-message-function
+When this variable is non-@code{nil}, @code{message} and related functions
+call it without arguments when their message is @code{nil} or the empty string.
+
+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
+@code{set-message-function}.
+
+The default value is the function that clears the message displayed at
+the end of the minibuffer when the minibuffer is active.
+@end defvar
+
@defvar inhibit-message
When this variable is non-@code{nil}, @code{message} and related functions
will not use the Echo Area to display messages.
the minibuffer. If non-nil, point will move to the end of the prompt
(if point is after the end of the prompt).
++++
+*** When the minibuffer is active, messages are displayed at the end of
+the minibuffer instead of overwriting the minibuffer by the echo area.
+
---
*** Minibuffer now uses 'minibuffer-message' to display error messages
at the end of the active minibuffer.
to read a character, so it maintains a history that can be navigated
via usual minibuffer keystrokes 'M-p'/'M-n'.
+** New variables 'set-message-function' and 'clear-message-function'
+can be used to specify functions to show and clear messages that
+normally are displayed in the echo area.
+
** 'setq-local' can now set an arbitrary number of variables, which
makes the syntax more like 'setq'.
(sit-for (or minibuffer-message-timeout 1000000)))
(delete-overlay ol)))))
+(defcustom minibuffer-message-clear-timeout nil
+ "How long to display an echo-area message when the minibuffer is active.
+If the value is a number, it should be specified in seconds.
+If the value is not a number, such messages never time out,
+and the text is displayed until the next input event arrives.
+Unlike `minibuffer-message-timeout' used by `minibuffer-message',
+this option affects the pair of functions `set-minibuffer-message'
+and `clear-minibuffer-message' called automatically via
+`set-message-function' and `clear-message-function'."
+ :type '(choice (const :tag "Never time out" nil)
+ (integer :tag "Wait for the number of seconds" 2))
+ :version "27.1")
+
+(defvar minibuffer-message-timer nil)
+(defvar minibuffer-message-overlay nil)
+
+(defun set-minibuffer-message (message)
+ "Temporarily display MESSAGE at the end of the minibuffer.
+The text is displayed for `minibuffer-message-clear-timeout' seconds
+(if the value is a number), or until the next input event arrives,
+whichever comes first.
+Unlike `minibuffer-message', this function is called automatically
+via `set-message-function'."
+ (when (and (not noninteractive)
+ (window-live-p (active-minibuffer-window)))
+ (with-current-buffer (window-buffer (active-minibuffer-window))
+ (setq message (if (string-match-p "\\` *\\[.+\\]\\'" message)
+ ;; Make sure we can put-text-property.
+ (copy-sequence message)
+ (concat " [" message "]")))
+ (unless (or (null minibuffer-message-properties)
+ ;; Don't overwrite the face properties the caller has set
+ (text-properties-at 0 message))
+ (setq message (apply #'propertize message minibuffer-message-properties)))
+
+ (clear-minibuffer-message)
+
+ (setq minibuffer-message-overlay
+ (make-overlay (point-max) (point-max) nil t t))
+ (unless (zerop (length message))
+ ;; The current C cursor code doesn't know to use the overlay's
+ ;; marker's stickiness to figure out whether to place the cursor
+ ;; before or after the string, so let's spoon-feed it the pos.
+ (put-text-property 0 1 'cursor t message))
+ (overlay-put minibuffer-message-overlay 'after-string message)
+
+ (when (numberp minibuffer-message-clear-timeout)
+ (setq minibuffer-message-timer
+ (run-with-timer minibuffer-message-clear-timeout nil
+ #'clear-minibuffer-message)))
+
+ ;; Return `t' telling the caller that the message
+ ;; was handled specially by this function.
+ t)))
+
+(setq set-message-function 'set-minibuffer-message)
+
+(defun clear-minibuffer-message ()
+ "Clear minibuffer message.
+Intended to be called via `clear-message-function'."
+ (when (not noninteractive)
+ (when (timerp minibuffer-message-timer)
+ (cancel-timer minibuffer-message-timer)
+ (setq minibuffer-message-timer nil))
+ (when (overlayp minibuffer-message-overlay)
+ (delete-overlay minibuffer-message-overlay)
+ (setq minibuffer-message-overlay nil))))
+
+(setq clear-message-function 'clear-minibuffer-message)
+
(defun minibuffer-completion-contents ()
"Return the user input in a minibuffer before point as a string.
In Emacs 22, that was what completion commands operated on.
safe_run_hooks (Qecho_area_clear_hook);
clear_message (1, 0);
}
+ else if (FUNCTIONP (Vclear_message_function))
+ clear_message (1, 0);
}
reread_for_input_method:
static void
set_message (Lisp_Object string)
{
+ Lisp_Object message = Qnil;
+
eassert (STRINGP (string));
- message_enable_multibyte = STRING_MULTIBYTE (string);
+ if (FUNCTIONP (Vset_message_function))
+ {
+ ptrdiff_t count = SPECPDL_INDEX ();
+ specbind (Qinhibit_quit, Qt);
+ message = safe_call1 (Vset_message_function, string);
+ unbind_to (count, Qnil);
- with_echo_area_buffer (0, -1, set_message_1, 0, string);
- message_buf_print = false;
- help_echo_showing_p = false;
+ if (STRINGP (message))
+ {
+ string = message;
+ message = Qnil;
+ }
+ }
+
+ if (NILP (message))
+ {
+ message_enable_multibyte = STRING_MULTIBYTE (string);
+
+ with_echo_area_buffer (0, -1, set_message_1, 0, string);
+ message_buf_print = false;
+ help_echo_showing_p = false;
+ }
if (STRINGP (Vdebug_on_message)
&& STRINGP (string)
{
echo_area_buffer[0] = Qnil;
message_cleared_p = true;
+
+ if (FUNCTIONP (Vclear_message_function))
+ {
+ ptrdiff_t count = SPECPDL_INDEX ();
+ specbind (Qinhibit_quit, Qt);
+ safe_call (1, Vclear_message_function);
+ unbind_to (count, Qnil);
+ }
}
if (last_displayed_p)
doc: /* If non-nil, debug if a message matching this regexp is displayed. */);
Vdebug_on_message = Qnil;
+ DEFVAR_LISP ("set-message-function", Vset_message_function,
+ doc: /* If non-nil, function to show the message.
+The function is called with one argument that is the message.
+When this function returns nil, the message is displayed in the echo
+area as usual. When the function returns a string, the returned
+string is displayed in the echo area. When this function returns
+other non-nil values, this means that the message was handled
+specially, so the same message is not displayed in the echo area.
+See also `clear-message-function' that can be used to clear the
+message displayed by this function. */);
+ Vset_message_function = Qnil;
+
+ DEFVAR_LISP ("clear-message-function", Vclear_message_function,
+ doc: /* If non-nil, function to clear message.
+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'. */);
+ Vclear_message_function = Qnil;
+
DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
doc: /* */);
Vredisplay__all_windows_cause = Fmake_hash_table (0, NULL);