--- Begin Message ---
Subject: |
25.0.50; query-replace-regexp becomes unusable when using lisp expressions for replacement |
Date: |
Mon, 15 Dec 2014 01:01:28 -0800 |
Hi.
I'm using a bleeding-edge emacs build, compiled from latest source as of
Dec 14. There's a regression in query-replace-regexp where under some
conditions it becomes unable to parse its history, and becomes unusable.
Here's a recipe. Deviating from the exact steps can make the failure not
occur, but I do see this in everyday use, so this isn't exactly a corner
case.
1. Create a file called /tmp/dat. I don't think the contents are super
important. I have
0001
0002
0003
0004
0005
0006
0007
0008
2. emacs -Q /tmp/dat
3. C-M-%
^.
<return>
\,(concat \#&)
<return>
Here we try to do a replacement, but there's an error: (concat ...)
expects a string, but \#& is a number, and emacs complains. This is
fine.
4. C-M-%
<up>
<end>
<left>
<left>
<backspace>
<return>
SPC
We run another replacement. We pull the previous one from the
history, and manually remove the # to fix the complaint. \& is a
string, as desired. We then replace the first match by presing SPC
5. M-%
Error!
After step 5, trying to M-% or C-M-% always fails with
mapconcat: Wrong type argument: number-or-marker-p, replace-eval-replacement
This is irreparable without dipping into lisp. Resetting the history
fixes it for the session: (setq query-replace-defaults nil)
When broken, the value of query-replace-defaults is
(("" replace-eval-replacement replace-quote (concat (match-string 0))) ("^." .
"\\,(concat \\#&)"))
and the value of query-replace-history is
((replace-eval-replacement replace-quote (concat (match-string 0))) ""
"\\,(concat \\#&)" "^.")
The backtrace looks like this:
Debugger entered--Lisp error: (wrong-type-argument number-or-marker-p
replace-eval-replacement)
isearch-text-char-description(replace-eval-replacement)
mapconcat(isearch-text-char-description (replace-eval-replacement
replace-quote (concat (match-string 0))) "")
query-replace-descr((replace-eval-replacement replace-quote (concat
(match-string 0))))
#[(from-to) "address@hidden \302A!Q\207" [from-to separator
query-replace-descr] 4](("" replace-eval-replacement replace-quote (concat
(match-string 0))))
mapcar(#[(from-to) "address@hidden \302A!Q\207" [from-to separator
query-replace-descr] 4] (("" replace-eval-replacement replace-quote (concat
(match-string 0))) ("^." . "\\,(concat \\#&)")))
query-replace-read-from("Query replace" nil)
query-replace-read-args("Query replace" nil)
(let ((common (query-replace-read-args (concat "Query replace" (if
current-prefix-arg (if (eq current-prefix-arg ...) " backward" " word") "") (if
(and transient-mark-mode mark-active) " in region" "")) nil))) (list (nth 0
common) (nth 1 common) (nth 2 common) (if (and transient-mark-mode mark-active)
(region-beginning)) (if (and transient-mark-mode mark-active) (region-end))
(nth 3 common)))
call-interactively(query-replace nil nil)
command-execute(query-replace)
The issue is that isearch-text-char-description expects a string
argument, but it's getting bits of that s-expression; specifically
'replace-eval-replacement. I haven't looked further, and I don't know if
this value of the history variables is wrong, or if their parsing is
incorrect in some way.
Thanks
--- End Message ---
--- Begin Message ---
Subject: |
Re: bug#19383: 25.0.50; query-replace-regexp becomes unusable when using lisp expressions for replacement |
Date: |
Tue, 16 Dec 2014 01:54:53 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (x86_64-pc-linux-gnu) |
> The issue is that isearch-text-char-description expects a string
> argument, but it's getting bits of that s-expression; specifically
> 'replace-eval-replacement. I haven't looked further, and I don't know if
> this value of the history variables is wrong, or if their parsing is
> incorrect in some way.
Thanks for the detailed report. This was caused by the recent changes
and is fixed now.
--- End Message ---