From aaef7a6438aaa74a5978e5e9d4b5e95910c2b15e Mon Sep 17 00:00:00 2001 From: Augusto Stoffel Date: Wed, 27 Jan 2021 16:09:38 +0100 Subject: [PATCH] Reduce flicker in Isearch mode Lazy highlighting now happens immediately (only) if the search string is longer than the value of the new custom variable `lazy-highlight-delay-max-chars`. Also avoid updating the lazy count in the echo area too often. * isearch.el (lazy-highlight-delay-max-chars): new defcustom * isearch.el (isearch-lazy-highlight-with-timer): new function, factors out a repeated snippet of code. * isearch.el (isearch-lazy-highlight-new-loop, isearch-lazy-highlight-update, isearch-lazy-highlight-buffer-update): use the new `isearch-lazy-highlight-with-timer` function. * isearch.el (isearch-lazy-highlight-new-loop): avoid a call to `isearch-message` that is quickly succeed by a second echo area update, thus causing flicker. --- lisp/isearch.el | 48 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 16 deletions(-) diff --git a/lisp/isearch.el b/lisp/isearch.el index a86678572c..ca0fd1434a 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -352,12 +352,22 @@ lazy-highlight-cleanup :group 'lazy-highlight) (defcustom lazy-highlight-initial-delay 0.25 - "Seconds to wait before beginning to lazily highlight all matches." + "Seconds to wait before beginning to lazily highlight all matches. +This setting only has effect if the current search string is at most +`lazy-highlight-initial-delay' character long." :type 'number :group 'lazy-highlight) +(defcustom lazy-highlight-delay-max-chars 2 + "Size of a search string above which lazy highlight happens immediately." + :type 'number + :group 'lazy-highlight + :version "28.1") + (defcustom lazy-highlight-interval 0 ; 0.0625 - "Seconds between lazily highlighting successive matches." + "Seconds between lazily highlighting successive matches. +This setting only has effect if the current search string is at most +`lazy-highlight-initial-delay' character long." :type 'number :group 'lazy-highlight) @@ -3357,7 +3367,7 @@ isearch-lazy-count-format (not isearch-error) (not isearch-suspended)) (format format-string - (if isearch-forward + (if isearch-lazy-highlight-forward isearch-lazy-count-current (if (eq isearch-lazy-count-current 0) 0 @@ -3858,6 +3868,15 @@ lazy-highlight-cleanup (cancel-timer isearch-lazy-highlight-timer) (setq isearch-lazy-highlight-timer nil))) +(defun isearch-lazy-highlight-with-timer (delay function) + "Arrange for FUNCTION to be called in idle time, possibly with DELAY. +There is no delay if the current search string is longer than +`lazy-highlight-delay-max-chars'." + (setq isearch-lazy-highlight-timer + (run-with-idle-timer + (if (> (length isearch-string) lazy-highlight-delay-max-chars) 0 delay) + nil function))) + (defun isearch-lazy-highlight-new-loop (&optional beg end) "Cleanup any previous `lazy-highlight' loop and begin a new one. BEG and END specify the bounds within which highlighting should occur. @@ -3917,7 +3936,8 @@ isearch-lazy-highlight-new-loop (clrhash isearch-lazy-count-hash) (setq isearch-lazy-count-current nil isearch-lazy-count-total nil) - (isearch-message))) + ;; Delay updating the message if possible, to avoid flicker + (when (string-equal isearch-string "") (isearch-message)))) (setq isearch-lazy-highlight-window-start-changed nil) (setq isearch-lazy-highlight-window-end-changed nil) (setq isearch-lazy-highlight-error isearch-error) @@ -3961,9 +3981,8 @@ isearch-lazy-highlight-new-loop (1- (length isearch-lazy-highlight-last-string))) (point-min)))) (unless (equal isearch-string "") - (setq isearch-lazy-highlight-timer - (run-with-idle-timer lazy-highlight-initial-delay nil - 'isearch-lazy-highlight-start)))) + (isearch-lazy-highlight-with-timer lazy-highlight-initial-delay + 'isearch-lazy-highlight-start))) ;; Update the current match number only in isearch-mode and ;; unless isearch-mode is used specially with isearch-message-function (when (and isearch-lazy-count isearch-mode (null isearch-message-function)) @@ -4101,12 +4120,10 @@ isearch-lazy-highlight-update (if isearch-lazy-highlight-forward (setq isearch-lazy-highlight-end (point-min)) (setq isearch-lazy-highlight-start (point-max))) - (setq isearch-lazy-highlight-timer - (run-at-time lazy-highlight-interval nil - 'isearch-lazy-highlight-buffer-update))) - (setq isearch-lazy-highlight-timer - (run-at-time lazy-highlight-interval nil - 'isearch-lazy-highlight-update))))))))) + (isearch-lazy-highlight-with-timer + lazy-highlight-interval 'isearch-lazy-highlight-buffer-update)) + (isearch-lazy-highlight-with-timer + lazy-highlight-interval 'isearch-lazy-highlight-update)))))))) (defun isearch-lazy-highlight-buffer-update () "Update highlighting of other matches in the full buffer." @@ -4180,9 +4197,8 @@ isearch-lazy-highlight-buffer-update (setq isearch-lazy-count-current (gethash opoint isearch-lazy-count-hash 0)) (isearch-message)) - (setq isearch-lazy-highlight-timer - (run-at-time lazy-highlight-interval nil - 'isearch-lazy-highlight-buffer-update))))))))) + (isearch-lazy-highlight-with-timer + lazy-highlight-interval 'isearch-lazy-highlight-buffer-update)))))))) (defun isearch-resume (string regexp word forward message case-fold) "Resume an incremental search. -- 2.29.2