Improve invisibility handling in isearch-lazy-highlight (bug#40808)

* lisp/isearch.el (isearch-lazy-highlight-invisible): New variable.
(isearch-lazy-highlight-new-loop, isearch-lazy-highlight-search)
(isearch-lazy-highlight-match, isearch-lazy-highlight-buffer-update): Use it.

* lisp/replace.el (replace-highlight): Let-bind isearch-invisible
to search-invisible.

* test/lisp/isearch-tests.el (isearch--test-invisible): New test.
This commit is contained in:
Juri Linkov 2023-11-20 19:57:57 +02:00
parent 5024ee1ad1
commit 9d292262f5
3 changed files with 165 additions and 5 deletions

View file

@ -4054,6 +4054,7 @@ since they have special meaning in a regexp."
(defvar isearch-lazy-highlight-point-max nil)
(defvar isearch-lazy-highlight-buffer nil)
(defvar isearch-lazy-highlight-case-fold-search nil)
(defvar isearch-lazy-highlight-invisible nil)
(defvar isearch-lazy-highlight-regexp nil)
(defvar isearch-lazy-highlight-lax-whitespace nil)
(defvar isearch-lazy-highlight-regexp-lax-whitespace nil)
@ -4099,6 +4100,8 @@ by other Emacs features."
isearch-lazy-highlight-window-group))
(not (eq isearch-lazy-highlight-case-fold-search
isearch-case-fold-search))
(not (eq isearch-lazy-highlight-invisible
isearch-invisible))
(not (eq isearch-lazy-highlight-regexp
isearch-regexp))
(not (eq isearch-lazy-highlight-regexp-function
@ -4177,6 +4180,7 @@ by other Emacs features."
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-invisible isearch-invisible
isearch-lazy-highlight-regexp isearch-regexp
isearch-lazy-highlight-lax-whitespace isearch-lax-whitespace
isearch-lazy-highlight-regexp-lax-whitespace isearch-regexp-lax-whitespace
@ -4226,8 +4230,10 @@ Attempt to do the search exactly the way the pending Isearch would."
(isearch-forward isearch-lazy-highlight-forward)
;; Count all invisible matches, but highlight only
;; matches that can be opened by visiting them later
(search-invisible (or (not (null isearch-lazy-count))
'can-be-opened))
(search-invisible
(or (not (null isearch-lazy-count))
(and (eq isearch-lazy-highlight-invisible 'open)
'can-be-opened)))
(retry t)
(success nil))
;; Use a loop like in `isearch-search'.
@ -4247,7 +4253,9 @@ Attempt to do the search exactly the way the pending Isearch would."
(when (or (not isearch-lazy-count)
;; Recheck the match that possibly was intended
;; for counting only, but not for highlighting
(let ((search-invisible 'can-be-opened))
(let ((search-invisible
(and (eq isearch-lazy-highlight-invisible 'open)
'can-be-opened)))
(funcall isearch-filter-predicate mb me)))
(let ((ov (make-overlay mb me)))
(push ov isearch-lazy-highlight-overlays)
@ -4396,9 +4404,9 @@ Attempt to do the search exactly the way the pending Isearch would."
;; value `open' since then lazy-highlight
;; will open all overlays with matches.
(if (not (let ((search-invisible
(if (eq search-invisible 'open)
(if (eq isearch-lazy-highlight-invisible 'open)
'can-be-opened
search-invisible)))
isearch-lazy-highlight-invisible)))
(funcall isearch-filter-predicate mb me)))
(setq isearch-lazy-count-invisible
(1+ (or isearch-lazy-count-invisible 0)))

View file

@ -2755,6 +2755,7 @@ to a regexp that is actually used for the search.")
(isearch-regexp-lax-whitespace
replace-regexp-lax-whitespace)
(isearch-case-fold-search case-fold)
(isearch-invisible search-invisible)
(isearch-forward (not backward))
(isearch-other-end match-beg)
(isearch-error nil)

View file

@ -38,6 +38,157 @@
;; Bug #21091: let `isearch-done' work without `isearch-update'.
(isearch-done))
;; Search invisible.
(declare-function outline-hide-sublevels "outline")
(ert-deftest isearch--test-invisible ()
(require 'outline)
(with-temp-buffer
(set-window-buffer nil (current-buffer))
(insert "\n1\n"
(propertize "2" 'invisible t)
(propertize "3" 'inhibit-isearch t)
"\n* h\n4\n\n")
(outline-mode)
(outline-hide-sublevels 1)
(goto-char (point-min))
(let ((isearch-lazy-count nil)
(search-invisible t)
(inhibit-message t))
(isearch-forward-regexp nil 1)
(isearch-process-search-string "[0-9]" "[0-9]")
(should (eq (point) 3))
(isearch-lazy-highlight-start)
(should (equal (seq-uniq (mapcar #'overlay-start isearch-lazy-highlight-overlays))
'(2)))
(isearch-repeat-forward)
(should (eq (point) 5))
(should (get-char-property 4 'invisible))
(isearch-repeat-forward)
(should (eq (point) 12))
(should (get-char-property 11 'invisible))
(goto-char isearch-opoint)
(isearch-done t)
(isearch-forward-regexp nil 1)
(setq isearch-invisible nil) ;; isearch-toggle-invisible
(isearch-process-search-string "[0-9]" "[0-9]")
(isearch-lazy-highlight-start)
(should (equal (seq-uniq (mapcar #'overlay-start isearch-lazy-highlight-overlays))
'(2)))
(goto-char isearch-opoint)
(isearch-done t)
(isearch-forward-regexp nil 1)
(setq isearch-invisible 'open) ;; isearch-toggle-invisible
(isearch-process-search-string "[0-9]" "[0-9]")
(should (eq (point) 3))
(isearch-lazy-highlight-start)
(should (equal (seq-uniq (mapcar #'overlay-start isearch-lazy-highlight-overlays))
'(2 11)))
(let ((isearch-hide-immediately t))
(isearch-repeat-forward)
(should (eq (point) 12))
(should-not (get-char-property 11 'invisible))
(isearch-delete-char)
(should (get-char-property 11 'invisible)))
(let ((isearch-hide-immediately nil))
(isearch-repeat-forward)
(should (eq (point) 12))
(should-not (get-char-property 11 'invisible))
(isearch-delete-char)
(should-not (get-char-property 11 'invisible)))
(goto-char isearch-opoint)
(isearch-done t)
(isearch-clean-overlays)
(should (get-char-property 11 'invisible)))
(let ((isearch-lazy-count t)
(search-invisible t)
(inhibit-message t))
(isearch-forward-regexp nil 1)
(isearch-process-search-string "[0-9]" "[0-9]")
(should (eq (point) 3))
(setq isearch-lazy-count-invisible nil isearch-lazy-count-total nil)
(isearch-lazy-highlight-start)
(isearch-lazy-highlight-buffer-update)
(should (eq isearch-lazy-count-invisible nil))
(should (eq isearch-lazy-count-total 3))
(should (equal (seq-uniq (mapcar #'overlay-start isearch-lazy-highlight-overlays))
'(2)))
(isearch-repeat-forward)
(should (eq (point) 5))
(should (get-char-property 4 'invisible))
(isearch-repeat-forward)
(should (eq (point) 12))
(should (get-char-property 11 'invisible))
(goto-char isearch-opoint)
(isearch-done t)
(isearch-forward-regexp nil 1)
(setq isearch-invisible nil) ;; isearch-toggle-invisible
(isearch-process-search-string "[0-9]" "[0-9]")
(setq isearch-lazy-count-invisible nil isearch-lazy-count-total nil)
(isearch-lazy-highlight-start)
(isearch-lazy-highlight-buffer-update)
(should (eq isearch-lazy-count-invisible 2))
(should (eq isearch-lazy-count-total 1))
(should (equal (seq-uniq (mapcar #'overlay-start isearch-lazy-highlight-overlays))
'(2)))
(goto-char isearch-opoint)
(isearch-done t)
(isearch-forward-regexp nil 1)
(setq isearch-invisible 'open) ;; isearch-toggle-invisible
(isearch-process-search-string "[0-9]" "[0-9]")
(should (eq (point) 3))
(setq isearch-lazy-count-invisible nil isearch-lazy-count-total nil)
(isearch-lazy-highlight-start)
(isearch-lazy-highlight-buffer-update)
(should (eq isearch-lazy-count-invisible 1))
(should (eq isearch-lazy-count-total 2))
(should (equal (seq-uniq (mapcar #'overlay-start isearch-lazy-highlight-overlays))
'(2 11)))
(let ((isearch-hide-immediately t))
(isearch-repeat-forward)
(should (eq (point) 12))
(should-not (get-char-property 11 'invisible))
(isearch-delete-char)
(should (get-char-property 11 'invisible)))
(let ((isearch-hide-immediately nil))
(isearch-repeat-forward)
(should (eq (point) 12))
(should-not (get-char-property 11 'invisible))
(isearch-delete-char)
(should-not (get-char-property 11 'invisible)))
(goto-char isearch-opoint)
(isearch-done t)
(isearch-clean-overlays)
(should (get-char-property 11 'invisible)))))
;; Search functions.