Highlight regexp sub-expressions

* doc/emacs/search.texi (Search Customizations): Document it.

* lisp/isearch.el (search-highlight-submatches): New variable.
(isearch-group-1, isearch-group-2, isearch-group-3)
(isearch-group-4, isearch-group-5): New faces.
(isearch-highlight): Use them.
(isearch-dehighlight): Ditto (bug#6227).
This commit is contained in:
Juri Linkov 2020-09-20 15:46:19 +02:00 committed by Lars Ingebrigtsen
parent f8d8d28bc6
commit 09e109851b
3 changed files with 99 additions and 2 deletions

View file

@ -1977,6 +1977,16 @@ performs case folding and lax-whitespace matching.
using the @code{isearch} face. This highlighting can be disabled by
setting the variable @code{search-highlight} to @code{nil}.
@vindex search-highlight-submatches
When searching for regular expressions (with @kbd{C-u C-s}, for
instance), subexpressions receive special highlighting depending on
the @code{search-highlight-submatches} variable. If this variable is
zero, no special highlighting is done, but if this is larger than
zero, subexpressions will be matched with
@code{isearch-group-}@samp{X} faces. For instance, when searching for
@samp{foo-\([0-9]+\)}, the part matched by @samp{[0-9]+} will be
highlighted with the @code{isearch-group-1} face.
@cindex lazy highlighting customizations
@vindex isearch-lazy-highlight
@cindex @code{lazy-highlight} face

View file

@ -1034,6 +1034,12 @@ window after starting). This variable defaults to nil.
** Miscellaneous
+++
*** Interactive regular expression search now uses faces for sub-groups.
'C-u C-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]+". This is
controlled by the 'search-highlight-submatches' variable.
---
*** New user option 'reveal-auto-hide'.
If non-nil (the default), revealed text is automatically hidden when

View file

@ -269,6 +269,19 @@ are `word-search-regexp' \(`\\[isearch-toggle-word]'), `isearch-symbol-regexp'
"Non-nil means incremental search highlights the current match."
:type 'boolean)
(defcustom search-highlight-submatches 5
"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.
The faces used to do the highlights are named `isearch-group-1'
and so on, and if you increase this variable from the default,
you have to add more of these faces."
: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 +3667,57 @@ since they have special meaning in a regexp."
;; Highlighting
(defvar isearch-overlay nil)
(defvar isearch-submatches-overlays nil)
(defface isearch-group-1
'((((class color) (background light))
(:background "#ff00ff" :foreground "lightskyblue1"))
(((class color) (background dark))
(:background "palevioletred3" :foreground "brown4"))
(t (:inverse-video t)))
"Face for highlighting Isearch sub-group matches (first sub-group)."
:group 'isearch
:version "28.1")
(defface isearch-group-2
'((((class color) (background light))
(:background "#d000d0" :foreground "lightskyblue1"))
(((class color) (background dark))
(:background "#be698f" :foreground "black"))
(t (:inverse-video t)))
"Face for highlighting Isearch sub-group matches (second sub-group)."
:group 'isearch
:version "28.1")
(defface isearch-group-3
'((((class color) (background light))
(:background "#a000a0" :foreground "lightskyblue1"))
(((class color) (background dark))
(:background "#a06080" :foreground "brown4"))
(t (:inverse-video t)))
"Face for highlighting Isearch sub-group matches (third sub-group)."
:group 'isearch
:version "28.1")
(defface isearch-group-4
'((((class color) (background light))
(:background "#800080" :foreground "lightskyblue1"))
(((class color) (background dark))
(:background "#905070" :foreground "brown4"))
(t (:inverse-video t)))
"Face for highlighting Isearch sub-group matches (fourth sub-group)."
:group 'isearch
:version "28.1")
(defface isearch-group-5
'((((class color) (background light))
(:background "#600060" :foreground "lightskyblue1"))
(((class color) (background dark))
(:background "#804060" :foreground "black"))
(t (:inverse-video t)))
"Face for highlighting Isearch sub-group matches (fifth sub-group)."
:group 'isearch
:version "28.1")
(defun isearch-highlight (beg end)
(if search-highlight
@ -3664,11 +3728,28 @@ since they have special meaning in a regexp."
(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-group-%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/>