diff --git a/lisp/isearch.el b/lisp/isearch.el index bc3697deb0a..529676042a2 100644 --- a/lisp/isearch.el +++ b/lisp/isearch.el @@ -2525,10 +2525,11 @@ isearch-delete-char (ding) (isearch-pop-state)) ;; When going back to the hidden match, reopen it and close other overlays. - (when (and (eq search-invisible 'open) isearch-hide-immediately) + (when (and (eq isearch-invisible 'open) isearch-hide-immediately) (if isearch-other-end - (isearch-range-invisible (min (point) isearch-other-end) - (max (point) isearch-other-end)) + (let ((search-invisible isearch-invisible)) + (isearch-range-invisible (min (point) isearch-other-end) + (max (point) isearch-other-end))) (isearch-close-unnecessary-overlays (point) (point)))) (isearch-update)) @@ -4008,6 +4009,7 @@ isearch-lazy-highlight-point-min (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) @@ -4053,6 +4055,8 @@ isearch-lazy-highlight-new-loop 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 @@ -4131,6 +4135,7 @@ isearch-lazy-highlight-new-loop 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 @@ -4180,8 +4185,10 @@ isearch-lazy-highlight-search (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'. @@ -4201,7 +4208,9 @@ isearch-lazy-highlight-match (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) @@ -4350,9 +4359,9 @@ isearch-lazy-highlight-buffer-update ;; 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))) diff --git a/lisp/replace.el b/lisp/replace.el index c7ae77d128b..11e30e62a9e 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -2744,6 +2744,7 @@ replace-highlight (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) diff --git a/test/lisp/isearch-tests.el b/test/lisp/isearch-tests.el index 8cb5e5e4542..37a0ba8579c 100644 --- a/test/lisp/isearch-tests.el +++ b/test/lisp/isearch-tests.el @@ -38,6 +38,157 @@ isearch--test-done ;; 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.