emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] master 3dd16a8: * lisp/isearch.el (lazy-highlight-buffer):


From: Juri Linkov
Subject: [Emacs-diffs] master 3dd16a8: * lisp/isearch.el (lazy-highlight-buffer): New defcustom. (Bug#29360)
Date: Sat, 27 Oct 2018 16:28:01 -0400 (EDT)

branch: master
commit 3dd16a89bf410d77e9ddc41cbfbbd4b343928d6d
Author: Juri Linkov <address@hidden>
Commit: Juri Linkov <address@hidden>

    * lisp/isearch.el (lazy-highlight-buffer): New defcustom.  (Bug#29360)
    
    (lazy-highlight-buffer-max-at-a-time): New defcustom.
    (isearch-lazy-highlight-buffer): New defvar.
    (isearch-lazy-highlight-new-loop): Don't check changes in window
    boundaries when lazy-highlight-buffer is non-nil.
    Move code that extends start/end to match whole string at point
    here from isearch-lazy-highlight-search.
    (isearch-lazy-highlight-search): Add args string and bound
    like in other search functions.  Move calculation of bound
    to isearch-lazy-highlight-update.
    (isearch-lazy-highlight-match): New function with code extracted from
    isearch-lazy-highlight-update to be called also from
    isearch-lazy-highlight-buffer-update.
    (isearch-lazy-highlight-update): Reuse the values returned from
    window-group-start and window-group-end.  At the end schedule the
    timer to call isearch-lazy-highlight-buffer-update when
    isearch-lazy-highlight-buffer is non-nil.
    (isearch-lazy-highlight-buffer-update): New function.
---
 etc/NEWS        |   8 +++
 lisp/isearch.el | 185 +++++++++++++++++++++++++++++++++++++++++++-------------
 2 files changed, 152 insertions(+), 41 deletions(-)

diff --git a/etc/NEWS b/etc/NEWS
index be32ac6..57a8306 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -581,6 +581,14 @@ can now be searched via 'C-s'.
 
 ** Search and Replace
 
+*** lazy-highlight-buffer highlights matches in the full buffer.
+It is useful in combination with lazy-highlight-cleanup customized to nil
+to leave matches highlighted in the whole buffer after exiting isearch.
+Also when lazy-highlight-buffer prepares highlighting in the buffer,
+navigation through the matches without flickering is more smooth.
+lazy-highlight-buffer-max-at-a-time controls the number of matches to
+highlight in one iteration while processing the full buffer.
+
 +++
 *** New isearch bindings.
 
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 38110d0..580b3ac 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -304,9 +304,9 @@ are `word-search-regexp' \(`\\[isearch-toggle-word]'), 
`isearch-symbol-regexp'
 
 (defcustom isearch-lazy-highlight t
   "Controls the lazy-highlighting during incremental search.
-When non-nil, all text in the buffer matching the current search
-string is highlighted lazily (see `lazy-highlight-initial-delay'
-and `lazy-highlight-interval').
+When non-nil, all text currently visible on the screen
+matching the current search string is highlighted lazily
+(see `lazy-highlight-initial-delay' and `lazy-highlight-interval').
 
 When multiple windows display the current buffer, the
 highlighting is displayed only on the selected window, unless
@@ -351,6 +351,27 @@ A value of nil means highlight all matches shown on the 
screen."
                 (integer :tag "Some"))
   :group 'lazy-highlight)
 
+(defcustom lazy-highlight-buffer-max-at-a-time 20
+  "Maximum matches to highlight at a time (for `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 in the buffer."
+  :type '(choice (const :tag "All" nil)
+                (integer :tag "Some"))
+  :group 'lazy-highlight
+  :version "27.1")
+
+(defcustom lazy-highlight-buffer nil
+  "Controls the lazy-highlighting of the full 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').
+This is useful when `lazy-highlight-cleanup' is customized to nil
+and doesn't remove full-buffer highlighting after a search."
+  :type 'boolean
+  :group 'lazy-highlight
+  :version "27.1")
+
 (defface lazy-highlight
   '((((class color) (min-colors 88) (background light))
      (:background "paleturquoise"))
@@ -3181,6 +3202,7 @@ since they have special meaning in a regexp."
 (defvar isearch-lazy-highlight-window-group nil)
 (defvar isearch-lazy-highlight-window-start nil)
 (defvar isearch-lazy-highlight-window-end nil)
+(defvar isearch-lazy-highlight-buffer nil)
 (defvar isearch-lazy-highlight-case-fold-search nil)
 (defvar isearch-lazy-highlight-regexp nil)
 (defvar isearch-lazy-highlight-lax-whitespace nil)
@@ -3229,10 +3251,12 @@ by other Emacs features."
                          isearch-lax-whitespace))
                 (not (eq isearch-lazy-highlight-regexp-lax-whitespace
                          isearch-regexp-lax-whitespace))
-                 (not (= (window-group-start)
-                         isearch-lazy-highlight-window-start))
-                 (not (= (window-group-end) ; Window may have been 
split/joined.
-                        isearch-lazy-highlight-window-end))
+                (not (or lazy-highlight-buffer
+                         (= (window-group-start)
+                            isearch-lazy-highlight-window-start)))
+                (not (or lazy-highlight-buffer
+                         (= (window-group-end) ; Window may have been 
split/joined.
+                            isearch-lazy-highlight-window-end)))
                 (not (eq isearch-forward
                          isearch-lazy-highlight-forward))
                 ;; In case we are recovering from an error.
@@ -3250,6 +3274,7 @@ by other Emacs features."
           isearch-lazy-highlight-window-group (selected-window-group)
          isearch-lazy-highlight-window-start (window-group-start)
          isearch-lazy-highlight-window-end   (window-group-end)
+         isearch-lazy-highlight-buffer       lazy-highlight-buffer
          ;; Start lazy-highlighting at the beginning of the found
          ;; match (`isearch-other-end').  If no match, use point.
          ;; One of the next two variables (depending on search direction)
@@ -3267,12 +3292,22 @@ by other Emacs features."
          isearch-lazy-highlight-regexp-lax-whitespace 
isearch-regexp-lax-whitespace
          isearch-lazy-highlight-regexp-function  isearch-regexp-function
          isearch-lazy-highlight-forward      isearch-forward)
+    ;; Extend start/end to match whole string at point (bug#19353)
+    (if isearch-lazy-highlight-forward
+        (setq isearch-lazy-highlight-start
+             (min (+ isearch-lazy-highlight-start
+                     (1- (length isearch-lazy-highlight-last-string)))
+                  (point-max)))
+      (setq isearch-lazy-highlight-end
+           (max (- isearch-lazy-highlight-end
+                   (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)))))
 
-(defun isearch-lazy-highlight-search ()
+(defun isearch-lazy-highlight-search (string bound)
   "Search ahead for the next or previous match, for lazy highlighting.
 Attempt to do the search exactly the way the pending Isearch would."
   (condition-case nil
@@ -3286,24 +3321,10 @@ Attempt to do the search exactly the way the pending 
Isearch would."
            (isearch-forward isearch-lazy-highlight-forward)
            (search-invisible nil)      ; don't match invisible text
            (retry t)
-           (success nil)
-           (bound (if isearch-lazy-highlight-forward
-                      (min (or isearch-lazy-highlight-end-limit (point-max))
-                           (if isearch-lazy-highlight-wrapped
-                               (+ isearch-lazy-highlight-start
-                                  ;; Extend bound to match whole string at 
point
-                                  (1- (length 
isearch-lazy-highlight-last-string)))
-                             (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))))))
+           (success nil))
        ;; Use a loop like in `isearch-search'.
        (while retry
-         (setq success (isearch-search-string
-                        isearch-lazy-highlight-last-string bound t))
+         (setq success (isearch-search-string string bound t))
          ;; Clear RETRY unless the search predicate says
          ;; to skip this search hit.
          (if (or (not success)
@@ -3315,6 +3336,17 @@ Attempt to do the search exactly the way the pending 
Isearch would."
        success)
     (error nil)))
 
+(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 (or (eq isearch-lazy-highlight 'all-windows)
+                isearch-lazy-highlight-buffer)
+      (overlay-put ov 'window (selected-window)))))
+
 (defun isearch-lazy-highlight-start ()
   "Start a new lazy-highlight updating loop."
   (lazy-highlight-cleanup t) ;remove old overlays
@@ -3324,19 +3356,32 @@ Attempt to do the search exactly the way the pending 
Isearch would."
   "Update highlighting of other matches for current search."
   (let ((max lazy-highlight-max-at-a-time)
         (looping t)
-        nomore)
+        nomore window-start window-end)
     (with-local-quit
       (save-selected-window
        (if (and (window-live-p isearch-lazy-highlight-window)
                 (not (memq (selected-window) 
isearch-lazy-highlight-window-group)))
            (select-window isearch-lazy-highlight-window))
+       (setq window-start (window-group-start))
+       (setq window-end (window-group-end))
        (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)))
+             (let* ((bound (if isearch-lazy-highlight-forward
+                               (min (or isearch-lazy-highlight-end-limit 
(point-max))
+                                    (if isearch-lazy-highlight-wrapped
+                                        isearch-lazy-highlight-start
+                                      window-end))
+                             (max (or isearch-lazy-highlight-start-limit 
(point-min))
+                                  (if isearch-lazy-highlight-wrapped
+                                      isearch-lazy-highlight-end
+                                    window-start))))
+                    (found (isearch-lazy-highlight-search
+                            isearch-lazy-highlight-last-string
+                            bound)))
                (when max
                  (setq max (1- max))
                  (if (<= max 0)
@@ -3348,24 +3393,17 @@ Attempt to do the search exactly the way the pending 
Isearch would."
                          (if isearch-lazy-highlight-forward
                              (if (= mb (if isearch-lazy-highlight-wrapped
                                            isearch-lazy-highlight-start
-                                         (window-group-end)))
+                                         window-end))
                                  (setq found nil)
                                (forward-char 1))
                            (if (= mb (if isearch-lazy-highlight-wrapped
                                          isearch-lazy-highlight-end
-                                       (window-group-start)))
+                                       window-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)))))
+                       (isearch-lazy-highlight-match 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.
@@ -3381,17 +3419,82 @@ Attempt to do the search exactly the way the pending 
Isearch would."
                      (setq isearch-lazy-highlight-wrapped t)
                      (if isearch-lazy-highlight-forward
                          (progn
-                           (setq isearch-lazy-highlight-end 
(window-group-start))
+                           (setq isearch-lazy-highlight-end window-start)
                            (goto-char (max (or 
isearch-lazy-highlight-start-limit (point-min))
-                                           (window-group-start))))
-                       (setq isearch-lazy-highlight-start (window-group-end))
+                                           window-start)))
+                       (setq isearch-lazy-highlight-start window-end)
                        (goto-char (min (or isearch-lazy-highlight-end-limit 
(point-max))
-                                       (window-group-end))))))))
-           (unless nomore
+                                       window-end)))))))
+           (if nomore
+               (when isearch-lazy-highlight-buffer
+                 (if isearch-lazy-highlight-forward
+                     (setq isearch-lazy-highlight-end (point-min))
+                   (setq isearch-lazy-highlight-start (point-max)))
+                 (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 full buffer."
+  (let ((max lazy-highlight-buffer-max-at-a-time)
+        (looping t)
+        nomore window-start window-end)
+    (with-local-quit
+      (save-selected-window
+       (if (and (window-live-p isearch-lazy-highlight-window)
+                (not (memq (selected-window) 
isearch-lazy-highlight-window-group)))
+           (select-window isearch-lazy-highlight-window))
+       (setq window-start (window-group-start))
+       (setq window-end (window-group-end))
+       (save-excursion
+         (save-match-data
+           (goto-char (if isearch-lazy-highlight-forward
+                          isearch-lazy-highlight-end
+                        isearch-lazy-highlight-start))
+           (while looping
+             (let* ((bound (if isearch-lazy-highlight-forward
+                               (or isearch-lazy-highlight-end-limit 
(point-max))
+                             (or isearch-lazy-highlight-start-limit 
(point-min))))
+                    (found (isearch-lazy-highlight-search
+                            isearch-lazy-highlight-last-string
+                            bound)))
+               (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 (point-max))
+                                 (setq found nil)
+                               (forward-char 1))
+                           (if (= mb (point-min))
+                               (setq found nil)
+                             (forward-char -1)))
+                       ;; Already highlighted by isearch-lazy-highlight-update
+                       (unless (and (>= mb window-start) (<= me window-end))
+                         ;; non-zero-length match
+                         (isearch-lazy-highlight-match mb me)))
+                     ;; Remember the current position of point for
+                     ;; the next call of `isearch-lazy-highlight-update'
+                     ;; when `lazy-highlight-buffer-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)
+                   (setq looping nil
+                         nomore  t))))
+           (unless nomore
+             (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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]