mirror of
https://git.savannah.gnu.org/git/emacs.git
synced 2024-11-27 07:37:33 +00:00
New variable set-message-function to show message at the end of the minibuffer
* doc/lispref/display.texi (Displaying Messages): Document set-message-function and clear-message-function. * lisp/minibuffer.el (minibuffer-message-clear-timeout): New defcustom. (minibuffer-message-timer, minibuffer-message-overlay): New variables. (set-minibuffer-message, clear-minibuffer-message): New functions. (set-message-function, clear-message-function): Set variables to set-minibuffer-message and clear-minibuffer-message respectively. * src/keyboard.c (read_char): Call clear_message when Vclear_message_function is a function. * src/xdisp.c (set_message): Call Vset_message_function when it's a function. (clear_message): Call Vclear_message_function when it's a function. (syms_of_xdisp): New variables set-message-function and clear-message-function (bug#38457).
This commit is contained in:
parent
678a71ea2d
commit
485b423e8f
@ -306,6 +306,35 @@ reformatted, with undesirable results. Instead, use @code{(message
|
||||
"%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.
|
||||
|
8
etc/NEWS
8
etc/NEWS
@ -781,6 +781,10 @@ been introduced to allow controlling how the 'M-<' command works in
|
||||
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.
|
||||
@ -2723,6 +2727,10 @@ This function works like 'read-char', but uses 'read-from-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'.
|
||||
|
||||
|
@ -746,6 +746,76 @@ If ARGS are provided, then pass MESSAGE through `format-message'."
|
||||
(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.
|
||||
|
@ -2990,6 +2990,8 @@ read_char (int commandflag, Lisp_Object map,
|
||||
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:
|
||||
|
55
src/xdisp.c
55
src/xdisp.c
@ -11706,13 +11706,32 @@ truncate_message_1 (ptrdiff_t nchars, Lisp_Object a2)
|
||||
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)
|
||||
@ -11768,6 +11787,14 @@ clear_message (bool current_p, bool last_displayed_p)
|
||||
{
|
||||
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)
|
||||
@ -34940,6 +34967,26 @@ display table takes effect; in this case, Emacs does not consult
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user