From: Juri Linkov <juri@linkov.net>
To: Drew Adams <drew.adams@oracle.com>
Cc: 29360@debbugs.gnu.org
Subject: bug#29360: 26.0; Add full-buffer choice for `isearch-lazy-highlight'
Date: Sun, 21 Oct 2018 22:06:48 +0300 [thread overview]
Message-ID: <87woqbglvb.fsf@mail.linkov.net> (raw)
In-Reply-To: <c40d7afb-3b80-4fcd-9ae6-ce3d4df315f4@default> (Drew Adams's message of "Sat, 20 Oct 2018 16:09:29 -0700 (PDT)")
[-- Attachment #1: Type: text/plain, Size: 819 bytes --]
> In any case, yes, your suggestion of first doing what we do now
> (highlight the immediate area, using the current algorith), and
> then following that with highlighting the rest of the buffer,
> could be a good idea. Dunno how much that might change
> the existing code.
In the patch attached below, a new function isearch-lazy-highlight-buffer-update
is a copy of isearch-lazy-highlight-update with some changes specific
to highlighting the full buffer. It seems making a duplicate function
is necessary because adding more full-buffer specific conditions to
the existing function isearch-lazy-highlight-update will make it
unmaintainable.
Only a part of the function (that highlights the match) is extracted
into a new function isearch-lazy-highlight-match and shared among these
aforementioned two functions.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: isearch-lazy-highlight-buffer.1.patch --]
[-- Type: text/x-diff, Size: 7163 bytes --]
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 1e785a44c5..cb9e72526b 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -304,7 +304,7 @@ isearch-fail
(defcustom isearch-lazy-highlight t
"Controls the lazy-highlighting during incremental search.
-When non-nil, all text in the buffer matching the current search
+When non-nil, all text on the screen matching the current search
string is highlighted lazily (see `lazy-highlight-initial-delay'
and `lazy-highlight-interval').
@@ -316,6 +316,15 @@ isearch-lazy-highlight
:group 'lazy-highlight
:group 'isearch)
+(defcustom isearch-lazy-highlight-buffer nil
+ "Controls the lazy-highlighting of the whole buffer.
+When non-nil, all text in the buffer matching the current search
+string is highlighted lazily (see `lazy-highlight-initial-delay',
+`lazy-highlight-interval' and `lazy-highlight-buffer-max-at-a-time')."
+ :type 'boolean
+ :group 'lazy-highlight
+ :group 'isearch)
+
;;; Lazy highlight customization.
(defgroup lazy-highlight nil
@@ -351,6 +360,15 @@ lazy-highlight-max-at-a-time
(integer :tag "Some"))
:group 'lazy-highlight)
+(defcustom lazy-highlight-buffer-max-at-a-time 20
+ "Maximum matches to highlight at a time (for `isearch-lazy-highlight-buffer').
+Larger values may reduce Isearch's responsiveness to user input;
+smaller values make matches highlight slowly.
+A value of nil means highlight all matches shown in the buffer."
+ :type '(choice (const :tag "All" nil)
+ (integer :tag "Some"))
+ :group 'lazy-highlight)
+
(defface lazy-highlight
'((((class color) (min-colors 88) (background light))
(:background "paleturquoise"))
@@ -3290,13 +3308,13 @@ isearch-lazy-highlight-search
(+ isearch-lazy-highlight-start
;; Extend bound to match whole string at point
(1- (length isearch-lazy-highlight-last-string)))
- (window-group-end)))
+ (if isearch-lazy-highlight-buffer (point-max) (window-group-end))))
(max (or isearch-lazy-highlight-start-limit (point-min))
(if isearch-lazy-highlight-wrapped
(- isearch-lazy-highlight-end
;; Extend bound to match whole string at point
(1- (length isearch-lazy-highlight-last-string)))
- (window-group-start))))))
+ (if isearch-lazy-highlight-buffer (point-min) (window-group-start)))))))
;; Use a loop like in `isearch-search'.
(while retry
(setq success (isearch-search-string
@@ -3317,6 +3335,20 @@ isearch-lazy-highlight-start
(lazy-highlight-cleanup t) ;remove old overlays
(isearch-lazy-highlight-update))
+(defvar isearch-lazy-highlight-match-function #'isearch-lazy-highlight-match
+ "Function that highlights the found match.
+The function accepts two arguments: the beginning and the end of the match.")
+
+(defun isearch-lazy-highlight-match (mb me)
+ (let ((ov (make-overlay mb me)))
+ (push ov isearch-lazy-highlight-overlays)
+ ;; 1000 is higher than ediff's 100+,
+ ;; but lower than isearch main overlay's 1001
+ (overlay-put ov 'priority 1000)
+ (overlay-put ov 'face 'lazy-highlight)
+ (unless (eq isearch-lazy-highlight 'all-windows)
+ (overlay-put ov 'window (selected-window)))))
+
(defun isearch-lazy-highlight-update ()
"Update highlighting of other matches for current search."
(let ((max lazy-highlight-max-at-a-time)
@@ -3353,16 +3385,8 @@ isearch-lazy-highlight-update
(window-group-start)))
(setq found nil)
(forward-char -1)))
-
;; non-zero-length match
- (let ((ov (make-overlay mb me)))
- (push ov isearch-lazy-highlight-overlays)
- ;; 1000 is higher than ediff's 100+,
- ;; but lower than isearch main overlay's 1001
- (overlay-put ov 'priority 1000)
- (overlay-put ov 'face 'lazy-highlight)
- (unless (eq isearch-lazy-highlight 'all-windows)
- (overlay-put ov 'window (selected-window)))))
+ (funcall isearch-lazy-highlight-match-function mb me))
;; Remember the current position of point for
;; the next call of `isearch-lazy-highlight-update'
;; when `lazy-highlight-max-at-a-time' is too small.
@@ -3384,11 +3408,75 @@ isearch-lazy-highlight-update
(setq isearch-lazy-highlight-start (window-group-end))
(goto-char (min (or isearch-lazy-highlight-end-limit (point-max))
(window-group-end))))))))
- (unless nomore
+ (if nomore
+ (when isearch-lazy-highlight-buffer
+ (setq isearch-lazy-highlight-start (window-group-start))
+ (setq isearch-lazy-highlight-end (window-group-end))
+ (setq isearch-lazy-highlight-wrapped nil)
+ (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)))))))))
+(defun isearch-lazy-highlight-buffer-update ()
+ "Update highlighting of other matches in the whole buffer."
+ (let ((max lazy-highlight-buffer-max-at-a-time)
+ (looping t)
+ nomore)
+ (with-local-quit
+ (save-excursion
+ (save-match-data
+ (goto-char (if isearch-lazy-highlight-forward
+ isearch-lazy-highlight-end
+ isearch-lazy-highlight-start))
+ (while looping
+ (let ((found (isearch-lazy-highlight-search)))
+ (when max
+ (setq max (1- max))
+ (if (<= max 0)
+ (setq looping nil)))
+ (if found
+ (let ((mb (match-beginning 0))
+ (me (match-end 0)))
+ (if (= mb me) ;zero-length match
+ (if isearch-lazy-highlight-forward
+ (if (= mb (if isearch-lazy-highlight-wrapped
+ (window-group-start)
+ (point-max)))
+ (setq found nil)
+ (forward-char 1))
+ (if (= mb (if isearch-lazy-highlight-wrapped
+ (window-group-end)
+ (point-min)))
+ (setq found nil)
+ (forward-char -1)))
+ ;; non-zero-length match
+ (funcall isearch-lazy-highlight-match-function mb me))
+ ;; Remember the current position of point for
+ ;; the next call of `isearch-lazy-highlight-update'
+ ;; when `lazy-highlight-max-at-a-time' is too small.
+ (if isearch-lazy-highlight-forward
+ (setq isearch-lazy-highlight-end (point))
+ (setq isearch-lazy-highlight-start (point)))))
+ ;; not found or zero-length match at the search bound
+ (if (not found)
+ (if isearch-lazy-highlight-wrapped
+ (setq looping nil
+ nomore t)
+ (setq isearch-lazy-highlight-wrapped t)
+ (if isearch-lazy-highlight-forward
+ (progn
+ (setq isearch-lazy-highlight-end (point-min))
+ (goto-char (point-min)))
+ (setq isearch-lazy-highlight-start (point-max))
+ (goto-char (point-max)))))))
+ (if nomore
+ (message "Finished lazy-highlighting the buffer")
+ (setq isearch-lazy-highlight-timer
+ (run-at-time lazy-highlight-interval nil
+ 'isearch-lazy-highlight-buffer-update))))))))
+
(defun isearch-resume (string regexp word forward message case-fold)
"Resume an incremental search.
STRING is the string or regexp searched for.
next prev parent reply other threads:[~2018-10-21 19:06 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-19 19:05 bug#29360: 26.0; Add full-buffer choice for `isearch-lazy-highlight' Drew Adams
2017-11-20 20:53 ` Juri Linkov
2017-11-20 22:40 ` Drew Adams
2017-11-23 21:49 ` Juri Linkov
2017-11-23 23:53 ` Drew Adams
2018-10-18 5:47 ` Drew Adams
2018-10-18 22:18 ` Juri Linkov
2018-10-18 23:25 ` Drew Adams
2018-10-20 17:10 ` Drew Adams
2018-10-20 22:12 ` Juri Linkov
2018-10-20 23:09 ` Drew Adams
2018-10-21 19:06 ` Juri Linkov [this message]
2018-10-22 3:33 ` Drew Adams
2018-10-23 22:05 ` Juri Linkov
2018-10-23 22:51 ` Drew Adams
2018-10-24 23:11 ` Juri Linkov
2018-10-25 0:28 ` Drew Adams
2018-10-27 20:28 ` Juri Linkov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87woqbglvb.fsf@mail.linkov.net \
--to=juri@linkov.net \
--cc=29360@debbugs.gnu.org \
--cc=drew.adams@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this external index
https://git.savannah.gnu.org/cgit/emacs.git
https://git.savannah.gnu.org/cgit/emacs/org-mode.git
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.