aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSpencer Baugh2026-01-29 16:45:15 +0000
committerSean Whitton2026-01-29 16:56:38 +0000
commit0ab5db015f7eed3ffdf85ccbb75ff48e2c44b5a1 (patch)
treefbe0dd7d61c604ebef42e9882a0fc02f543326c4
parent3937833fff0c31f9f6c71badcec2e5d43f7e5eba (diff)
downloademacs-0ab5db015f7eed3ffdf85ccbb75ff48e2c44b5a1.tar.gz
emacs-0ab5db015f7eed3ffdf85ccbb75ff48e2c44b5a1.zip
(minibuffer-message): Do not block while displaying message.
* lisp/minibuffer.el (minibuffer--message-overlay) (minibuffer--message-timer): New variables. (minibuffer--delete-message-overlay): New function. (minibuffer-message): Use a timer and 'pre-command-hook' to clear message overlay instead of blocking with 'sit-for'. (bug#79510) * etc/NEWS: Document the change.
-rw-r--r--etc/NEWS7
-rw-r--r--lisp/minibuffer.el63
2 files changed, 40 insertions, 30 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 65c8c62dec5..4af778c990c 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -3918,6 +3918,13 @@ Binding 'inhibit-message' to a non-nil value will now suppress both
3918the display of messages and the clearing of the echo area, such as 3918the display of messages and the clearing of the echo area, such as
3919caused by calling 'message' with a nil argument. 3919caused by calling 'message' with a nil argument.
3920 3920
3921---
3922** 'minibuffer-message' no longer blocks while displaying message
3923'minibuffer-message' now uses a timer to clear the message printed to
3924the minibuffer, instead of waiting with 'sit-for' and then clearing it.
3925This makes 'minibuffer-message' usable in Lisp programs which want to
3926print a message and then continue to perform work.
3927
3921** Special Events 3928** Special Events
3922 3929
3923+++ 3930+++
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 12827cacfe2..0904a592eb4 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -797,6 +797,19 @@ for use at QPOS."
797(defvar minibuffer-message-properties nil 797(defvar minibuffer-message-properties nil
798 "Text properties added to the text shown by `minibuffer-message'.") 798 "Text properties added to the text shown by `minibuffer-message'.")
799 799
800(defvar minibuffer--message-overlay nil)
801
802(defvar minibuffer--message-timer nil)
803
804(defun minibuffer--delete-message-overlay ()
805 (when (overlayp minibuffer--message-overlay)
806 (delete-overlay minibuffer--message-overlay)
807 (setq minibuffer--message-overlay nil))
808 (when (timerp minibuffer--message-timer)
809 (cancel-timer minibuffer--message-timer)
810 (setq minibuffer--message-timer nil))
811 (remove-hook 'pre-command-hook #'minibuffer--delete-message-overlay))
812
800(defun minibuffer-message (message &rest args) 813(defun minibuffer-message (message &rest args)
801 "Temporarily display MESSAGE at the end of minibuffer text. 814 "Temporarily display MESSAGE at the end of minibuffer text.
802This function is designed to be called from the minibuffer, i.e., 815This function is designed to be called from the minibuffer, i.e.,
@@ -814,13 +827,9 @@ through `format-message'.
814If some of the minibuffer text has the `minibuffer-message' text 827If some of the minibuffer text has the `minibuffer-message' text
815property, MESSAGE is shown at that position instead of EOB." 828property, MESSAGE is shown at that position instead of EOB."
816 (if (not (minibufferp (current-buffer) t)) 829 (if (not (minibufferp (current-buffer) t))
817 (progn 830 (apply #'message message args)
818 (if args
819 (apply #'message message args)
820 (message "%s" message))
821 (prog1 (sit-for (or minibuffer-message-timeout 1000000))
822 (message nil)))
823 ;; Clear out any old echo-area message to make way for our new thing. 831 ;; Clear out any old echo-area message to make way for our new thing.
832 (minibuffer--delete-message-overlay)
824 (message nil) 833 (message nil)
825 (setq message (if (and (null args) 834 (setq message (if (and (null args)
826 (string-match-p "\\` *\\[.+\\]\\'" message)) 835 (string-match-p "\\` *\\[.+\\]\\'" message))
@@ -834,30 +843,24 @@ property, MESSAGE is shown at that position instead of EOB."
834 (setq message (apply #'propertize message minibuffer-message-properties))) 843 (setq message (apply #'propertize message minibuffer-message-properties)))
835 ;; Put overlay either on `minibuffer-message' property, or at EOB. 844 ;; Put overlay either on `minibuffer-message' property, or at EOB.
836 (let* ((ovpos (minibuffer--message-overlay-pos)) 845 (let* ((ovpos (minibuffer--message-overlay-pos))
837 (ol (make-overlay ovpos ovpos nil t t)) 846 (ol (make-overlay ovpos ovpos nil t t)))
838 ;; A quit during sit-for normally only interrupts the sit-for, 847 (unless (zerop (length message))
839 ;; but since minibuffer-message is used at the end of a command, 848 ;; The current C cursor code doesn't know to use the overlay's
840 ;; at a time when the command has virtually finished already, a C-g 849 ;; marker's stickiness to figure out whether to place the cursor
841 ;; should really cause an abort-recursive-edit instead (i.e. as if 850 ;; before or after the string, so let's spoon-feed it the pos.
842 ;; the C-g had been typed at top-level). Binding inhibit-quit here 851 (put-text-property 0 1 'cursor t message))
843 ;; is an attempt to get that behavior. 852 (overlay-put ol 'after-string message)
844 (inhibit-quit t)) 853 ;; Make sure the overlay with the message is displayed before
845 (unwind-protect 854 ;; any other overlays in that position, in case they have
846 (progn 855 ;; resize-mini-windows set to nil and the other overlay strings
847 (unless (zerop (length message)) 856 ;; are too long for the mini-window width. This makes sure the
848 ;; The current C cursor code doesn't know to use the overlay's 857 ;; temporary message will always be visible.
849 ;; marker's stickiness to figure out whether to place the cursor 858 (overlay-put ol 'priority 1100)
850 ;; before or after the string, so let's spoon-feed it the pos. 859 (setq minibuffer--message-overlay ol
851 (put-text-property 0 1 'cursor t message)) 860 minibuffer--message-timer
852 (overlay-put ol 'after-string message) 861 (run-at-time (or minibuffer-message-timeout 1000000) nil
853 ;; Make sure the overlay with the message is displayed before 862 #'minibuffer--delete-message-overlay))
854 ;; any other overlays in that position, in case they have 863 (add-hook 'pre-command-hook #'minibuffer--delete-message-overlay))))
855 ;; resize-mini-windows set to nil and the other overlay strings
856 ;; are too long for the mini-window width. This makes sure the
857 ;; temporary message will always be visible.
858 (overlay-put ol 'priority 1100)
859 (sit-for (or minibuffer-message-timeout 1000000)))
860 (delete-overlay ol)))))
861 864
862(defcustom minibuffer-message-clear-timeout nil 865(defcustom minibuffer-message-clear-timeout nil
863 "How long to display an echo-area message when the minibuffer is active. 866 "How long to display an echo-area message when the minibuffer is active.