(query-replace-descr): New fun.
[bpt/emacs.git] / lisp / replace.el
index 380dd83..a7c8b85 100644 (file)
@@ -1,7 +1,7 @@
 ;;; replace.el --- replace commands for Emacs
 
-;; Copyright (C) 1985, 86, 87, 92, 94, 96, 1997, 2000, 2001, 2002,
-;;   2003, 2004 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1992, 1994, 1996, 1997, 2000, 2001, 2002,
+;;   2003, 2004  Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 
@@ -64,37 +64,54 @@ strings or patterns."
   :group 'matching
   :version "21.4")
 
+(defun query-replace-descr (string)
+  (mapconcat 'isearch-text-char-description string ""))
+
 (defun query-replace-read-from (string regexp-flag)
-  "Query and return the `from' argument of a query-replace operation."
+  "Query and return the `from' argument of a query-replace operation.
+The return value can also be a pair (FROM . TO) indicating that the user
+wants to replace FROM with TO."
   (if query-replace-interactive
       (car (if regexp-flag regexp-search-ring search-ring))
-    (let* ((from
+    (let* ((lastfrom (car (symbol-value query-replace-from-history-variable)))
+          (lastto (car (symbol-value query-replace-to-history-variable)))
+          (from
            ;; The save-excursion here is in case the user marks and copies
            ;; a region in order to specify the minibuffer input.
            ;; That should not clobber the region for the query-replace itself.
            (save-excursion
+             (when (equal lastfrom lastto)
+               ;; Typically, this is because the two histlists are shared.
+               (setq lastfrom (cadr (symbol-value
+                                     query-replace-from-history-variable))))
              (read-from-minibuffer
-              (format "%s: " string)
+              (if (and lastto lastfrom)
+                  (format "%s (default %s -> %s): " string
+                          (query-replace-descr lastfrom)
+                          (query-replace-descr lastto))
+                (format "%s: " string))
               nil nil nil
               query-replace-from-history-variable
               nil t))))
-      ;; Warn if user types \n or \t, but don't reject the input.
-      (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)))
-      from)))
+      (if (and (zerop (length from)) lastto lastfrom)
+         (cons lastfrom lastto)
+       ;; Warn if user types \n or \t, but don't reject the input.
+       (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)))
+       from))))
 
 (defun query-replace-read-to (from string regexp-flag)
   "Query and return the `from' argument of a query-replace operation."
   (let ((to (save-excursion
              (read-from-minibuffer
-              (format "%s %s with: " string from)
+              (format "%s %s with: " string (query-replace-descr from))
               nil nil nil
               query-replace-to-history-variable from t))))
     (when (and regexp-flag
@@ -137,7 +154,8 @@ strings or patterns."
   (unless noerror
     (barf-if-buffer-read-only))
   (let* ((from (query-replace-read-from string regexp-flag))
-        (to (query-replace-read-to from string regexp-flag)))
+        (to (if (consp from) (prog1 (cdr from) (setq from (car from)))
+              (query-replace-read-to from string regexp-flag))))
     (list from to current-prefix-arg)))
 
 (defun query-replace (from-string to-string &optional delimited start end)
@@ -269,14 +287,16 @@ Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
 only matches that are surrounded by word boundaries.
 Fourth and fifth arg START and END specify the region to operate on."
   (interactive
-   (let* ((from (if query-replace-interactive
-                   (car regexp-search-ring)
-                 (read-from-minibuffer "Query replace regexp: "
-                                       nil nil nil
-                                       query-replace-from-history-variable
-                                       nil t)))
+   (barf-if-buffer-read-only)
+   (let* ((from
+          ;; Let-bind the history var to disable the "foo -> bar" default.
+          ;; Maybe we shouldn't disable this default, but for now I'll
+          ;; leave it off.  --Stef
+          (let ((query-replace-to-history-variable nil))
+            (query-replace-read-from "Query replace regexp" t)))
          (to (list (read-from-minibuffer
-                    (format "Query replace regexp %s with eval: " from)
+                    (format "Query replace regexp %s with eval: "
+                            (query-replace-descr from))
                     nil nil t query-replace-to-history-variable from t))))
      ;; We make TO a list because replace-match-string-symbols requires one,
      ;; and the user might enter a single token.
@@ -317,7 +337,7 @@ Fourth and fifth arg START and END specify the region to operate on."
                                        'query-replace-history nil t)))
          (to (read-from-minibuffer
               (format "Query replace %s with (space-separated strings): "
-                      from)
+                      (query-replace-descr from))
               nil nil nil
               'query-replace-history from t)))
      (list from to
@@ -760,7 +780,7 @@ If the value is nil, don't highlight the buffer names specially."
                (read-from-minibuffer
                 (if default
                     (format "List lines matching regexp (default `%s'): "
-                            default)
+                            (query-replace-descr default))
                   "List lines matching regexp: ")
                 nil
                 nil
@@ -1538,5 +1558,5 @@ make, or the user didn't cancel the call."
                      (if (facep 'query-replace)
                          'query-replace 'region)))))
 
-;;; arch-tag: 16b4cd61-fd40-497b-b86f-b667c4cf88e4
+;; arch-tag: 16b4cd61-fd40-497b-b86f-b667c4cf88e4
 ;;; replace.el ends here