Subject: bug#13402: 24.2.92 pretest: bugs in isearch-yank-line in info page. [Patch]

From: Alan Mackenzie <[email-masked]>
Date: Fri, 15 Feb 2013 13:20:04 +0000

Hi, Juri.

On Fri, Feb 15, 2013 at 12:10:45PM +0200, Juri Linkov wrote:
> >> Here is a patch for this change:

> > Thanks, I'll test your patch now.

> I noticed one problem: going to the next match with `C-s'
> (isearch-repeat-forward) doesn't lazy-highlight the previous match
> that was unhighlighted.  The previous match needs to be re-highlighted
> and the next match unhighlighted.  But this requires performing the complete
> round of lazy-highlighting all of lazy-matches on every `C-s' key press
> that will cause significant slow down in lazy-highlighting because it will
> remove the current optimization where `C-s' doesn't cause re-highlighting
> of lazy-matches most of the time (when there is no scrolling or toggling
> of search parameters).

OK, here's a better patch.  As already suggested, every match now has its
lazy-highlight overlay, just that the one overlapping the current match
no longer has the 'face property set.  I don't think there can be more
than one overlapping match.  This approach preserves the optimisation
with `C-s'.

=== modified file 'lisp/isearch.el'
*** lisp/isearch.el	2013-02-01 23:38:41 +0000
--- lisp/isearch.el	2013-02-15 13:09:26 +0000
***************
*** 2862,2867 ****
--- 2862,2869 ----
  (defvar isearch-lazy-highlight-end-limit nil)
  (defvar isearch-lazy-highlight-start nil)
  (defvar isearch-lazy-highlight-end nil)
+ (defvar isearch-lazy-highlight-point nil)
+ (defvar isearch-lazy-highlight-shadowed nil)
  (defvar isearch-lazy-highlight-timer nil)
  (defvar isearch-lazy-highlight-last-string nil)
  (defvar isearch-lazy-highlight-window nil)
***************
*** 2881,2891 ****
  is nil.  This function is called when exiting an incremental search if
  `lazy-highlight-cleanup' is non-nil."
    (interactive '(t))
!   (if (or force lazy-highlight-cleanup)
!       (while isearch-lazy-highlight-overlays
!         (delete-overlay (car isearch-lazy-highlight-overlays))
!         (setq isearch-lazy-highlight-overlays
!               (cdr isearch-lazy-highlight-overlays))))
    (when isearch-lazy-highlight-timer
      (cancel-timer isearch-lazy-highlight-timer)
      (setq isearch-lazy-highlight-timer nil)))
--- 2883,2894 ----
  is nil.  This function is called when exiting an incremental search if
  `lazy-highlight-cleanup' is non-nil."
    (interactive '(t))
!   (when (or force lazy-highlight-cleanup)
!     (while isearch-lazy-highlight-overlays
!       (delete-overlay (car isearch-lazy-highlight-overlays))
!       (setq isearch-lazy-highlight-overlays
! 	    (cdr isearch-lazy-highlight-overlays)))
!     (setq isearch-lazy-highlight-shadowed nil))
    (when isearch-lazy-highlight-timer
      (cancel-timer isearch-lazy-highlight-timer)
      (setq isearch-lazy-highlight-timer nil)))
***************
*** 2894,2955 ****
                                  'lazy-highlight-cleanup
                                  "22.1")
  
  (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.
  This is called when `isearch-update' is invoked (which can cause the
  search string to change or the window to scroll).  It is also used
  by other Emacs features."
!   (when (and (null executing-kbd-macro)
!              (sit-for 0)         ;make sure (window-start) is credible
!              (or (not (equal isearch-string
!                              isearch-lazy-highlight-last-string))
!                  (not (eq (selected-window)
!                           isearch-lazy-highlight-window))
! 		 (not (eq isearch-lazy-highlight-case-fold-search
! 			  isearch-case-fold-search))
! 		 (not (eq isearch-lazy-highlight-regexp
! 			  isearch-regexp))
! 		 (not (eq isearch-lazy-highlight-word
! 			  isearch-word))
! 		 (not (eq isearch-lazy-highlight-lax-whitespace
! 			  isearch-lax-whitespace))
! 		 (not (eq isearch-lazy-highlight-regexp-lax-whitespace
! 			  isearch-regexp-lax-whitespace))
!                  (not (= (window-start)
!                          isearch-lazy-highlight-window-start))
!                  (not (= (window-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.
! 		 (not (equal isearch-error
! 			     isearch-lazy-highlight-error))))
!     ;; something important did indeed change
!     (lazy-highlight-cleanup t) ;kill old loop & remove overlays
!     (setq isearch-lazy-highlight-error isearch-error)
!     ;; It used to check for `(not isearch-error)' here, but actually
!     ;; lazy-highlighting might find matches to highlight even when
!     ;; `isearch-error' is non-nil.  (Bug#9918)
!     (setq isearch-lazy-highlight-start-limit beg
! 	  isearch-lazy-highlight-end-limit end)
!     (setq isearch-lazy-highlight-window       (selected-window)
! 	  isearch-lazy-highlight-window-start (window-start)
! 	  isearch-lazy-highlight-window-end   (window-end)
! 	  isearch-lazy-highlight-start        (point)
! 	  isearch-lazy-highlight-end          (point)
! 	  isearch-lazy-highlight-wrapped      nil
! 	  isearch-lazy-highlight-last-string  isearch-string
! 	  isearch-lazy-highlight-case-fold-search isearch-case-fold-search
! 	  isearch-lazy-highlight-regexp       isearch-regexp
! 	  isearch-lazy-highlight-lax-whitespace   isearch-lax-whitespace
! 	  isearch-lazy-highlight-regexp-lax-whitespace isearch-regexp-lax-whitespace
! 	  isearch-lazy-highlight-word         isearch-word
! 	  isearch-lazy-highlight-forward      isearch-forward)
!       (unless (equal isearch-string "")
! 	(setq isearch-lazy-highlight-timer
! 	      (run-with-idle-timer lazy-highlight-initial-delay nil
! 				   'isearch-lazy-highlight-update)))))
  
  (defun isearch-lazy-highlight-search ()
    "Search ahead for the next or previous match, for lazy highlighting.
--- 2897,2979 ----
                                  'lazy-highlight-cleanup
                                  "22.1")
  
+ (defun isearch-lazy-highlight-move-shadow ()
+   "Move the lazy highlight \"shadow\" to the current match position."
+   (if isearch-lazy-highlight-shadowed
+       (overlay-put isearch-lazy-highlight-shadowed 'face lazy-highlight-face))
+   (let ((ovs (if isearch-forward
+ 		 (overlays-in isearch-other-end (point))
+ 	       (overlays-in (point) isearch-other-end)))
+ 	ov)
+     (while ovs
+       (setq ov (car ovs)
+ 	    ovs (cdr ovs))
+       (when (memq ov isearch-lazy-highlight-overlays)
+ 	(overlay-put ov 'face nil)
+ 	(setq isearch-lazy-highlight-shadowed ov)))))
+ 
  (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.
  This is called when `isearch-update' is invoked (which can cause the
  search string to change or the window to scroll).  It is also used
  by other Emacs features."
!   (if (and (null executing-kbd-macro)
! 	   (sit-for 0)		 ;make sure (window-start) is credible
! 	   (or (not (equal isearch-string
! 			   isearch-lazy-highlight-last-string))
! 	       (not (eq (selected-window)
! 			isearch-lazy-highlight-window))
! 	       (not (eq isearch-lazy-highlight-case-fold-search
! 			isearch-case-fold-search))
! 	       (not (eq isearch-lazy-highlight-regexp
! 			isearch-regexp))
! 	       (not (eq isearch-lazy-highlight-word
! 			isearch-word))
! 	       (not (eq isearch-lazy-highlight-lax-whitespace
! 			isearch-lax-whitespace))
! 	       (not (eq isearch-lazy-highlight-regexp-lax-whitespace
! 			isearch-regexp-lax-whitespace))
! 	       (not (= (window-start)
! 		       isearch-lazy-highlight-window-start))
! 	       (not (= (window-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.
! 	       (not (equal isearch-error
! 			   isearch-lazy-highlight-error))))
!       ;; something important did indeed change
!       (progn
! 	(lazy-highlight-cleanup t)    ;kill old loop & remove overlays
! 	(setq isearch-lazy-highlight-error isearch-error)
! 	;; It used to check for `(not isearch-error)' here, but actually
! 	;; lazy-highlighting might find matches to highlight even when
! 	;; `isearch-error' is non-nil.  (Bug#9918)
! 	(setq isearch-lazy-highlight-start-limit beg
! 	      isearch-lazy-highlight-end-limit end)
! 	(setq isearch-lazy-highlight-window       (selected-window)
! 	      isearch-lazy-highlight-window-start (window-start)
! 	      isearch-lazy-highlight-window-end   (window-end)
! 	      isearch-lazy-highlight-start        (point)
! 	      isearch-lazy-highlight-end          (point)
! 	      isearch-lazy-highlight-point        (point)
! 	      isearch-lazy-highlight-shadowed     nil
! 	      isearch-lazy-highlight-wrapped      nil
! 	      isearch-lazy-highlight-last-string  isearch-string
! 	      isearch-lazy-highlight-case-fold-search isearch-case-fold-search
! 	      isearch-lazy-highlight-regexp       isearch-regexp
! 	      isearch-lazy-highlight-lax-whitespace   isearch-lax-whitespace
! 	      isearch-lazy-highlight-regexp-lax-whitespace isearch-regexp-lax-whitespace
! 	      isearch-lazy-highlight-word         isearch-word
! 	      isearch-lazy-highlight-forward      isearch-forward)
! 	(unless (equal isearch-string "")
! 	  (setq isearch-lazy-highlight-timer
! 		(run-with-idle-timer lazy-highlight-initial-delay nil
! 				     'isearch-lazy-highlight-update))))
! 
!     ;; Swap the previously "shadowed" lazy highlight overlay for the new one.
!     (isearch-lazy-highlight-move-shadow)))
  
  (defun isearch-lazy-highlight-search ()
    "Search ahead for the next or previous match, for lazy highlighting.
***************
*** 3033,3039 ****
  			  ;; 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-face)
  			  (overlay-put ov 'window (selected-window))))
  		      (if isearch-lazy-highlight-forward
  			  (setq isearch-lazy-highlight-end (point))
--- 3057,3069 ----
  			  ;; 1000 is higher than ediff's 100+,
  			  ;; but lower than isearch main overlay's 1001
  			  (overlay-put ov 'priority 1000)
! 			  (if (if isearch-lazy-highlight-forward
! 				  (or (<= me isearch-other-end)
! 				      (>= mb isearch-lazy-highlight-point))
! 				(or (<= me isearch-lazy-highlight-point)
! 				    (>= mb isearch-other-end)))
! 			      (overlay-put ov 'face lazy-highlight-face)
! 			    (setq isearch-lazy-highlight-shadowed ov))
  			  (overlay-put ov 'window (selected-window))))
  		      (if isearch-lazy-highlight-forward
  			  (setq isearch-lazy-highlight-end (point))

-- 
Alan Mackenzie (Nuremberg, Germany).