From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED.blaine.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.bugs Subject: bug#38457: 27.0.50; dabbrev-expand regression due to message change Date: Wed, 18 Dec 2019 01:51:00 +0200 Organization: LINKOV.NET Message-ID: <87y2vawly3.fsf@mail.linkov.net> References: <8736e3vve8.fsf@gmx.net> <83lfrrigj8.fsf@gnu.org> <87eexiqps5.fsf@mail.linkov.net> <83lfrphp94.fsf@gnu.org> <87wob7g2jk.fsf@mail.linkov.net> <83k177ebs0.fsf@gnu.org> <87muc27prn.fsf@mail.linkov.net> <83tv6acgq5.fsf@gnu.org> <87eexdoygh.fsf@mail.linkov.net> <83tv68c0nb.fsf@gnu.org> <87d0cubfxx.fsf@mail.linkov.net> <83a77y9k35.fsf@gnu.org> <87eex9jf14.fsf@mail.linkov.net> <83d0cs8uw8.fsf@gnu.org> <87a77uh5a5.fsf@mail.linkov.net> <83r21561qd.fsf@gnu.org> <878snd2liu.fsf@mail.linkov.net> <8336dk5k1p.fsf@gnu.org> <87a77rgajf.fsf@mail.linkov.net> <83immf3pba.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: blaine.gmane.org; posting-host="blaine.gmane.org:195.159.176.226"; logging-data="247292"; mail-complaints-to="usenet@blaine.gmane.org" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/27.0.50 (x86_64-pc-linux-gnu) Cc: 38457@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Dec 18 01:07:16 2019 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([209.51.188.17]) by blaine.gmane.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.89) (envelope-from ) id 1ihMrz-00127X-9i for geb-bug-gnu-emacs@m.gmane.org; Wed, 18 Dec 2019 01:07:15 +0100 Original-Received: from localhost ([::1]:47500 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ihMry-0000fy-3k for geb-bug-gnu-emacs@m.gmane.org; Tue, 17 Dec 2019 19:07:14 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:49925) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ihMro-0000eC-2g for bug-gnu-emacs@gnu.org; Tue, 17 Dec 2019 19:07:05 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ihMrm-0008ME-E9 for bug-gnu-emacs@gnu.org; Tue, 17 Dec 2019 19:07:04 -0500 Original-Received: from debbugs.gnu.org ([209.51.188.43]:36559) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1ihMrm-0008M8-AP for bug-gnu-emacs@gnu.org; Tue, 17 Dec 2019 19:07:02 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1ihMrm-00006z-49 for bug-gnu-emacs@gnu.org; Tue, 17 Dec 2019 19:07:02 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Juri Linkov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Wed, 18 Dec 2019 00:07:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 38457 X-GNU-PR-Package: emacs Original-Received: via spool by 38457-submit@debbugs.gnu.org id=B38457.1576627614400 (code B ref 38457); Wed, 18 Dec 2019 00:07:02 +0000 Original-Received: (at 38457) by debbugs.gnu.org; 18 Dec 2019 00:06:54 +0000 Original-Received: from localhost ([127.0.0.1]:42529 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ihMre-00006M-2K for submit@debbugs.gnu.org; Tue, 17 Dec 2019 19:06:54 -0500 Original-Received: from anteater.elm.relay.mailchannels.net ([23.83.212.3]:35823) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ihMrb-00006B-UV for 38457@debbugs.gnu.org; Tue, 17 Dec 2019 19:06:52 -0500 X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Original-Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 7C7683C0A74; Wed, 18 Dec 2019 00:06:50 +0000 (UTC) Original-Received: from pdx1-sub0-mail-a90.g.dreamhost.com (100-96-15-224.trex.outbound.svc.cluster.local [100.96.15.224]) (Authenticated sender: dreamhost) by relay.mailchannels.net (Postfix) with ESMTPA id 0C8A73C0A59; Wed, 18 Dec 2019 00:06:50 +0000 (UTC) X-Sender-Id: dreamhost|x-authsender|jurta@jurta.org Original-Received: from pdx1-sub0-mail-a90.g.dreamhost.com ([TEMPUNAVAIL]. [64.90.62.162]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.18.5); Wed, 18 Dec 2019 00:06:50 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: dreamhost|x-authsender|jurta@jurta.org X-MailChannels-Auth-Id: dreamhost X-Squirrel-Plucky: 1f6cfb570e0a7437_1576627610281_2466110706 X-MC-Loop-Signature: 1576627610281:2803171925 X-MC-Ingress-Time: 1576627610281 Original-Received: from pdx1-sub0-mail-a90.g.dreamhost.com (localhost [127.0.0.1]) by pdx1-sub0-mail-a90.g.dreamhost.com (Postfix) with ESMTP id C404C7F14E; Tue, 17 Dec 2019 16:06:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=linkov.net; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=linkov.net; bh=Bc+qVh++rlOCE+eU+WCOFNbKD1M=; b= o6i5RRuxYwbZmCC22/dvsZNLC7oP5YHDDhtnKF7eJEo+tPR7MxAYvI5+Izo5+ZDL DDBRL/HVkRqZuyzoOtOyiFXqg4KA5ty/Aa7TIGMlcfaPXeX9EbIeyW6YwZXsy+to oifB0yJ2og+lPUL10XAf94shxK+fBbmhG42MlCXG4nM= Original-Received: from mail.jurta.org (m91-129-107-186.cust.tele2.ee [91.129.107.186]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jurta@jurta.org) by pdx1-sub0-mail-a90.g.dreamhost.com (Postfix) with ESMTPSA id 7F66E7F13F; Tue, 17 Dec 2019 16:06:43 -0800 (PST) X-DH-BACKEND: pdx1-sub0-mail-a90 In-Reply-To: <83immf3pba.fsf@gnu.org> (Eli Zaretskii's message of "Tue, 17 Dec 2019 18:11:05 +0200") X-VR-OUT-STATUS: OK X-VR-OUT-SCORE: -100 X-VR-OUT-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrgedufedrvddtkedgudekucetufdoteggodetrfdotffvucfrrhhofhhilhgvmecuggftfghnshhusghstghrihgsvgdpffftgfetoffjqffuvfenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmnecujfgurhephffvufhofhffjgfkfgggtgesmhdtreertdertdenucfhrhhomheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqeenucfkphepledurdduvdelrddutdejrddukeeinecurfgrrhgrmhepmhhouggvpehsmhhtphdphhgvlhhopehmrghilhdrjhhurhhtrgdrohhrghdpihhnvghtpeeluddruddvledruddtjedrudekiedprhgvthhurhhnqdhprghthheplfhurhhiucfnihhnkhhovhcuoehjuhhriheslhhinhhkohhvrdhnvghtqedpmhgrihhlfhhrohhmpehjuhhriheslhhinhhkohhvrdhnvghtpdhnrhgtphhtthhopegvlhhiiiesghhnuhdrohhrghenucevlhhushhtvghrufhiiigvpedt X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.51.188.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:173506 Archived-At: --=-=-= Content-Type: text/plain >> >> (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. --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=set-minibuffer-message.patch 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); --=-=-=--