From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: David Kastrup Newsgroups: gmane.emacs.devel Subject: Re: query-replace-interactive not documented Date: 15 Jun 2004 17:43:52 +0200 Sender: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Message-ID: References: <20040528.181649.25475113.wl@gnu.org> <200405291737.i4THbPJ06689@raven.dms.auburn.edu> <873c5jug73.fsf@mail.jurta.org> <87oenqa4lu.fsf@mail.jurta.org> <873c51w5rq.fsf@mail.jurta.org> <87659snbd8.fsf@mail.jurta.org> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Trace: sea.gmane.org 1087314306 3227 80.91.224.253 (15 Jun 2004 15:45:06 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Tue, 15 Jun 2004 15:45:06 +0000 (UTC) Cc: emacs-devel@gnu.org, rms@gnu.org, storm@cua.dk Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Tue Jun 15 17:44:57 2004 Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by deer.gmane.org with esmtp (Exim 3.35 #1 (Debian)) id 1BaG7N-0003iR-00 for ; Tue, 15 Jun 2004 17:44:57 +0200 Original-Received: from lists.gnu.org ([199.232.76.165]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1BaG7M-0002TG-00 for ; Tue, 15 Jun 2004 17:44:57 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BaG8J-0002h0-L9 for emacs-devel@quimby.gnus.org; Tue, 15 Jun 2004 11:45:55 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1BaG8H-0002ga-3n for emacs-devel@gnu.org; Tue, 15 Jun 2004 11:45:53 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1BaG8G-0002gA-21 for emacs-devel@gnu.org; Tue, 15 Jun 2004 11:45:52 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BaG8F-0002fl-Pu for emacs-devel@gnu.org; Tue, 15 Jun 2004 11:45:51 -0400 Original-Received: from [199.232.76.164] (helo=fencepost.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.34) id 1BaG6T-0003Qp-V3 for emacs-devel@gnu.org; Tue, 15 Jun 2004 11:44:02 -0400 Original-Received: from localhost ([127.0.0.1] helo=lola.goethe.zz) by fencepost.gnu.org with esmtp (Exim 4.34) id 1BaG6M-0003Uq-Ki; Tue, 15 Jun 2004 11:43:55 -0400 Original-To: Juri Linkov In-Reply-To: <87659snbd8.fsf@mail.jurta.org> Original-Lines: 121 User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3.50 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.4 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Xref: main.gmane.org gmane.emacs.devel:25001 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:25001 Juri Linkov writes: > David Kastrup writes: > > storm@cua.dk (Kim F. Storm) writes: > >> Richard Stallman writes: > >> > That seems like an interesting idea. > >> > >> I would prefer a syntax which can be parsed with `read', which > >> includes the second example above, but not the first one. > > > > Well, this was of course just a wild proposal without any serious > > thought behind the involved details. One should probably take a look > > at eshell syntax maybe for getting some suggestions for a somewhat > > consistent syntax, and one would need to think about a way that makes > > it possible to end the expression in question without adding > > unnecessary spaces or so to the match. > > I like this idea. To avoid problems with `read' and to end the expression > explicitly I suggest to always place the expression in parenthesis. > To use a single variable inside a replacement string, one can use > a no-op function like `+': > > \\footnote{\\label{fn:\!(+ replace-count)} If there are always to be parens around, then there would be no need for !. One could just write \\footnote{\\label{fn:\(+ replace-count\)} I don't see a good way around having to backslash the closing paren: if one doesn't, paren matching goes awry. > > And of course, this sort of stuff should not be done by > > replace-match or similar functions but just by the interactive > > function, to avoid opening security concerns when Emacs is used as > > a match-and-replace engine (where people don't expect it to > > execute arbitrary code). > > Doing it only in the interactive function instead of `replace-match' > seems right. This is needed only to save keystrokes for users. > Since `replace-match' is not a command, when the programmer writes a > loop with `re-search-forward' and `replace-match', he can construct > a replacement string explicitly with appropriate functions. > > Anyway, below is a quick implementation of such a feature. I tried it > a bit and I like it. What I don't like yet is the choice of a special > meta symbol `\!'. Usually this symbol is associated with the error code. > Perhaps, a better symbol would be \( itself like in: > > \\footnote{\\label{fn:\(+ replace-count)} > > but this has another problem: the open parenthesis is escaped > and Emacs commands don't match it with the close parenthesis. Oh shucks. That's what I get from replying before reading to the end. Anyway, since it appears that we can hardly avoid using non-escaped parens if we want to make use of the Lisp reader as well as paren matching, one might as well use the original proposal allowing a variable name directly. How about using \'? After all, we have an unevaled expression following. That would allow either \\footnote{\\label{fn:\'(+ replace-count)} or \\footnote{\\label{fn:\'replace-count }} Well, the latter has a spurious space. Bother. > Index: replace.el > =================================================================== > RCS file: /cvsroot/emacs/emacs/lisp/replace.el,v > retrieving revision 1.172 > diff -c -r1.172 replace.el > *** replace.el 10 Jun 2004 04:21:14 -0000 1.172 > --- replace.el 15 Jun 2004 14:56:15 -0000 > *************** > *** 174,180 **** > (if (and transient-mark-mode mark-active) > (region-end))))) > > ! (perform-replace regexp to-string t t delimited nil nil start end)) > (define-key esc-map [?\C-%] 'query-replace-regexp) > > (defun query-replace-regexp-eval (regexp to-expr &optional delimited start end) > --- 183,200 ---- > (if (and transient-mark-mode mark-active) > (region-end))))) > > ! (if (string-match "!\(" to-string) > ! (let (res) > ! (while (string-match "!\(" to-string) > ! (setq res (cons (substring to-string 0 (1- (match-beginning 0))) res) > ! to-string (substring to-string (1- (match-end 0)))) > ! (let ((r (read-from-string to-string))) > ! (setq res (cons `(format "%s" ,(car r)) res) > ! to-string (substring to-string (cdr r))))) > ! (perform-replace regexp `(replace-eval-replacement > ! concat ,@(nreverse (cons to-string res))) > ! t 'literal delimited nil nil start end)) > ! (perform-replace regexp to-string t t delimited nil nil start end))) > (define-key esc-map [?\C-%] 'query-replace-regexp) > > (defun query-replace-regexp-eval (regexp to-expr &optional delimited start end) First you are matching against !( not against \!( or similar. Then you are not replacing any \1 \2 or similar sequences as far as I can see. It will probably not be easy to do this right: have the \( replacement not being interpreted afterwards, but the non-evalled ones still being interpreted. Probably one needs to explicitly double any \ returned from the evaluation, and then call perform-replace with "t" instead of 'literal. Something like that. -- David Kastrup, Kriemhildstr. 15, 44793 Bochum