This is related to Emacs: regular expression replacing to change case
My additional problem is that I need to script the search-replace but the "\,()"
solution works (for me) only when used interactively (emacs 24.2.1)
. Inside a script it gives the error: "Invalid use of \'
in replacement text".
I usually write a "perform-replace" to some file to be loaded when needed. Something like:
(perform-replace "<\\([^>]+\\)>" "<\\,(downcase \1)>"
t t nil 1 nil (point-min) (point-max))
It should be possible to call a function to generate the replacement (pg 741 of the emacs lisp manual)
, but I've tried many variations of the following with no luck:
(defun myfun ()
(downcase (match-string 0)))
(perform-replace "..." (myfun . ()) t t nil)
Can anyone help?
Constructs like
\,()
are only allowed in interactive calls toquery-replace
, which is why Emacs complains in your case.The documentation of
perform-replace
mentions that you should not use it in elisp code and proposes a better alternative, upon which we can build the following code:If you still want to interactively query the user about the replacements, using
perform-replace
like you did is probably the right thing to do. There were a few different problems in your code:As stated in the elisp manual the replacement function must take two arguments (the data you provide in the cons cell and the number of replacements already made).
As stated in the documentation of
query-replace-regexp
(or the elisp manual), you need to ensure thatcase-fold-search
orcase-replace
is set to nil so that the case pattern is not transferred to the replacement.You need to quote the cons cell
(myfun . nil)
, otherwise it will be interpreted as a function call and evaluated too early.Here is a working version:
C-h f perform-replace
says:Now the
"<\\,(downcase \1)>"
needs to be replaced by an Elisp expression that builds the proper string, such as(format "<%s>" (downcase (match-string 1)))
.If you do need the query and stuff, then you might like to try:
C-M-% f\(o\)o RET bar \,(downcase \1) baz RET
and thenC-x RET RET
to see what arguments were constructed during the interactive call.You'll see discover (even better if you click on
replace.el
inC-h f perform-replace
to see the source code of the function), that thereplacements
argument can take the form (FUNCTION . ARGUMENT). More specifically, the code includes a comment giving some details: