emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: improving query-replace and query-replace-regexp


From: Juri Linkov
Subject: Re: improving query-replace and query-replace-regexp
Date: Sat, 03 Jul 2004 12:45:05 +0300
User-agent: Gnus/5.110002 (No Gnus v0.2) Emacs/21.3.50 (gnu/linux)

Stefan Monnier <address@hidden> writes:
>> What do you think of making M-% and C-M-% b behave similar to C-s and
>> C-u C-s?  This is, typing it a second time continues a previous
>> query-and-replace action.  This would save a lot of time.
> [...]
> +     (setq from (read-from-minibuffer (if (null lastto)
> +                                          (format "%s: " string)
> +                                        (format "%s [%s -> %s]: " string

When I looked more at the arrow in the prompt in the Stefan's patch,
I thought: why not to use that arrow in the input string instead of the
prompt.  This means to use a special user-defined separator to split
one input string into two parts: from-string and to-string.  When
using this, the prompt and a sample input string might look like this:

Query replace (sep=" -> "): x -> y

The separator value in the prompt reminds the user what string is
currently used as the separator in the input string.  Users should
choose such separators which don't appear in the text to replace.

This has several benefits: it's much easier to repeat previous
replacements by moving through the history list with both from-string
and to-string inserted into the minibuffer at a time; it's possible
to change from-string value during entering the value of to-string
in the same input string...

In the following patch a new variable `query-replace-args-separator'
is nil by default which means that the current behavior with two
separate prompts is still preserved.  But if this option is set
to a string, it is used to split the input string.  It the input
string doesn't contain a separator, then the string is considered
as the from-string only, and the second prompt asks for the to-string.
 
Index: lisp/replace.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/replace.el,v
retrieving revision 1.180
diff -u -r1.180 replace.el
--- lisp/replace.el     3 Jul 2004 05:18:38 -0000       1.180
+++ lisp/replace.el     3 Jul 2004 09:31:43 -0000
@@ -70,6 +70,17 @@
   :group 'matching
   :version "21.4")
 
+(defcustom query-replace-args-separator nil
+  "*Non-nil value separates from-string and to-string in one input string.
+This means that after `query-replace-read-args' reads the first
+argument it splits it using the value of this variable and
+assignes the first half of the input string to the from-string
+and the second half to the to-string.  This works provided the
+separator does not appear in the text you want to replace."
+  :type 'regexp
+  :group 'matching
+  :version "21.4")
+
 (defun query-replace-read-args (string regexp-flag &optional noerror)
   (unless noerror
     (barf-if-buffer-read-only))
@@ -82,12 +93,19 @@
       ;; That should not clobber the region for the query-replace itself.
       (save-excursion
         (setq from (read-from-minibuffer
-                    (format "%s: " string)
+                    (if query-replace-args-separator
+                        (format "%s (sep=\"%s\"): "
+                                string query-replace-args-separator)
+                      (format "%s: " string))
                     (if (eq query-replace-interactive 'initial)
                         (car (if regexp-flag regexp-search-ring search-ring)))
                     nil nil
                     query-replace-from-history-variable
                     nil t)))
+      (if (and query-replace-args-separator
+               (string-match query-replace-args-separator from))
+          (setq to   (substring from (match-end 0))
+                from (substring from 0 (match-beginning 0))))
       ;; Warn if user types \n or \t, but don't reject the input.
       (and regexp-flag
           (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\[nt]\\)" from)
@@ -99,11 +117,12 @@
               (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)
-                nil nil nil
-                query-replace-to-history-variable from t)))
+    (unless to
+      (save-excursion
+        (setq to (read-from-minibuffer
+                  (format "%s %s with: " string from)
+                  nil nil nil
+                  query-replace-to-history-variable from t))))
     (when (and regexp-flag
               (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to))
       (let (pos list char)

-- 
Juri Linkov
http://www.jurta.org/emacs/





reply via email to

[Prev in Thread] Current Thread [Next in Thread]