all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Juri Linkov <juri@linkov.net>
To: 40808@debbugs.gnu.org
Subject: bug#40808: 27.0.91; inaccuracy in isearch-lazy-count
Date: Sat, 10 Dec 2022 19:51:39 +0200	[thread overview]
Message-ID: <86cz8rgn9w.fsf@mail.linkov.net> (raw)
In-Reply-To: <868rp4hmto.fsf@mail.linkov.net> (Juri Linkov's message of "Thu,  07 Jul 2022 20:09:07 +0300")

[-- Attachment #1: Type: text/plain, Size: 658 bytes --]

> So here is the complete implementation that was made possible
> thanks to the suggestions in
> https://lists.gnu.org/archive/html/emacs-devel/2022-06/msg01208.html
>
> For example, searching for the word "nongnu" in etc/ORG-NEWS
> when all outlines are collapsed with isearch-lazy-count=t
> will show such prompts:
>
> search-invisible = t      1/4 I-search:
> search-invisible = open   1/2 (invisible 2) I-search:
> search-invisible = nil    0/0 (invisible 4) I-search:
>
> where such numbers as "1/2" show the matches that can be visited by isearch,
> and "(invisible 2)" are the rest of matches unreachable by isearch.

Here are more fixes with tests:


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: isearch-lazy-highlight-invisible.patch --]
[-- Type: text/x-diff, Size: 9790 bytes --]

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))
 
+\f
+;; 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)))))
+
 \f
 ;; Search functions.
 

  parent reply	other threads:[~2022-12-10 17:51 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-12  1:58 bug#40808: 27.0.91; inaccuracy in isearch-lazy-count Drew Adams
2022-07-07 17:09 ` Juri Linkov
2022-07-08 17:48   ` Juri Linkov
2022-12-10 17:51   ` Juri Linkov [this message]
2022-12-12 17:44     ` Juri Linkov
2022-12-28 18:54       ` Juri Linkov
  -- strict thread matches above, loose matches on Subject: below --
2020-04-24  6:42 Abdullah Asad
2020-04-25 20:53 ` Juri Linkov
2020-04-28 18:46   ` Abdullah Asad
2020-04-28 19:19     ` Eli Zaretskii
2020-04-28 23:54       ` Juri Linkov
2020-04-29  7:11         ` Eli Zaretskii
2020-04-29 20:56           ` Juri Linkov
2020-04-30 20:18             ` Juri Linkov
2020-05-01  5:58               ` Eli Zaretskii
2020-05-03 22:33                 ` 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=86cz8rgn9w.fsf@mail.linkov.net \
    --to=juri@linkov.net \
    --cc=40808@debbugs.gnu.org \
    /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.