Subject: Re: bug#6227: Color isearch regexp submatches differently

From: Lars Ingebrigtsen <[email-masked]>
Date: Sat, 19 Sep 2020 23:29:48 +0200

Juri Linkov <[email-masked]> writes:

>>> I agree, your approach is probably better. But check for more
>>> submatches. Maybe upto the value of some variable, say
>>> isearch-max-submatch-num.
>>
>> Good idea.
>
> Maybe something like this:

The ten year old patch no longer applied to Emacs 28, so I've respun it.

I think the results are really nice.  I guess we should add a few more
faces before applying?

Anybody else got any comments on this?

diff --git a/lisp/isearch.el b/lisp/isearch.el
index 7fb1d8a3ca..56eb443d31 100644
--- a/lisp/isearch.el
+++ b/lisp/isearch.el
@@ -269,6 +269,14 @@ search-highlight
   "Non-nil means incremental search highlights the current match."
   :type 'boolean)
 
+(defcustom search-highlight-submatches 2
+  "Highlight regexp subexpressions of the current regexp match.
+An integer means highlight regexp subexpressions up to the
+specified maximal number.
+When 0, do not highlight regexp subexpressions."
+  :type 'integer
+  :version "28.1")
+
 (defface isearch
   '((((class color) (min-colors 88) (background light))
      ;; The background must not be too dark, for that means
@@ -3654,6 +3662,21 @@ isearch-unread
 ;; Highlighting
 
 (defvar isearch-overlay nil)
+(defvar isearch-submatches-overlays nil)
+
+(defface isearch-1
+  '((((class color) (min-colors 88) (background light))
+     :background "magenta2" :foreground "lightskyblue1")
+    (((class color) (min-colors 88) (background dark))
+     :background "palevioletred3" :foreground "brown4"))
+  "Used for displaying the first matching subexpression.")
+
+(defface isearch-2
+  '((((class color) (min-colors 88) (background light))
+     :background "magenta1" :foreground "lightskyblue1")
+    (((class color) (min-colors 88) (background dark))
+     :background "palevioletred4" :foreground "brown4"))
+  "Used for displaying the second matching subexpression.")
 
 (defun isearch-highlight (beg end)
   (if search-highlight
@@ -3664,11 +3687,28 @@ isearch-highlight
 	(setq isearch-overlay (make-overlay beg end))
 	;; 1001 is higher than lazy's 1000 and ediff's 100+
 	(overlay-put isearch-overlay 'priority 1001)
-	(overlay-put isearch-overlay 'face isearch-face))))
+	(overlay-put isearch-overlay 'face isearch-face)))
+  (when (and (integerp search-highlight-submatches)
+	     (> search-highlight-submatches 0)
+	     isearch-regexp)
+    (mapc 'delete-overlay isearch-submatches-overlays)
+    (setq isearch-submatches-overlays nil)
+    (let ((i 0) ov)
+      (while (<= i search-highlight-submatches)
+	(when (match-beginning i)
+	  (setq ov (make-overlay (match-beginning i) (match-end i)))
+	  (overlay-put ov 'face (intern-soft (format "isearch-%d" i)))
+	  (overlay-put ov 'priority 1002)
+	  (push ov isearch-submatches-overlays))
+	(setq i (1+ i))))))
 
 (defun isearch-dehighlight ()
   (when isearch-overlay
-    (delete-overlay isearch-overlay)))
+    (delete-overlay isearch-overlay))
+  (when search-highlight-submatches
+    (mapc 'delete-overlay isearch-submatches-overlays)
+    (setq isearch-submatches-overlays nil)))
+
 
 ;; isearch-lazy-highlight feature
 ;; by Bob Glickstein <http://www.zanshin.com/~bobg/>

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no