emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master c8acc5f: Introduce a new 'inhibit-isearch' text property


From: Lars Ingebrigtsen
Subject: master c8acc5f: Introduce a new 'inhibit-isearch' text property
Date: Fri, 5 Nov 2021 23:59:13 -0400 (EDT)

branch: master
commit c8acc5fd92ad9979fc5870623014290cad998337
Author: Lars Ingebrigtsen <larsi@gnus.org>
Commit: Lars Ingebrigtsen <larsi@gnus.org>

    Introduce a new 'inhibit-isearch' text property
    
    * doc/lispref/text.texi (Special Properties): Mention it.
    
    * lisp/image.el (insert-image): Make `C-s' skip over the image data.
    * lisp/isearch.el (isearch--search-skip-inhibited): New function.
    (isearch-search-string): Use it.
    (isearch--invisible-p): New function.
    (isearch-range-invisible): Use it.
---
 doc/lispref/text.texi |  5 +++++
 etc/NEWS              |  6 ++++++
 lisp/image.el         |  1 +
 lisp/isearch.el       | 40 ++++++++++++++++++++++++++++++++++------
 4 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/doc/lispref/text.texi b/doc/lispref/text.texi
index 163ac90..fa1135b 100644
--- a/doc/lispref/text.texi
+++ b/doc/lispref/text.texi
@@ -3615,6 +3615,11 @@ edited even in read-only buffers.  @xref{Read Only 
Buffers}.
 A non-@code{nil} @code{invisible} property can make a character invisible
 on the screen.  @xref{Invisible Text}, for details.
 
+@kindex inhibit-isearch @r{(text property)}
+@item inhibit-isearch
+A non-@code{nil} @code{inhibit-isearch} property will make isearch
+skip the text.
+
 @item intangible
 @kindex intangible @r{(text property)}
 If a group of consecutive characters have equal and non-@code{nil}
diff --git a/etc/NEWS b/etc/NEWS
index 78c8481..4d38968 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -432,6 +432,12 @@ Use 'exif-parse-file' and 'exif-field' instead.
 
 * Lisp Changes in Emacs 29.1
 
++++
+*** New text property 'inhibit-isearch'.
+If set, 'isearch' will skip these areas, which can be useful (for
+instance) when covering huge amounts of data (that has no meaningful
+searchable data, like image data) with a 'display' text property.
+
 ---
 *** New user option 'pp-use-max-width'.
 If non-nil, 'pp' will attempt to limit the line length when formatting
diff --git a/lisp/image.el b/lisp/image.el
index bfcbb66..adcdf0e 100644
--- a/lisp/image.el
+++ b/lisp/image.el
@@ -644,6 +644,7 @@ height of the image; integer values are taken as pixel 
values."
                                        (list (cons 'slice slice) image)
                                      image)
                                    rear-nonsticky t
+                                  inhibit-isearch t
                                    keymap ,image-map))))
 
 
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 52e4a39..4c4b947 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -3536,6 +3536,20 @@ Can be changed via `isearch-search-fun-function' for 
special needs."
        (if isearch-forward #'re-search-forward #'re-search-backward)
        regexp bound noerror count))))
 
+(defun isearch--search-skip-inhibited (func string bound noerror)
+  "Search for STRING with FUNC, but skip areas where isearch is inhibited.
+Returns the value of the (final) call to the search function."
+  (let (pos)
+    (while (and (setq pos (funcall func string bound noerror))
+                ;; If we're inhibited here, skip to the end of that
+                ;; area and try again.
+                (get-text-property (match-beginning 0) 'inhibit-isearch)
+                (goto-char (next-single-property-change
+                            (match-beginning 0)
+                            'inhibit-isearch
+                            nil (point-max)))))
+    pos))
+
 (defun isearch-search-string (string bound noerror)
   "Search for the first occurrence of STRING or its translation.
 STRING's characters are translated using `translation-table-for-input'
@@ -3547,7 +3561,8 @@ The match found must not extend after that position.
 Optional third argument, if t, means if fail just return nil (no error).
   If not nil and not t, move to limit of search and return nil."
   (let* ((func (isearch-search-fun))
-         (pos1 (save-excursion (funcall func string bound noerror)))
+         (pos1 (save-excursion
+                 (isearch--search-skip-inhibited func string bound noerror)))
          pos2)
     (when (and
           ;; Avoid "obsolete" warnings for translation-table-for-input.
@@ -3570,7 +3585,8 @@ Optional third argument, if t, means if fail just return 
nil (no error).
         (when translated
           (save-match-data
             (save-excursion
-              (if (setq pos2 (funcall func translated bound noerror))
+              (if (setq pos2 (isearch--search-skip-inhibited
+                              func string bound noerror))
                   (setq match-data (match-data t)))))
           (when (and pos2
                      (or (not pos1)
@@ -3724,6 +3740,15 @@ Optional third argument, if t, means if fail just return 
nil (no error).
            (overlay-put ov 'isearch-invisible nil)))))))
 
 
+(defun isearch--invisible-p (val)
+  "Like `invisible-p', but also takes into account `inhibit-isearch' 
properties.
+If search is inhibited due to the latter, return `inhibit-isearch', and
+if it's due to the former, return `invisible'."
+  (or (and (invisible-p val)
+           'invisible)
+      (and (get-text-property (point) 'inhibit-isearch)
+           'inhibit-isearch)))
+
 (defun isearch-range-invisible (beg end)
   "Return t if all the text from BEG to END is invisible."
   (when (/= beg end)
@@ -3733,16 +3758,19 @@ Optional third argument, if t, means if fail just 
return nil (no error).
       (let (;; can-be-opened keeps track if we can open some overlays.
            (can-be-opened (eq search-invisible 'open))
            ;; the list of overlays that could be opened
-           (crt-overlays nil))
+           (crt-overlays nil)
+            ii-prop)
        (when (and can-be-opened isearch-hide-immediately)
          (isearch-close-unnecessary-overlays beg end))
        ;; If the following character is currently invisible,
        ;; skip all characters with that same `invisible' property value.
        ;; Do that over and over.
-       (while (and (< (point) end) (invisible-p (point)))
-         (if (invisible-p (get-text-property (point) 'invisible))
+       (while (and (< (point) end)
+                    (isearch--invisible-p (point)))
+         (if (setq ii-prop (isearch--invisible-p
+                             (get-text-property (point) 'invisible)))
              (progn
-               (goto-char (next-single-property-change (point) 'invisible
+               (goto-char (next-single-property-change (point) ii-prop
                                                        nil end))
                ;; if text is hidden by an `invisible' text property
                ;; we cannot open it at all.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]