[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
bug#38457: 27.0.50; dabbrev-expand regression due to message change
From: |
Juri Linkov |
Subject: |
bug#38457: 27.0.50; dabbrev-expand regression due to message change |
Date: |
Fri, 20 Dec 2019 00:16:46 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) |
> I think leaving "M-x" (or any other prompt) unobscured in this
> situation is a nice benefit, and if it simplifies the code, it's even
> more desirable.
Implemented in a new patch.
>> after-input=nil after-timeout=0 - never clear the message
>> after-input=t after-timeout=2 - clear either on input or after timeout
>> after-input=t after-timeout=0 - clear only when input is available:
>> this has an advantage that user has
>> control when
>> wants to clear message immediately on
>> keypress;
>> after-input=nil after-timeout=2 - clear only after timeout, not on input:
>> this has an advantage that user will never
>> miss
>> a message while typing in the minibuffer,
>> the message will stay for the specified
>> number
>> of seconds regardless of input,
>> so user will have a chance to read it
>>
>> Do all these variants make sense?
>
> I would never want to use variants 1 and 4, but if someone wants them,
> I won't object as long as the default for Emacs 27 is as in the 2nd
> variant.
Actually, supporting an option after-input is not straightforward,
because when clear-minibuffer-message is called, there is no distinction
whether it was called by new input arrived, or by a function calling
'message' with an empty argument. But really an option after-input
is not necessary, this rules out variants 1 and 4 anyway.
So this patch implements only the option clear-timeout
with the 2nd variant by default.
Also made changes for all your previous comments:
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 76d8ca4475..502375ee1e 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -746,6 +746,76 @@ minibuffer-message
(sit-for (or minibuffer-message-timeout 1000000)))
(delete-overlay ol)))))
+(defcustom minibuffer-message-clear-timeout 2
+ "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."
+ :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."
+ (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)))
+
+ (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 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
+ (lambda ()
+ (when (overlayp minibuffer-message-overlay)
+ (delete-overlay minibuffer-message-overlay)
+ (setq minibuffer-message-overlay nil)
+ (setq minibuffer-message-timer nil))))))
+
+ t)))
+
+(setq set-message-function 'set-minibuffer-message)
+
+(defun clear-minibuffer-message ()
+ "Clear minibuffer message."
+ (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.
diff --git a/src/keyboard.c b/src/keyboard.c
index 5135fd0bc8..5b1b6f2c95 100644
--- a/src/keyboard.c
+++ b/src/keyboard.c
@@ -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))
+ message1 (0);
}
reread_for_input_method:
diff --git a/src/xdisp.c b/src/xdisp.c
index 08c6927052..3d232d8e92 100644
--- a/src/xdisp.c
+++ b/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,14 @@ syms_of_xdisp (void)
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 set message. */);
+ Vset_message_function = Qnil;
+
+ DEFVAR_LISP ("clear-message-function", Vclear_message_function,
+ doc: /* If non-nil, function to clear message. */);
+ Vclear_message_function = Qnil;
+
DEFVAR_LISP ("redisplay--all-windows-cause", Vredisplay__all_windows_cause,
doc: /* */);
Vredisplay__all_windows_cause = Fmake_hash_table (0, NULL);
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, (continued)
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Dmitry Gutov, 2019/12/16
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, HaiJun Zhang, 2019/12/17
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Eli Zaretskii, 2019/12/17
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Juri Linkov, 2019/12/17
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, HaiJun Zhang, 2019/12/17
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Eli Zaretskii, 2019/12/17
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Juri Linkov, 2019/12/17
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Eli Zaretskii, 2019/12/18
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Juri Linkov, 2019/12/18
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Eli Zaretskii, 2019/12/19
- bug#38457: 27.0.50; dabbrev-expand regression due to message change,
Juri Linkov <=
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Dmitry Gutov, 2019/12/19
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Juri Linkov, 2019/12/19
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Eli Zaretskii, 2019/12/20
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Juri Linkov, 2019/12/19
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Eli Zaretskii, 2019/12/20
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Juri Linkov, 2019/12/21
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Eli Zaretskii, 2019/12/20
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Juri Linkov, 2019/12/21
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Eli Zaretskii, 2019/12/22
- bug#38457: 27.0.50; dabbrev-expand regression due to message change, Dmitry Gutov, 2019/12/20