Question as title.
More specifically, I'm rather tired of having to type \(
, etc. every time I want a parenthesis in Emacs's (interactive) regexp functions (not to mention the \\(
in code). So I wrote something like
(defadvice query-replace-regexp (before my-query-replace-regexp activate)
(ad-set-arg 0 (replace-regexp-in-string "(" "\\\\(" (ad-get-arg 0)))
(ad-set-arg 0 (replace-regexp-in-string ")" "\\\\)" (ad-get-arg 0)))))
in hope that I can conveniently forget about emacs's idiosyncrasy in regexp during "interaction mode". Except I cannot get the regexp right...
(replace-regexp-in-string "(" "\\\\(" "(abc")
gives \\(abc
instead of the wanted \(abc
. Other variations on the number of slashes just gives errors. Thoughts?
Since I started questioning, might as well ask another one: since lisp code is not supposed to use interactive functions, advicing query-replace-regexp
should be okay, am I correct?
The replacement you has works well for me.
Take the text:
hi there mom
hi son!
and try query-replace-regexp with your advice:
M-x query-replace-regexp (hi).*(mom) RET \1 \2! RET
yields
hi mom!
hi son!
I didn't have to put a backslash in front of the parentheses to get them to group. That said, this disables being able to match actual parentheses...
The reason the replace-regexp-in-string
yields \\(abc
, is that as a string, that is equivalent to an interactively typed \(abc
. In a string \
is used to denote that the following character is special, e.g. "\t"
is a string with a tab. So, in order to specify just a backslash, you need to use a backslash in front of it "\\"
is a string containing a backslash.
Regarding advising interactive functions, lisp code can call interactive functions all it wants. A prime example is find-file
- which is called all over the place. To make your advice a little safer, you can wrap the body with a check for interactive-p
to avoid mussing with internal calls:
(defadvice query-replace-regexp (before my-query-replace-regexp activate)
(when (interactive-p)
(ad-set-arg 0 (replace-regexp-in-string "(" "\\\\(" (ad-get-arg 0)))
(ad-set-arg 0 (replace-regexp-in-string ")" "\\\\)" (ad-get-arg 0)))))