bug#81667: 32.0.50; `query-replace-show-preview' includes Quail IME UI and suggestions in buffer preview
Rahul Martim Juliato <[email protected]>
| Newsgroups | gmane.emacs.bugs |
|---|---|
| Message-ID | <[email protected]> |
समीर सिंह Sameer Singh <[email protected]> writes: > Currently, with `query-replace-show-preview' set to 't and a Quail IME > active, the replacement preview in the buffer erroneously includes the > input method's name and its completion suggestions. This happens because > the minibuffer displays this additional UI information while an input > method is active, and the replacement preview logic does not filter it > out. > > Steps to reproduce: > 1. emacs -Q > 2. M-: (setq query-replace-show-preview t) > 3. C-x RET C-\ > 4. Type in the name of any quail input-method, such as > "devanagari-kyoto-harvard" > 5. Type in a word such as: "श्वेत" > 6. M-x replace-string > 7. श्वेत RET > 8. Type "z" in the minibuffer > > Observed behaviour: > Instead of displaying only "श्", the buffer preview text displays: > "श् [DevKH] \nz[AEILQRUaeiloqu](01/01) 1.श्", incorrectly mirroring the > full minibuffer contents. > > It would be nice if this got fixed. Thanks. Hi Sameer, Thanks for the bug report, the recipe was easy to reproduce. See before-with-bug.png and after-without-bug.png, and the patch, all attached. It looks like the preview feature was only the messenger of the real problem: `quail-show-guidance' displays the guidance through `quail-minibuffer-message', which *inserts* it into the minibuffer at point-max, waits with `sit-for', and deletes it when the next key arrives. That insertion runs `after-change-functions', so any hook reading `minibuffer-contents' sees the user's text plus the guidance. The preview is just one such hook. The same happens with no replace.el involved at all: an `after-change-functions' hook on a plain `read-string' logs: "श्" "श् [DevKH]\nz[AEILQRUaeiloqu](01/01) 1.श्" Every other minibuffer message path uses an overlay instead of inserting text (`set-minibuffer-message'), so the patch makes this one do the same. I have no fluency in the language or the script involved, so my testing was mechanical, and quail.el needs a review from someone who really knows Mule and input methods (adding Eli for Mule and Juri for replace.el in Cc). Could you test the attached patch, whether it fixes it for you as well and/or creates complications in other uses of this input method? Thanks, -- Rahul Martim Juliato
after-without-bug.png
(image/png, 90.6 KB) - not displayed
before-with-bug.png
(image/png, 112.8 KB) - not displayed
0001-Show-Quail-guidance-with-an-overlay-bug-81667.patch
(application/octet-stream, 2 KB)
From b490f1f06bc835e3dd644707f72f1cf2abfa80c4 Mon Sep 17 00:00:00 2001 From: Rahul Martim Juliato <[email protected]> Date: Fri, 21 Aug 2026 00:11:49 -0300 Subject: [PATCH] Show Quail guidance with an overlay (bug#81667) Inserting the guidance into the minibuffer made it part of 'minibuffer-contents', so hooks reading it, such as the replacement preview, showed the guidance too. * lisp/international/quail.el (quail-minibuffer-message): Display STRING with an overlay instead of inserting it into the minibuffer. Put a 'cursor' property on it so that the cursor stays at point. --- lisp/international/quail.el | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/lisp/international/quail.el b/lisp/international/quail.el index 39c10287f3c..f838bc9ab8e 100644 --- a/lisp/international/quail.el +++ b/lisp/international/quail.el @@ -1998,14 +1998,22 @@ quail-require-guidance-buf (defun quail-minibuffer-message (string) (message nil) - (let ((point-max (point-max)) - (inhibit-quit t) - (deactivate-mark nil)) - (save-excursion - (goto-char point-max) - (insert string)) - (sit-for 1000000) - (delete-region point-max (point-max)) + (let ((inhibit-quit t) + ;; Display the guidance with an overlay instead of inserting it + ;; into the minibuffer, so that it stays out of the minibuffer + ;; contents (bug#81667). + (ov (make-overlay (point-max) (point-max) nil t t))) + (unwind-protect + (progn + ;; Tell the display engine to keep the cursor before the + ;; guidance, where point is. + (unless (zerop (length string)) + (setq string (copy-sequence string)) + (put-text-property 0 1 'cursor t string)) + (overlay-put ov 'after-string string) + (overlay-put ov 'priority 1100) + (sit-for 1000000)) + (delete-overlay ov)) (when quit-flag (setq quit-flag nil) (quail-add-unread-command-events 7 t)))) -- 2.55.0