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.
next prev 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.