@@ -290,6 +290,70 @@ Looks up the state in meow-replace-state-name-list"
290290 (regexp-quote selected))
291291 selected))))
292292
293+ (defun meow--prompt-buffer-highlight (prompt beg end )
294+ " PROMPT from the minibuffer while highlighting matches between BEG and END.
295+
296+ When `meow-visit-sanitize-completion' is non-nil, matches are
297+ literal instead of regexps and only words and symbols are
298+ matched.
299+
300+ Highlights are only visible in the selected window."
301+ (let ((current-buffer (current-buffer ))
302+ (selected-window (selected-window ))
303+ (timer)
304+ (overlays)
305+ (prompter-minibuffer))
306+ (cl-labels ((transform-text (txt &optional quote-regexp)
307+ (cond (meow-visit-sanitize-completion
308+ ; ; To support Emacs 26.3, we need to use RX's `regexp'
309+ ; ; form with `regexp-quote' instead of the `literal'
310+ ; ; form, which was added in Emacs 27.
311+ (let ((qtd (regexp-quote txt)))
312+ (rx (or (seq symbol-start
313+ (regexp qtd)
314+ symbol-end)
315+ (seq word-start
316+ (regexp qtd)
317+ word-end)))))
318+ (quote-regexp (regexp-quote txt))
319+ (t txt)))
320+ (delete-overlays ()
321+ (mapc #'delete-overlay overlays)
322+ (setq overlays nil ))
323+ (highlight-matches ()
324+ ; ; Before highlighting the minibuffer contents, we need to
325+ ; ; check that we are still in the prompter's minibuffer, not
326+ ; ; some other minibuffer.
327+ (when (or (not enable-recursive-minibuffers)
328+ (equal prompter-minibuffer (current-buffer )))
329+ (delete-overlays)
330+ (let ((regexp (transform-text (minibuffer-contents ))))
331+ (unless (string-empty-p regexp)
332+ (save-excursion
333+ (with-current-buffer current-buffer
334+ (goto-char beg)
335+ (while (ignore-error invalid-regexp
336+ ; ; If the user is still typing the regexp it
337+ ; ; might not be valid. In that case, we
338+ ; ; treat it as valid but not matching.
339+ (re-search-forward regexp end t ))
340+ (let ((ov (make-overlay (match-beginning 0 )
341+ (match-end 0 ))))
342+ (overlay-put ov 'face 'lazy-highlight )
343+ ; ; Same priority as Isearch lazy-highlight.
344+ (overlay-put ov 'priority 1000 )
345+ (overlay-put ov 'window selected-window)
346+ (push ov overlays)))))))))
347+ (make-hl-timer ()
348+ (run-with-idle-timer 0.01 'repeat #'highlight-matches )))
349+ (unwind-protect
350+ (minibuffer-with-setup-hook
351+ (lambda () (setq timer (make-hl-timer)
352+ prompter-minibuffer (current-buffer )))
353+ (transform-text (read-from-minibuffer prompt) t ))
354+ (cancel-timer timer)
355+ (delete-overlays)))))
356+
293357(defun meow--on-window-state-change (&rest _args )
294358 " Update cursor style after switching window."
295359 (meow--update-cursor)
0 commit comments