diff options
| author | Spencer Baugh | 2026-01-29 16:45:15 +0000 |
|---|---|---|
| committer | Sean Whitton | 2026-01-29 16:56:38 +0000 |
| commit | 0ab5db015f7eed3ffdf85ccbb75ff48e2c44b5a1 (patch) | |
| tree | fbe0dd7d61c604ebef42e9882a0fc02f543326c4 | |
| parent | 3937833fff0c31f9f6c71badcec2e5d43f7e5eba (diff) | |
| download | emacs-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/NEWS | 7 | ||||
| -rw-r--r-- | lisp/minibuffer.el | 63 |
2 files changed, 40 insertions, 30 deletions
| @@ -3918,6 +3918,13 @@ Binding 'inhibit-message' to a non-nil value will now suppress both | |||
| 3918 | the display of messages and the clearing of the echo area, such as | 3918 | the display of messages and the clearing of the echo area, such as |
| 3919 | caused by calling 'message' with a nil argument. | 3919 | caused 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 | ||
| 3924 | the minibuffer, instead of waiting with 'sit-for' and then clearing it. | ||
| 3925 | This makes 'minibuffer-message' usable in Lisp programs which want to | ||
| 3926 | print 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. |
| 802 | This function is designed to be called from the minibuffer, i.e., | 815 | This function is designed to be called from the minibuffer, i.e., |
| @@ -814,13 +827,9 @@ through `format-message'. | |||
| 814 | If some of the minibuffer text has the `minibuffer-message' text | 827 | If some of the minibuffer text has the `minibuffer-message' text |
| 815 | property, MESSAGE is shown at that position instead of EOB." | 828 | property, 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. |