emacs-diffs
[Top][All Lists]
Advanced

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

master 46aa145: Add match-data to isearch state and repeat faces to high


From: Juri Linkov
Subject: master 46aa145: Add match-data to isearch state and repeat faces to highlight group matches
Date: Tue, 6 Oct 2020 16:14:38 -0400 (EDT)

branch: master
commit 46aa145d3906d21b4eb0e088c6325967c1579f3d
Author: Juri Linkov <juri@linkov.net>
Commit: Juri Linkov <juri@linkov.net>

    Add match-data to isearch state and repeat faces to highlight group matches
    
    * lisp/isearch.el (isearch-match-data): New variable.
    (isearch-mode): Set isearch-match-data to nil.
    (isearch-update): Call isearch-highlight with isearch-match-data.
    (isearch--state): Add isearch-match-data.
    (isearch--set-state): Restore isearch-match-data.
    (with-isearch-suspended): Preserve isearch-match-data.
    (isearch-search): Set isearch-match-data to integers.
    (isearch-group-1): Rename from isearch-group-odd and adjust colors.
    (isearch-group-2): Rename from isearch-group-even and adjust colors.
    (isearch-highlight): Add optional arg 'match-data'.
    Rewrite search-highlight-submatches part to recycle faces.
    
    * doc/emacs/search.texi (Search Customizations): Amend the
    documentation for isearch-group faces.
    
    (bug#6227, bug#43702)
---
 doc/emacs/search.texi | 10 +++++----
 etc/NEWS              |  4 ++--
 lisp/isearch.el       | 62 ++++++++++++++++++++++++++++++++-------------------
 3 files changed, 47 insertions(+), 29 deletions(-)

diff --git a/doc/emacs/search.texi b/doc/emacs/search.texi
index d982a9e..d25e356 100644
--- a/doc/emacs/search.texi
+++ b/doc/emacs/search.texi
@@ -1984,11 +1984,13 @@ the @code{search-highlight-submatches} variable.  If 
this variable's
 value is @code{nil}, no special highlighting is done, but if the value
 is non-@code{nil}, text that matches @samp{\( @dots{} \)} constructs
 (a.k.a.@: ``subexpressions'') in the regular expression will be
-highlighted with distinct faces, named @code{isearch-group-odd}
-for the odd group matches, and @code{isearch-group-even}
-for the even group matches.  For instance, when searching for
+highlighted with distinct faces, named @code{isearch-group-1}
+and @code{isearch-group-2}.  For instance, when searching for
 @samp{foo-\([0-9]+\)}, the part matched by @samp{[0-9]+} will be
-highlighted with the @code{isearch-group-odd} face.
+highlighted with the @code{isearch-group-1} face.  When there are
+more matches than faces, then faces are recycled from beginning,
+so the @code{isearch-group-1} face is used for the third match again.
+You can define more faces using the same numbering scheme.
 
 @cindex lazy highlighting customizations
 @vindex isearch-lazy-highlight
diff --git a/etc/NEWS b/etc/NEWS
index 1a5634f..9d7b6e3 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1106,9 +1106,9 @@ keystrokes.
 
 +++
 *** Interactive regular expression search now uses faces for sub-groups.
-E.g., 'C-M-s foo-\([0-9]+\)' will now use the 'isearch-group-odd' face
+E.g., 'C-M-s foo-\([0-9]+\)' will now use the 'isearch-group-1' face
 on the part of the regexp that matches the sub-expression "[0-9]+".
-The even group matches are highlighted with the 'isearch-group-even' face.
+By default, there are two group faces, but you can define more.
 This is controlled by the 'search-highlight-submatches' user option.
 This feature is available only on terminals that have enough colors to
 distinguish between sub-expression highlighting.
diff --git a/lisp/isearch.el b/lisp/isearch.el
index 781a8c5..08d4be3 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -271,8 +271,11 @@ are `word-search-regexp' \(`\\[isearch-toggle-word]'), 
`isearch-symbol-regexp'
 
 (defcustom search-highlight-submatches t
   "Whether to highlight regexp subexpressions of the current regexp match.
-The faces used to do the highlights are named `isearch-group-odd' and
-`isearch-group-even'."
+The faces used to do the highlights are named `isearch-group-1',
+`isearch-group-2'.  When there are more matches than faces, then faces are
+recycled from beginning, so the `isearch-group-1' face is used for the
+third match again.  If you want to use more distinctive colors, you have to
+define more of these faces using the same numbering scheme."
   :type 'boolean
   :version "28.1")
 
@@ -887,7 +890,7 @@ variable by the command `isearch-toggle-lax-whitespace'.")
   "Stack of search status elements.
 Each element is an `isearch--state' struct where the slots are
  [STRING MESSAGE POINT SUCCESS FORWARD OTHER-END WORD/REGEXP-FUNCTION
-  ERROR WRAPPED BARRIER CASE-FOLD-SEARCH POP-FUN]")
+  ERROR WRAPPED BARRIER CASE-FOLD-SEARCH POP-FUN MATCH-DATA]")
 
 (defvar isearch-string "")  ; The current search string.
 (defvar isearch-message "") ; text-char-description version of isearch-string
@@ -903,6 +906,7 @@ Each element is an `isearch--state' struct where the slots 
are
   "Recorded minimum/maximal point for the current search.")
 (defvar isearch-just-started nil)
 (defvar isearch-start-hscroll 0)       ; hscroll when starting the search.
+(defvar isearch-match-data nil)         ; match-data of regexp-based search
 
 ;; case-fold-search while searching.
 ;;   either nil, t, or 'yes.  'yes means the same as t except that mixed
@@ -1221,6 +1225,7 @@ used to set the value of `isearch-regexp-function'."
        isearch-small-window nil
        isearch-just-started t
        isearch-start-hscroll (window-hscroll)
+       isearch-match-data nil
 
        isearch-opoint (point)
        search-ring-yank-pointer nil
@@ -1349,8 +1354,8 @@ The last thing is to trigger a new round of lazy 
highlighting."
                (set-window-hscroll (selected-window) current-scroll))))
        (if isearch-other-end
             (if (< isearch-other-end (point)) ; isearch-forward?
-                (isearch-highlight isearch-other-end (point))
-              (isearch-highlight (point) isearch-other-end))
+                (isearch-highlight isearch-other-end (point) 
isearch-match-data)
+              (isearch-highlight (point) isearch-other-end isearch-match-data))
           (isearch-dehighlight))))
   (setq ;; quit-flag nil  not for isearch-mode
    isearch-adjusted nil
@@ -1508,7 +1513,8 @@ REGEXP if non-nil says use the regexp search ring."
                  (barrier isearch-barrier)
                  (case-fold-search isearch-case-fold-search)
                  (pop-fun (if isearch-push-state-function
-                              (funcall isearch-push-state-function))))))
+                              (funcall isearch-push-state-function)))
+                 (match-data isearch-match-data))))
   (string nil :read-only t)
   (message nil :read-only t)
   (point nil :read-only t)
@@ -1520,7 +1526,8 @@ REGEXP if non-nil says use the regexp search ring."
   (wrapped nil :read-only t)
   (barrier nil :read-only t)
   (case-fold-search nil :read-only t)
-  (pop-fun nil :read-only t))
+  (pop-fun nil :read-only t)
+  (match-data nil :read-only t))
 
 (defun isearch--set-state (cmd)
   (setq isearch-string (isearch--state-string cmd)
@@ -1532,7 +1539,8 @@ REGEXP if non-nil says use the regexp search ring."
        isearch-error (isearch--state-error cmd)
        isearch-wrapped (isearch--state-wrapped cmd)
        isearch-barrier (isearch--state-barrier cmd)
-       isearch-case-fold-search (isearch--state-case-fold-search cmd))
+       isearch-case-fold-search (isearch--state-case-fold-search cmd)
+       isearch-match-data (isearch--state-match-data cmd))
   (if (functionp (isearch--state-pop-fun cmd))
       (funcall (isearch--state-pop-fun cmd) cmd))
   (goto-char (isearch--state-point cmd)))
@@ -1624,6 +1632,7 @@ You can update the global isearch variables by setting 
new values to
              (isearch-adjusted isearch-adjusted)
              (isearch-yank-flag isearch-yank-flag)
              (isearch-error isearch-error)
+             (isearch-match-data isearch-match-data)
 
              (multi-isearch-file-list-new multi-isearch-file-list)
              (multi-isearch-buffer-list-new multi-isearch-buffer-list)
@@ -3432,6 +3441,7 @@ Optional third argument, if t, means if fail just return 
nil (no error).
                           (match-beginning 0) (match-end 0)))
              (setq retry nil)))
        (setq isearch-just-started nil)
+       (setq isearch-match-data (match-data t))
        (if isearch-success
            (setq isearch-other-end
                  (if isearch-forward (match-beginning 0) (match-end 0)))))
@@ -3663,27 +3673,27 @@ since they have special meaning in a regexp."
 (defvar isearch-overlay nil)
 (defvar isearch-submatches-overlays nil)
 
-(defface isearch-group-odd
+(defface isearch-group-1
   '((((class color) (min-colors 88) (background light))
-     (:background "#ff00ff" :foreground "lightskyblue1"))
+     (:background "#f000f0" :foreground "lightskyblue1"))
     (((class color) (min-colors 88) (background dark))
-     (:background "palevioletred3" :foreground "brown4"))
+     (:background "palevioletred1" :foreground "brown4"))
     (t (:inherit isearch)))
   "Face for highlighting Isearch the odd group matches."
   :group 'isearch
   :version "28.1")
 
-(defface isearch-group-even
+(defface isearch-group-2
   '((((class color) (min-colors 88) (background light))
-     (:background "#800080" :foreground "lightskyblue1"))
+     (:background "#a000a0" :foreground "lightskyblue1"))
     (((class color) (min-colors 88) (background dark))
-     (:background "#905070" :foreground "brown4"))
+     (:background "palevioletred3" :foreground "brown4"))
     (t (:inherit isearch)))
   "Face for highlighting Isearch the even group matches."
   :group 'isearch
   :version "28.1")
 
-(defun isearch-highlight (beg end)
+(defun isearch-highlight (beg end &optional match-data)
   (if search-highlight
       (if isearch-overlay
          ;; Overlay already exists, just move it.
@@ -3693,18 +3703,24 @@ since they have special meaning in a regexp."
        ;; 1001 is higher than lazy's 1000 and ediff's 100+
        (overlay-put isearch-overlay 'priority 1001)
        (overlay-put isearch-overlay 'face isearch-face)))
+
   (when (and search-highlight-submatches
             isearch-regexp)
     (mapc 'delete-overlay isearch-submatches-overlays)
     (setq isearch-submatches-overlays nil)
-    (dotimes (i (/ (length (match-data)) 2))
-      (unless (zerop i)
-       (let ((ov (make-overlay (match-beginning i) (match-end i))))
-         (overlay-put ov 'face (if (zerop (mod i 2))
-                                   'isearch-group-even
-                                 'isearch-group-odd))
-         (overlay-put ov 'priority 1002)
-         (push ov isearch-submatches-overlays))))))
+    (let ((submatch-data (cddr (butlast match-data)))
+          (group 0)
+          ov face)
+      (while submatch-data
+        (setq group (1+ group))
+        (setq ov (make-overlay (pop submatch-data) (pop submatch-data))
+              face (intern-soft (format "isearch-group-%d" group)))
+        ;; Recycle faces from beginning.
+        (unless (facep face)
+          (setq group 1 face 'isearch-group-1))
+        (overlay-put ov 'face face)
+        (overlay-put ov 'priority 1002)
+        (push ov isearch-submatches-overlays)))))
 
 (defun isearch-dehighlight ()
   (when isearch-overlay



reply via email to

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