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: 17 Jun 2004 02:56:37 +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> <87llin98sc.fsf@mail.jurta.org> <87n033y0yj.fsf@mail.jurta.org> NNTP-Posting-Host: deer.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Trace: sea.gmane.org 1087433818 19118 80.91.224.253 (17 Jun 2004 00:56:58 GMT) X-Complaints-To: usenet@sea.gmane.org NNTP-Posting-Date: Thu, 17 Jun 2004 00:56:58 +0000 (UTC) Cc: Juri Linkov , schwab@suse.de, emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+emacs-devel=quimby.gnus.org@gnu.org Thu Jun 17 02:56:52 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 1BalD2-0003Oo-00 for ; Thu, 17 Jun 2004 02:56:52 +0200 Original-Received: from lists.gnu.org ([199.232.76.165]) by quimby.gnus.org with esmtp (Exim 3.35 #1 (Debian)) id 1BalD1-0003NX-00 for ; Thu, 17 Jun 2004 02:56:51 +0200 Original-Received: from localhost ([127.0.0.1] helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BalE2-0001Pk-QQ for emacs-devel@quimby.gnus.org; Wed, 16 Jun 2004 20:57:54 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.33) id 1BalDz-0001Pf-RY for emacs-devel@gnu.org; Wed, 16 Jun 2004 20:57:51 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.33) id 1BalDz-0001PT-7i for emacs-devel@gnu.org; Wed, 16 Jun 2004 20:57:51 -0400 Original-Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.33) id 1BalDz-0001PJ-6K for emacs-devel@gnu.org; Wed, 16 Jun 2004 20:57:51 -0400 Original-Received: from [199.232.76.164] (helo=fencepost.gnu.org) by monty-python.gnu.org with esmtp (Exim 4.34) id 1BalCp-0003Zv-W7 for emacs-devel@gnu.org; Wed, 16 Jun 2004 20:56:40 -0400 Original-Received: from localhost ([127.0.0.1] helo=lola.goethe.zz) by fencepost.gnu.org with esmtp (Exim 4.34) id 1BalCo-0000Eq-KY; Wed, 16 Jun 2004 20:56:39 -0400 Original-To: storm@cua.dk (Kim F. Storm) In-Reply-To: Original-Lines: 43 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:25053 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:25053 --=-=-= storm@cua.dk (Kim F. Storm) writes: > David Kastrup writes: > > > Juri Linkov writes: > > > > > It is not important what question it asks. It would work even for > > > two or three different \? in one replacement string. In rare cases > > > where the user needs more \?, he can use \,(read-string "My prompt: > > > "). > > > > > > Or to let it to automatically enumerate prompt strings, i.e. to have > > > a counter in expression generating code in `query-replace-regexp' > > > that will convert several \? in the same string into prompts in a > > > fixed format with the prompt counter added to the prompt string: > > > > > > (concat (read-string "Enter string 1: ") (read-string "Enter string > > > 2: ")) > > > > Yes, I might do something like that. > > Maybe "Enter string: " for the first one, "Enter string 2:" etc for the > following strings. Ouch, I just realized that the dialog will basically be: Enter string: xsxa RET Query replace gfag with fdsfxsxa* (y/n)? That's so weird that I don't really know if it should be a "feature" with its own shortcut. Entering the strings when they might not even get used... I'll just post the current untested diff (which might or might not work) since I'm about to fall asleep. In case it works, people have something to play with. --=-=-= Content-Type: text/x-patch Content-Disposition: attachment --- replace.el 10 Jun 2004 09:36:09 +0200 1.172 +++ replace.el 17 Jun 2004 02:16:46 +0200 @@ -81,14 +81,15 @@ query-replace-from-history-variable nil t))) ;; Warn if user types \n or \t, but don't reject the input. - (if (string-match "\\\\[nt]" from) - (let ((match (match-string 0 from))) - (cond - ((string= match "\\n") - (message "Note: `\\n' here doesn't match a newline; to do that, type C-q C-j instead")) - ((string= match "\\t") - (message "Note: `\\t' here doesn't match a tab; to do that, just type TAB"))) - (sit-for 2)))) + (and regexp-flag + (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\)*\\(\\\\[nt]\\)" from) + (let ((match (match-string 3 from))) + (cond + ((string= match "\\n") + (message "Note: `\\n' here doesn't match a newline; to do that, type C-q C-j instead")) + ((string= match "\\t") + (message "Note: `\\t' here doesn't match a tab; to do that, just type TAB"))) + (sit-for 2)))) (save-excursion (setq to (read-from-minibuffer (format "%s %s with: " string from) @@ -165,18 +166,65 @@ (interactive (let ((common (query-replace-read-args "Query replace regexp" t))) - (list (nth 0 common) (nth 1 common) (nth 2 common) - ;; These are done separately here - ;; so that command-history will record these expressions - ;; rather than the values they had this time. - (if (and transient-mark-mode mark-active) - (region-beginning)) - (if (and transient-mark-mode mark-active) - (region-end))))) - + (list + (nth 0 common) + (if (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#?]" + (nth 1 common)) + (let ((to-string (nth 1 common)) pos to-expr char prompt) + (while (string-match + "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#?]" + to-string) + (setq pos (match-end 0)) + (push (substring to-string 0 (- pos 2)) to-expr) + (setq char (aref to-string (1- pos)) + to-string (substring to-string pos)) + (cond ((eq char ?\#) + (push '(number-to-string replace-count) to-expr)) + ((eq char ?\,) + (setq pos (read-from-string to-string)) + (push `(replace-quote ,(pop pos)) to-expr) + (setq to-string + (substring to-string + (if (and (< pos (length to-string)) + (eq (aref to-string pos) ?\ )) + (1+ pos) + pos)))) + ((eq char ?\?) + (push `(replace-quote + (replace-read-replacement + ,(if prompt + (progn + (setq prompt (1+ prompt)) + (format "Replacement %d: " prompt)) + (setq prompt 1) + "Replacement: "))) + to-expr)))) + (setq to-expr (delete "" (nreverse (cons to-string to-expr)))) + (replace-match-string-symbols to-expr) + (cons 'replace-eval-replacement + (if (> (length to-expr) 1) + (cons 'concat to-expr) + (car to-expr)))) + (nth 1 common)) + (nth 2 common) + ;; These are done separately here + ;; so that command-history will record these expressions + ;; rather than the values they had this time. + (if (and transient-mark-mode mark-active) + (region-beginning)) + (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 replace-read-replacement (prompt) + "Read a replacement string with PROMPT." + (read-from-minibuffer + prompt + nil nil t query-replace-to-history-variable + nil t)) + (defun query-replace-regexp-eval (regexp to-expr &optional delimited start end) "Replace some things after point matching REGEXP with the result of TO-EXPR. As each match is found, the user must type a character saying @@ -1012,6 +1060,7 @@ #N (string-to-number (match-string N)) & (match-string 0) #& (string-to-number (match-string 0)) +# replace-count Note that these symbols must be preceeded by a backslash in order to type them." @@ -1031,7 +1080,9 @@ ((string= "&" name) (setcar n '(match-string 0))) ((string= "#&" name) - (setcar n '(string-to-number (match-string 0)))))))) + (setcar n '(string-to-number (match-string 0)))) + ((string= "#" name) + (setcar n 'replace-count)))))) (setq n (cdr n)))) (defun replace-eval-replacement (expression replace-count) @@ -1040,6 +1091,21 @@ replacement (prin1-to-string replacement t)))) +(defun replace-quote (replacement) + "Quote a replacement string. +This just doubles all backslashes in REPLACEMENT and +returns the resulting string. If REPLACEMENT is not +a string, it is first passed through `prin1-to-string' +with the `noescape' argument set. + +`match-data' is preserved across the call." + (save-match-data + (replace-regexp-in-string "\\\\" "\\\\" + (if (stringp replacement) + replacement + (prin1-to-string replacement t)) + t t))) + (defun replace-loop-through-replacements (data replace-count) ;; DATA is a vector contaning the following values: ;; 0 next-rotate-count --=-=-= -- David Kastrup, Kriemhildstr. 15, 44793 Bochum --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Emacs-devel mailing list Emacs-devel@gnu.org http://lists.gnu.org/mailman/listinfo/emacs-devel --=-=-=--