From: Juri Linkov <juri@linkov.net>
To: Eli Zaretskii <eliz@gnu.org>
Cc: 38457@debbugs.gnu.org
Subject: bug#38457: 27.0.50; dabbrev-expand regression due to message change
Date: Wed, 18 Dec 2019 01:51:00 +0200 [thread overview]
Message-ID: <87y2vawly3.fsf@mail.linkov.net> (raw)
In-Reply-To: <83immf3pba.fsf@gnu.org> (Eli Zaretskii's message of "Tue, 17 Dec 2019 18:11:05 +0200")
[-- Attachment #1: Type: text/plain, Size: 2045 bytes --]
>> >> (if (and
>> >> ;; When `inhibit-message' is non-nil, the intention was to just
>> >> ;; log the message to the *Messages* buffer using `message'.
>> >> (null inhibit-message)
>> >> (window-live-p (active-minibuffer-window))
>> >> (window-live-p (old-selected-window))
>> >> (bufferp (window-buffer (old-selected-window)))
>> >> (minibufferp (window-buffer (old-selected-window))))
>> >
>> > Btw, can you explain why every part of this condition is needed? IOW,
>> > why isn't just the below enough?
>> >
>> > (window-live-p (active-minibuffer-window))
>> >
>> > (I do understand the reason for the test of inhibit-message).
>> >
>> > Maybe the other conditions need a comment to explain them?
>>
>> Unfortunately, I forgot why they were added, i.e. during testing
>> I added them one by one when noticed that some cases don't work.
>> Now I'll try to reproduce these cases by removing conditions
>> and checking which part doesn't work.
Now I recall why just (window-live-p (active-minibuffer-window))
is not enough. Because it returns non-nil even when the
current buffer is not the minibuffer, but the minibuffer was
activated earlier. Test case:
0. emacs -Q
1. M-x ;; activate the minibuffer
2. C-x o ;; switch back to *scratch*
3. Eval in *scratch* buffer:
(window-live-p (active-minibuffer-window))
=> t
A message overlay should not be added to the *scratch* buffer, so it's
important to check if old-selected-window is a minibuffer window
(i.e. the current buffer is the minibuffer).
>> But if implementation would be straightforward and if you see no problems
>> then why not.
>
> The implementation looks straightforward to me, since you already
> implemented almost all of it in that ELPA package. What's left is
> minor details.
Let's iron out the details. A new patch attached works well
in all cases I tested (dabbrev, icomplete, etc.) But I'm sure
it could be improved further because I might have made wrong
assumptions on the C side, or something.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: set-minibuffer-message.patch --]
[-- Type: text/x-diff, Size: 6366 bytes --]
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 76d8ca4475..331b2a44ed 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -746,6 +746,78 @@ minibuffer-message
(sit-for (or minibuffer-message-timeout 1000000)))
(delete-overlay ol)))))
+(defcustom minibuffer-message-wait 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."
+ :type '(choice (const :tag "Never time out" nil)
+ (integer :tag "Wait for the number of seconds" 2)))
+
+(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-wait' seconds,
+or until the next input event arrives, whichever comes first.
+Enclose MESSAGE in [...] if this is not yet the case."
+ (when (and (not noninteractive)
+ (window-live-p (active-minibuffer-window))
+ (window-live-p (old-selected-window))
+ (bufferp (window-buffer (old-selected-window)))
+ (minibufferp (window-buffer (old-selected-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-wait)
+ (setq minibuffer-message-timer
+ (run-with-timer minibuffer-message-wait nil
+ (lambda ()
+ (when (overlayp minibuffer-message-overlay)
+ (delete-overlay minibuffer-message-overlay)
+ (setq minibuffer-message-overlay nil))))))
+
+ t))
+
+(setq set-message-function 'set-minibuffer-message)
+
+(defun clear-minibuffer-message ()
+ "Clear minibuffer message."
+ (when (not noninteractive)
+ ;; When this option is a number, the message
+ ;; should be cleared only by timer.
+ (unless (numberp minibuffer-message-wait)
+ (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..d9c9213098 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 (!NILP (Vclear_message_function))
+ message1 (0);
}
reread_for_input_method:
diff --git a/src/xdisp.c b/src/xdisp.c
index 08c6927052..a31a90c7e2 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -11706,13 +11706,33 @@ 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 (!NILP (Vset_message_function))
+ {
+ ptrdiff_t count = SPECPDL_INDEX ();
+ specbind (Qinhibit_quit, Qt);
+ message = 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))
+ {
+ eassert (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 +11788,14 @@ clear_message (bool current_p, bool last_displayed_p)
{
echo_area_buffer[0] = Qnil;
message_cleared_p = true;
+
+ if (!NILP (Vclear_message_function))
+ {
+ ptrdiff_t count = SPECPDL_INDEX ();
+ specbind (Qinhibit_quit, Qt);
+ call0 (Vclear_message_function);
+ unbind_to (count, Qnil);
+ }
}
if (last_displayed_p)
@@ -34940,6 +34968,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);
next prev parent reply other threads:[~2019-12-17 23:51 UTC|newest]
Thread overview: 115+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-12-02 11:06 bug#38457: 27.0.50; dabbrev-expand regression due to message change Stephen Berman
2019-12-02 16:02 ` Eli Zaretskii
2019-12-02 23:00 ` Juri Linkov
2019-12-03 0:15 ` Stephen Berman
2019-12-03 3:36 ` Eli Zaretskii
2019-12-03 23:44 ` Juri Linkov
2019-12-04 3:38 ` Eli Zaretskii
2019-12-04 23:16 ` Juri Linkov
2019-12-05 3:43 ` Eli Zaretskii
2019-12-06 0:10 ` Juri Linkov
2019-12-06 7:44 ` Eli Zaretskii
2019-12-07 23:05 ` Juri Linkov
2019-12-08 3:28 ` Eli Zaretskii
2019-12-08 5:18 ` Eli Zaretskii
2019-12-08 21:50 ` Juri Linkov
2019-12-09 3:36 ` Eli Zaretskii
2019-12-09 7:43 ` Lars Ingebrigtsen
2019-12-09 14:00 ` Eli Zaretskii
2019-12-09 15:55 ` Eli Zaretskii
2019-12-11 7:32 ` Lars Ingebrigtsen
2019-12-11 7:35 ` Lars Ingebrigtsen
2019-12-11 16:30 ` Eli Zaretskii
2019-12-11 16:28 ` Eli Zaretskii
2019-12-24 16:30 ` Lars Ingebrigtsen
2019-12-24 17:50 ` Eli Zaretskii
2019-12-09 23:45 ` Juri Linkov
2019-12-10 3:36 ` Eli Zaretskii
2019-12-10 7:19 ` HaiJun Zhang
2019-12-10 16:11 ` Eli Zaretskii
2019-12-10 17:52 ` Drew Adams
2019-12-10 17:51 ` Drew Adams
2019-12-10 16:34 ` Eli Zaretskii
2019-12-10 17:08 ` Stefan Monnier
2019-12-10 17:49 ` Eli Zaretskii
2019-12-10 17:57 ` Eli Zaretskii
2019-12-10 23:45 ` Juri Linkov
2019-12-11 16:19 ` Eli Zaretskii
2019-12-11 17:34 ` Stefan Monnier
2019-12-11 17:50 ` Eli Zaretskii
2019-12-11 18:53 ` Stefan Monnier
2019-12-11 23:12 ` Juri Linkov
2019-12-12 4:39 ` Eli Zaretskii
2019-12-12 22:45 ` Juri Linkov
2019-12-13 8:25 ` Eli Zaretskii
2019-12-10 19:45 ` Stefan Monnier
2019-12-10 20:11 ` Eli Zaretskii
2019-12-10 21:45 ` Stefan Monnier
2019-12-11 3:24 ` HaiJun Zhang
2019-12-11 3:40 ` Eli Zaretskii
2019-12-11 3:59 ` HaiJun Zhang
2019-12-11 16:26 ` Eli Zaretskii
2019-12-12 4:33 ` HaiJun Zhang
2019-12-12 5:29 ` Eli Zaretskii
2019-12-12 22:58 ` Juri Linkov
2019-12-13 7:02 ` Eli Zaretskii
2019-12-13 9:07 ` Eli Zaretskii
2019-12-12 13:21 ` Stefan Monnier
2019-12-11 3:35 ` HaiJun Zhang
2019-12-11 16:11 ` Eli Zaretskii
2019-12-11 16:42 ` Eli Zaretskii
2019-12-11 23:24 ` Juri Linkov
2019-12-12 5:36 ` Eli Zaretskii
2019-12-12 11:08 ` Dmitry Gutov
2019-12-12 23:07 ` Juri Linkov
2019-12-13 8:46 ` Eli Zaretskii
2019-12-11 23:28 ` Juri Linkov
2019-12-12 5:41 ` Eli Zaretskii
2019-12-12 23:12 ` Juri Linkov
2019-12-13 8:57 ` Eli Zaretskii
2019-12-14 23:10 ` Juri Linkov
2019-12-15 15:35 ` Eli Zaretskii
2019-12-15 23:59 ` Juri Linkov
2019-12-16 16:09 ` Eli Zaretskii
2019-12-16 22:29 ` Juri Linkov
2019-12-16 23:26 ` Dmitry Gutov
2019-12-17 6:27 ` HaiJun Zhang
2019-12-17 16:19 ` Eli Zaretskii
2019-12-17 23:53 ` Juri Linkov
2019-12-18 3:38 ` HaiJun Zhang
2019-12-17 16:11 ` Eli Zaretskii
2019-12-17 23:51 ` Juri Linkov [this message]
2019-12-18 16:24 ` Eli Zaretskii
2019-12-19 0:12 ` Juri Linkov
2019-12-19 15:36 ` Eli Zaretskii
2019-12-19 22:16 ` Juri Linkov
2019-12-19 22:30 ` Dmitry Gutov
2019-12-19 23:17 ` Juri Linkov
2019-12-20 7:34 ` Eli Zaretskii
2019-12-19 22:52 ` Juri Linkov
2019-12-20 7:59 ` Eli Zaretskii
2019-12-21 22:09 ` Juri Linkov
2019-12-20 7:54 ` Eli Zaretskii
2019-12-21 22:02 ` Juri Linkov
2019-12-22 19:02 ` Eli Zaretskii
2019-12-20 14:29 ` Dmitry Gutov
2019-12-21 22:03 ` Juri Linkov
2019-12-23 10:10 ` Dmitry Gutov
2019-12-23 22:58 ` Juri Linkov
2019-12-24 0:42 ` Dmitry Gutov
2019-12-24 23:47 ` Juri Linkov
2019-12-25 16:30 ` Dmitry Gutov
2019-12-25 16:44 ` Eli Zaretskii
2019-12-25 16:49 ` Dmitry Gutov
2020-01-18 0:59 ` Dmitry Gutov
2020-01-18 8:19 ` Eli Zaretskii
2020-01-20 12:30 ` Dmitry Gutov
2020-01-21 16:15 ` Eli Zaretskii
2020-01-22 0:46 ` Dmitry Gutov
2020-01-18 1:00 ` Dmitry Gutov
2019-12-05 15:24 ` Kévin Le Gouguec
2019-12-05 16:36 ` Eli Zaretskii
2019-12-06 0:06 ` Juri Linkov
2019-12-06 7:41 ` Eli Zaretskii
2019-12-06 17:15 ` Kévin Le Gouguec
[not found] <<8736e3vve8.fsf@gmx.net>
[not found] ` <<8736e2coyv.fsf@mail.linkov.net>
[not found] ` <<83y2vujd0y.fsf@gnu.org>
[not found] ` <<87blspm0sm.fsf@mail.linkov.net>
[not found] ` <<837e3ckbem.fsf@gnu.org>
[not found] ` <<871rtjn0kt.fsf@mail.linkov.net>
[not found] ` <<83lfrrigj8.fsf@gnu.org>
[not found] ` <<87eexiqps5.fsf@mail.linkov.net>
[not found] ` <<83lfrphp94.fsf@gnu.org>
[not found] ` <<87wob7g2jk.fsf@mail.linkov.net>
[not found] ` <<83k177ebs0.fsf@gnu.org>
[not found] ` <<AE02ADC8-6567-4EB1-8A44-E60BC4B5807A@gnu.org>
[not found] ` <<87muc27prn.fsf@mail.linkov.net>
[not found] ` <<83tv6acgq5.fsf@gnu.org>
[not found] ` <<87eexdoygh.fsf@mail.linkov.net>
[not found] ` <<83tv68c0nb.fsf@gnu.org>
[not found] ` <<83h828b0lz.fsf@gnu.org>
2019-12-10 17:53 ` Drew Adams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87y2vawly3.fsf@mail.linkov.net \
--to=juri@linkov.net \
--cc=38457@debbugs.gnu.org \
--cc=eliz@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).