From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Juri Linkov Newsgroups: gmane.emacs.bugs Subject: bug#43702: Emacs master: Incorrect highlighting in regexp isearch. Date: Mon, 12 Oct 2020 22:59:53 +0300 Organization: LINKOV.NET Message-ID: <874kmzz03q.fsf@mail.linkov.net> References: <20200929121317.GA27007@ACM> <83wo0ck5ig.fsf@gnu.org> <20200929153355.GB27007@ACM> <87y2ks819k.fsf@gnus.org> <87y2krdqsk.fsf@mail.linkov.net> <87y2kp93dn.fsf@mail.linkov.net> <87mu0z3zxf.fsf@mail.linkov.net> <871riav4os.fsf@mail.linkov.net> <21c5738b-e9f2-465f-9ca3-8947a5b9191d@default> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="27031"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (x86_64-pc-linux-gnu) Cc: Alan Mackenzie , Lars Ingebrigtsen , 43702@debbugs.gnu.org To: Drew Adams Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Oct 12 22:02:14 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kS41N-0006wk-PC for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 12 Oct 2020 22:02:13 +0200 Original-Received: from localhost ([::1]:49206 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kS41M-0007ao-HU for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 12 Oct 2020 16:02:12 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:58332) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kS41C-0007ag-IO for bug-gnu-emacs@gnu.org; Mon, 12 Oct 2020 16:02:02 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:60716) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kS41B-0007G6-W8 for bug-gnu-emacs@gnu.org; Mon, 12 Oct 2020 16:02:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kS41B-0008NJ-TV for bug-gnu-emacs@gnu.org; Mon, 12 Oct 2020 16:02:01 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Juri Linkov Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 12 Oct 2020 20:02:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 43702 X-GNU-PR-Package: emacs Original-Received: via spool by 43702-submit@debbugs.gnu.org id=B43702.160253287432135 (code B ref 43702); Mon, 12 Oct 2020 20:02:01 +0000 Original-Received: (at 43702) by debbugs.gnu.org; 12 Oct 2020 20:01:14 +0000 Original-Received: from localhost ([127.0.0.1]:44029 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kS40P-0008MF-RW for submit@debbugs.gnu.org; Mon, 12 Oct 2020 16:01:14 -0400 Original-Received: from relay1-d.mail.gandi.net ([217.70.183.193]:52073) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kS40M-0008M0-KE for 43702@debbugs.gnu.org; Mon, 12 Oct 2020 16:01:13 -0400 X-Originating-IP: 91.129.102.160 Original-Received: from mail.gandi.net (m91-129-102-160.cust.tele2.ee [91.129.102.160]) (Authenticated sender: juri@linkov.net) by relay1-d.mail.gandi.net (Postfix) with ESMTPSA id 3FFC3240008; Mon, 12 Oct 2020 20:01:01 +0000 (UTC) In-Reply-To: <21c5738b-e9f2-465f-9ca3-8947a5b9191d@default> (Drew Adams's message of "Wed, 7 Oct 2020 08:42:10 -0700 (PDT)") X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:190360 Archived-At: --=-=-= Content-Type: text/plain >> How highlighting the replacement submatches will help the user to decide >> whether to replace the current match or not? > > Whether to replace a given match is not the only thing > a user can do - not the only thing to decide/consider. > > Highlighting groups helps you see _how_ a regexp matches. > > And you can always change a regexp and search/replace > again, if it's either not matching something you want > to match or matching too many things you don't want to > match. > > It's helpful in pretty much any context where regexps > are matched against text, IMO. I think you are right. So here is a patch that implements this: --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=query-replace-highlight-submatches.patch diff --git a/lisp/replace.el b/lisp/replace.el index e363924501..f9ffa36f54 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -126,6 +126,18 @@ query-replace-highlight :type 'boolean :group 'matching) +(defcustom query-replace-highlight-submatches t + "Whether to highlight regexp subexpressions during query replacement. +The faces used to do the highlights are named `isearch-group-1', +`isearch-group-2', etc. (By default, only these 2 are defined.) +When there are more matches than faces, then faces are reused from the +beginning, in a cyclical manner, so the `isearch-group-1' face is +isreused for the third match. If you want to use more distinctive colors, +you can define more of these faces using the same numbering scheme." + :type 'boolean + :group 'matching + :version "28.1") + (defcustom query-replace-lazy-highlight t "Controls the lazy-highlighting during query replacements. When non-nil, all text in the buffer matching the current match @@ -2403,16 +2427,36 @@ replace-search (funcall search-function search-string limit t))) (defvar replace-overlay nil) +(defvar replace-submatches-overlays nil) (defun replace-highlight (match-beg match-end range-beg range-end search-string regexp-flag delimited-flag - case-fold &optional backward) + case-fold &optional backward match-data) (if query-replace-highlight (if replace-overlay (move-overlay replace-overlay match-beg match-end (current-buffer)) (setq replace-overlay (make-overlay match-beg match-end)) (overlay-put replace-overlay 'priority 1001) ;higher than lazy overlays (overlay-put replace-overlay 'face 'query-replace))) + + (when (and query-replace-highlight-submatches + regexp-flag) + (mapc 'delete-overlay replace-submatches-overlays) + (setq replace-submatches-overlays nil) + (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 replace-submatches-overlays)))) + (if query-replace-lazy-highlight (let ((isearch-string search-string) (isearch-regexp regexp-flag) @@ -2433,6 +2477,9 @@ replace-highlight (defun replace-dehighlight () (when replace-overlay (delete-overlay replace-overlay)) + (when query-replace-highlight-submatches + (mapc 'delete-overlay replace-submatches-overlays) + (setq replace-submatches-overlays nil)) (when query-replace-lazy-highlight (lazy-highlight-cleanup lazy-highlight-cleanup) (setq isearch-lazy-highlight-last-string nil)) @@ -2694,7 +2741,7 @@ perform-replace (replace-highlight (nth 0 real-match-data) (nth 1 real-match-data) start end search-string - regexp-flag delimited-flag case-fold-search backward)) + regexp-flag delimited-flag case-fold-search backward real-match-data)) (setq noedit (replace-match-maybe-edit next-replacement nocasify literal @@ -2719,7 +2766,7 @@ perform-replace (replace-highlight (match-beginning 0) (match-end 0) start end search-string - regexp-flag delimited-flag case-fold-search backward) + regexp-flag delimited-flag case-fold-search backward real-match-data) ;; Obtain the matched groups: needed only when ;; regexp-flag non nil. (when (and last-was-undo regexp-flag) --=-=-=--