(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")
"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
"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
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
(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
(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)
(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)
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)))
(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)
(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)))))
(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.
;; 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