Package: emacs;
Reported by: Tino Calancha <tino.calancha <at> gmail.com>
Date: Wed, 7 Jun 2017 02:02:02 UTC
Severity: minor
Tags: patch
Found in version 26.0.50
Done: Tino Calancha <tino.calancha <at> gmail.com>
Bug is archived. No further changes may be made.
To add a comment to this bug, you must first unarchive it, by sending
a message to control AT debbugs.gnu.org, with unarchive 27268 in the body.
You can then email your comments to 27268 AT debbugs.gnu.org in the normal way.
Toggle the display of automated, internal messages from the tracker.
View this report as an mbox folder, status mbox, maintainer mbox
juri <at> linkov.net, bug-gnu-emacs <at> gnu.org
:bug#27268
; Package emacs
.
(Wed, 07 Jun 2017 02:02:02 GMT) Full text and rfc822 format available.Tino Calancha <tino.calancha <at> gmail.com>
:juri <at> linkov.net, bug-gnu-emacs <at> gnu.org
.
(Wed, 07 Jun 2017 02:02:02 GMT) Full text and rfc822 format available.Message #5 received at submit <at> debbugs.gnu.org (full text, mbox):
From: Tino Calancha <tino.calancha <at> gmail.com> To: bug-gnu-emacs <at> gnu.org Subject: 26.0.50; Undo comma replacements in query-replace Date: Wed, 07 Jun 2017 11:01:21 +0900
X-Debbugs-CC: Juri Linkov <juri <at> linkov.net> 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 <tino.calancha <at> gmail.com> 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 <tino.calancha <at> gmail.com> 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
Tino Calancha <tino.calancha <at> gmail.com>
:Tino Calancha <tino.calancha <at> gmail.com>
:Message #10 received at 27268-done <at> debbugs.gnu.org (full text, mbox):
From: Tino Calancha <tino.calancha <at> gmail.com> To: 27268-done <at> debbugs.gnu.org Subject: Re: bug#27268: 26.0.50; Undo comma replacements in query-replace Date: Tue, 08 Aug 2017 10:31:56 +0900
Tino Calancha <tino.calancha <at> gmail.com> writes: > 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. Fixed in master branch as commit 919ac3ae1635bf2b99eb1f3efc7476826359e92a (query-replace: Undo replacements performed with 'comma)
Debbugs Internal Request <help-debbugs <at> gnu.org>
to internal_control <at> debbugs.gnu.org
.
(Tue, 05 Sep 2017 11:24:04 GMT) Full text and rfc822 format available.
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.