From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Tino Calancha Newsgroups: gmane.emacs.bugs Subject: bug#27268: 26.0.50; Undo comma replacements in query-replace Date: Wed, 07 Jun 2017 11:01:21 +0900 Message-ID: <87d1aga74e.fsf@calancha-pc> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1496800934 11496 195.159.176.226 (7 Jun 2017 02:02:14 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 7 Jun 2017 02:02:14 +0000 (UTC) Cc: juri linkov To: 27268@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Wed Jun 07 04:02:10 2017 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dIQIT-0002f9-EV for geb-bug-gnu-emacs@m.gmane.org; Wed, 07 Jun 2017 04:02:09 +0200 Original-Received: from localhost ([::1]:40883 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIQIX-0002L8-4M for geb-bug-gnu-emacs@m.gmane.org; Tue, 06 Jun 2017 22:02:13 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:54711) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIQIQ-0002L1-FL for bug-gnu-emacs@gnu.org; Tue, 06 Jun 2017 22:02:07 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIQIN-0002yZ-9n for bug-gnu-emacs@gnu.org; Tue, 06 Jun 2017 22:02:06 -0400 Original-Received: from debbugs.gnu.org ([208.118.235.43]:57415) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dIQIN-0002yR-5B for bug-gnu-emacs@gnu.org; Tue, 06 Jun 2017 22:02:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1dIQIM-00078U-Dz; Tue, 06 Jun 2017 22:02:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Tino Calancha Original-Sender: "Debbugs-submit" Resent-CC: juri@linkov.net, bug-gnu-emacs@gnu.org Resent-Date: Wed, 07 Jun 2017 02:02:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: report 27268 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch X-Debbugs-Original-To: bug-gnu-emacs@gnu.org X-Debbugs-Original-Xcc: juri linkov Original-Received: via spool by submit@debbugs.gnu.org id=B.149680090527401 (code B ref -1); Wed, 07 Jun 2017 02:02:02 +0000 Original-Received: (at submit) by debbugs.gnu.org; 7 Jun 2017 02:01:45 +0000 Original-Received: from localhost ([127.0.0.1]:60090 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dIQI4-00077t-KN for submit@debbugs.gnu.org; Tue, 06 Jun 2017 22:01:44 -0400 Original-Received: from eggs.gnu.org ([208.118.235.92]:35385) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1dIQI2-00077g-FX for submit@debbugs.gnu.org; Tue, 06 Jun 2017 22:01:42 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIQHv-0002e0-Ll for submit@debbugs.gnu.org; Tue, 06 Jun 2017 22:01:37 -0400 Original-Received: from lists.gnu.org ([2001:4830:134:3::11]:45480) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dIQHv-0002dv-IM for submit@debbugs.gnu.org; Tue, 06 Jun 2017 22:01:35 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:54573) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dIQHt-0002JX-O0 for bug-gnu-emacs@gnu.org; Tue, 06 Jun 2017 22:01:35 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dIQHq-0002cL-Jv for bug-gnu-emacs@gnu.org; Tue, 06 Jun 2017 22:01:33 -0400 Original-Received: from mail-pf0-x22d.google.com ([2607:f8b0:400e:c00::22d]:34925) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dIQHq-0002bi-A4 for bug-gnu-emacs@gnu.org; Tue, 06 Jun 2017 22:01:30 -0400 Original-Received: by mail-pf0-x22d.google.com with SMTP id l89so29681608pfi.2 for ; Tue, 06 Jun 2017 19:01:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:subject:date:message-id:mime-version; bh=/DZ/GV9SJl5dunab7Gu0Z7E6pfVACcIXHrEORB4XE+Q=; b=hk7CFcAcvu8mtqgvEFlkaZigv79Ffq1MAAaZaUTZnEx5D6TstcWKfeL9ByDk7lopYu F16VM9k69wJzncmuwTa3XeYhGTo1dOXwWx/tdjTOac9nMDhKO9bpfKrw8+rkTaf84HW6 RKo/8M1UofPy76Iy8ErrICkxUxdcRtcBweuybPMpQ/QMYKRq0vlcRaQ81QvbyDhppoG9 Ynd+1Cx2SHhY67k3czqHoo/XfpQo24cqePVKXw13ltSywTC1f9cZA4LkBvcgHrIvmnru 46jdpzou1G3Xf93fboE93Ttq65wOLjDR0rI3LpR6/Yxsn5vPeYOIsNlWwlbY3oInyrYf w00Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:mime-version; bh=/DZ/GV9SJl5dunab7Gu0Z7E6pfVACcIXHrEORB4XE+Q=; b=Q6tWeYHT5ihAZT8JPgVIihwuSb0EuOaPUWK0avFKB/2oXXhSW1b6vrp4P1VLGHm8R9 3V09Jt+VGA2DVDiY95N/NQ3SOJ4Njw8zW4xGZWNcQdaZ7yxHgiuyPvcA3EKBSjQniIZm RZQpY1aaCFG07dnLZNEOa7QUlO2GvOKbDoy17YpAxNwlKhx6BpQiN6a0yfYlHAkFBUQB OST+/Eiyq+E/On/NeLCdZ2W4z/T57LSpQNax2bZz80anDO+xPbOaxHB9mSLjiGLuyD3P 7niQWGNsdJ+ryp3oQyVPJDDOruZVZ+KoH4ZOTxY+sPBMOnSd2RbVr+MVjelaP6PNxAU2 tSYA== X-Gm-Message-State: AODbwcAdI07aDIWCVOJ9G3JZTOhABA6GXmqGL9A6LZbxJkMNG3yKVK+M dzqZBfudQDCHMC+c X-Received: by 10.99.104.136 with SMTP id d130mr5869721pgc.236.1496800887365; Tue, 06 Jun 2017 19:01:27 -0700 (PDT) Original-Received: from calancha-pc (222.139.137.133.dy.bbexcite.jp. [133.137.139.222]) by smtp.gmail.com with ESMTPSA id c67sm236010pfe.37.2017.06.06.19.01.25 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 06 Jun 2017 19:01:26 -0700 (PDT) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6.x X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 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.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.org gmane.emacs.bugs:133355 Archived-At: X-Debbugs-CC: Juri Linkov Severity: minor Tags: patch During a `query-replace' we can input a ?, character. >From `query-replace-help': Comma to replace but not move point immediately. Currently, those replacements are ignored. Following patch undo the comma replacements as well. --8<-----------------------------cut here---------------start------------->8--- >From 6ff176755eb3472d86c718ba67457ba88aa95fac Mon Sep 17 00:00:00 2001 From: Tino Calancha Date: Wed, 7 Jun 2017 10:59:49 +0900 Subject: [PATCH] query-replace: Undo replacements performed with 'comma During a `query-replace', character ?, replaces the character at point but not move point. A character ?u must undo such replacement (Bug#27268). * lisp/replace.el (replace--push-stack): New macro extracted from `perform-replace'. (perform-replace): Use it. --- lisp/replace.el | 70 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/lisp/replace.el b/lisp/replace.el index 64dfe7da22..ba8ea40162 100644 --- a/lisp/replace.el +++ b/lisp/replace.el @@ -2216,6 +2216,26 @@ replace-dehighlight ;; Close overlays opened by `isearch-range-invisible' in `perform-replace'. (isearch-clean-overlays)) +;; A macro because we push STACK, i.e. a local var in `perform-replace'. +(defmacro replace--push-stack (replaced search-str next-replace stack) + (declare (indent 0) (debug (form form form gv-place))) + `(push (list (point) ,replaced +;;; If the replacement has already happened, all we need is the +;;; current match start and end. We could get this with a trivial +;;; match like +;;; (save-excursion (goto-char (match-beginning 0)) +;;; (search-forward (match-string 0)) +;;; (match-data t)) +;;; if we really wanted to avoid manually constructing match data. +;;; Adding current-buffer is necessary so that match-data calls can +;;; return markers which are appropriate for editing. + (if ,replaced + (list + (match-beginning 0) (match-end 0) (current-buffer)) + (match-data t)) + ,search-str ,next-replace) + ,stack)) + (defun perform-replace (from-string replacements query-flag regexp-flag delimited-flag &optional repeat-count map start end backward region-noncontiguous-p) @@ -2259,6 +2279,8 @@ perform-replace (next-replacement-replaced nil) ; replacement string ; (substituted regexp) (last-was-undo) + (last-was-act-and-show) + (update-stack t) (replace-count 0) (skip-read-only-count 0) (skip-filtered-count 0) @@ -2542,7 +2564,7 @@ perform-replace next-replacement) (while (and (< stack-idx stack-len) stack - (null replaced)) + (or (null replaced) last-was-act-and-show)) (let* ((elt (nth stack-idx stack))) (setq stack-idx (1+ stack-idx) @@ -2552,10 +2574,11 @@ perform-replace search-string (nth (if replaced 4 3) elt) next-replacement (nth (if replaced 3 4) elt) search-string-replaced search-string - next-replacement-replaced next-replacement) + next-replacement-replaced next-replacement + last-was-act-and-show nil) (when (and (= stack-idx stack-len) - (null replaced) + (and (null replaced) (not last-was-act-and-show)) (zerop num-replacements)) (message "Nothing to undo") (ding 'no-terminate) @@ -2595,7 +2618,7 @@ perform-replace "replacements")) (ding 'no-terminate) (sit-for 1))) - (setq replaced nil last-was-undo t))) + (setq replaced nil last-was-undo t last-was-act-and-show nil))) ((eq def 'act) (or replaced (setq noedit @@ -2603,7 +2626,7 @@ perform-replace next-replacement nocasify literal noedit real-match-data backward) replace-count (1+ replace-count))) - (setq done t replaced t)) + (setq done t replaced t update-stack (not last-was-act-and-show))) ((eq def 'act-and-exit) (or replaced (setq noedit @@ -2614,7 +2637,7 @@ perform-replace (setq keep-going nil) (setq done t replaced t)) ((eq def 'act-and-show) - (if (not replaced) + (unless replaced (setq noedit (replace-match-maybe-edit next-replacement nocasify literal @@ -2622,7 +2645,11 @@ perform-replace replace-count (1+ replace-count) real-match-data (replace-match-data t real-match-data) - replaced t))) + replaced t last-was-act-and-show t) + (replace--push-stack + replaced + search-string-replaced + next-replacement-replaced stack))) ((or (eq def 'automatic) (eq def 'automatic-all)) (or replaced (setq noedit @@ -2633,7 +2660,7 @@ perform-replace (setq done t query-flag nil replaced t) (if (eq def 'automatic-all) (setq multi-buffer t))) ((eq def 'skip) - (setq done t)) + (setq done t update-stack (not last-was-act-and-show))) ((eq def 'recenter) ;; `this-command' has the value `query-replace', ;; so we need to bind it to `recenter-top-bottom' @@ -2703,27 +2730,14 @@ perform-replace ;; Record previous position for ^ when we move on. ;; Change markers to numbers in the match data ;; since lots of markers slow down editing. - (push (list (point) replaced -;;; If the replacement has already happened, all we need is the -;;; current match start and end. We could get this with a trivial -;;; match like -;;; (save-excursion (goto-char (match-beginning 0)) -;;; (search-forward (match-string 0)) -;;; (match-data t)) -;;; if we really wanted to avoid manually constructing match data. -;;; Adding current-buffer is necessary so that match-data calls can -;;; return markers which are appropriate for editing. - (if replaced - (list - (match-beginning 0) - (match-end 0) - (current-buffer)) - (match-data t)) - search-string-replaced - next-replacement-replaced) - stack) + (when update-stack + (replace--push-stack + replaced + search-string-replaced + next-replacement-replaced stack)) (setq next-replacement-replaced nil - search-string-replaced nil)))))) + search-string-replaced nil + last-was-act-and-show nil)))))) (replace-dehighlight)) (or unread-command-events (message "Replaced %d occurrence%s%s" -- 2.11.0 >From 4a9297fde76b0a6bebba994f99b9e3bcd9af67dc Mon Sep 17 00:00:00 2001 From: Tino Calancha Date: Wed, 7 Jun 2017 11:00:02 +0900 Subject: [PATCH] * test/lisp/replace-tests.el (query-replace--undo): Add test. --- test/lisp/replace-tests.el | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/test/lisp/replace-tests.el b/test/lisp/replace-tests.el index adef5a3f3d..6c4cbc45b8 100644 --- a/test/lisp/replace-tests.el +++ b/test/lisp/replace-tests.el @@ -358,4 +358,25 @@ replace-occur-test-create (dotimes (i (length replace-occur-tests)) (replace-occur-test-create i)) +(defun replace-tests--query-replace-undo (&optional comma) + (with-temp-buffer + (insert "111") + (goto-char 1) + (let ((count 0)) + (cl-letf (((symbol-function 'read-event) + (lambda (&rest args) + (cl-incf count) + (let ((val (pcase count + ('2 (if comma ?, ?\s)) + ('3 ?u) + ('4 ?q) + (_ ?\s)))) + val)))) + (perform-replace "1" "2" t nil nil))) + (buffer-string))) + +(ert-deftest query-replace--undo () + (should (string= "211" (replace-tests--query-replace-undo))) + (should (string= "211" (replace-tests--query-replace-undo 'comma)))) + ;;; replace-tests.el ends here -- 2.11.0 --8<-----------------------------cut here---------------end--------------->8--- In GNU Emacs 26.0.50 (build 1, x86_64-pc-linux-gnu, GTK+ Version 3.22.11) of 2017-06-07 Repository revision: 43885eac09d7c69ecbac08c033d33381e21f48a2