Subject: Interactive highlighting of sub-regexp

From: Grégory Mounié <[email-masked]>
Date: Fri, 3 Aug 2018 16:24:39 +0200

Dear maintainers,

  I propose to add to Interactive Highlighting (hi-lock.el) few lines in 
order to highlight only the first sub-regexps if it exists.

  The use case that interested me was to highlight the column of a CSV file.

  EG.:

  M-x highlight-regexp  then ^\(?:[^,]*,\)\{5\}\([^,]*\),.*$ for 
highlighting the 6th column of a clean CSV file

  I try to keep it as simple as possible as the function is in the 
documentation.

  The modified function has two paths: font-lock if enabled or directly 
overlay

  The sub-regexp detection is a bit rough for font-lock-mode case. I do 
not know how to do it perfectly without implementing a regexp engine or
using a much more complex detection regexp.
  For overlay-case, the code seems quite straightforward.

  Have a nice day,
  Grégory Mounié

>From 1764f0aa16727f510ecfe113aab4b3e689aa0978 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gr=C3=A9gory=20Mouni=C3=A9?= <[email-masked]>
Date: Fri, 3 Aug 2018 15:53:34 +0200
Subject: [PATCH] Interactive Hightlighting: only the first subexp if it exists

When interactively highlighting regular expression (highlight-regexp),
if the regular expression contains a subexpression, only the
first sub-expression is highlighted.

* lisp/hi-lock.el (hi-lock-set-pattern):
* doc/emacs/display.texi:
* etc/NEWS:
 highlight only the first subexp if the regexp contains subexps

Copyright-paperwork-exempt: yes
---
 doc/emacs/display.texi |  2 ++
 etc/NEWS               |  6 ++++++
 lisp/hi-lock.el        | 12 +++++++++---
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/doc/emacs/display.texi b/doc/emacs/display.texi
index 2f5ce80d60..ef3d8aab3e 100644
--- a/doc/emacs/display.texi
+++ b/doc/emacs/display.texi
@@ -986,6 +986,8 @@ Highlight Interactively
 You can use this command multiple times, specifying various regular
 expressions to highlight in different ways.
 
+Only the first sub-@var{regexp} is highlighted, if relevant.
+
 @item M-s h u @var{regexp} @key{RET}
 @itemx C-x w r @var{regexp} @key{RET}
 @kindex M-s h u
diff --git a/etc/NEWS b/etc/NEWS
index 6ccf6fc089..44a6f468a0 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -651,6 +651,12 @@ to signal the main thread, e.g., when they encounter an error.
 +++
 *** 'thread-join' returns the result of the finished thread now.
 
+** Interactive Highlighting
+
+*** The function 'highlight-regexp' highlights first subexp.
+If the regular expression includes at least a subexp, the
+function highlights only the first subexp.
+
 
 * New Modes and Packages in Emacs 27.1
 
diff --git a/lisp/hi-lock.el b/lisp/hi-lock.el
index 13ebffb1af..62cba0f4d1 100644
--- a/lisp/hi-lock.el
+++ b/lisp/hi-lock.el
@@ -687,10 +687,12 @@ hi-lock-read-face-name
     (intern face)))
 
 (defun hi-lock-set-pattern (regexp face)
-  "Highlight REGEXP with face FACE."
+  "Highlight REGEXP (or first SUBEXP) with face FACE."
   ;; Hashcons the regexp, so it can be passed to remove-overlays later.
   (setq regexp (hi-lock--hashcons regexp))
-  (let ((pattern (list regexp (list 0 (list 'quote face) 'prepend)))
+  (let ((pattern (list regexp
+                       (list (if (string-match-p "\\\\(.*\\\\)" regexp) 1 0)
+                             (list 'quote face) 'prepend)))
         (no-matches t))
     ;; Refuse to highlight a text that is already highlighted.
     (if (assoc regexp hi-lock-interactive-patterns)
@@ -712,7 +714,11 @@ hi-lock-set-pattern
             (goto-char search-start)
             (while (re-search-forward regexp search-end t)
               (when no-matches (setq no-matches nil))
-              (let ((overlay (make-overlay (match-beginning 0) (match-end 0))))
+              (let ((overlay (make-overlay
+                              (or (match-beginning 1)
+                                  (match-beginning 0))
+                              (or (match-end 1)
+                                  (match-end 0)))))
                 (overlay-put overlay 'hi-lock-overlay t)
                 (overlay-put overlay 'hi-lock-overlay-regexp regexp)
                 (overlay-put overlay 'face face))
-- 
2.18.0