evaluation time changes
[bpt/emacs.git] / lisp / replace.el
index 42f7f3c..cf88cb5 100644 (file)
@@ -1,9 +1,9 @@
 ;;; replace.el --- replace commands for Emacs
 
-;; Copyright (C) 1985-1987, 1992, 1994, 1996-1997, 2000-2013
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1985-1987, 1992, 1994, 1996-1997, 2000-2014 Free
+;; Software Foundation, Inc.
 
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
 ;; Package: emacs
 
 ;; This file is part of GNU Emacs.
@@ -450,6 +450,7 @@ of the region.  Otherwise, operate from point to the end of the buffer.
 
 Non-interactively, TO-STRINGS may be a list of replacement strings.
 
+Interactively, reads the regexp using `read-regexp'.
 Use \\<minibuffer-local-map>\\[next-history-element] \
 to pull the last incremental search regexp to the minibuffer
 that reads REGEXP.
@@ -522,6 +523,8 @@ What you probably want is a loop like this:
 which will run faster and will not set the mark or print anything.
 \(You may need a more complex loop if FROM-STRING can match the null string
 and TO-STRING is also null.)"
+  (declare (interactive-only
+           "use `search-forward' and `replace-match' instead."))
   (interactive
    (let ((common
          (query-replace-read-args
@@ -539,8 +542,6 @@ and TO-STRING is also null.)"
               (region-end))
           (nth 3 common))))
   (perform-replace from-string to-string nil nil delimited nil nil start end backward))
-(put 'replace-string 'interactive-only
-     "use `search-forward' and `replace-match' instead.")
 
 (defun replace-regexp (regexp to-string &optional delimited start end backward)
   "Replace things after point matching REGEXP with TO-STRING.
@@ -596,6 +597,8 @@ What you probably want is a loop like this:
   (while (re-search-forward REGEXP nil t)
     (replace-match TO-STRING nil nil))
 which will run faster and will not set the mark or print anything."
+  (declare (interactive-only
+           "use `re-search-forward' and `replace-match' instead."))
   (interactive
    (let ((common
          (query-replace-read-args
@@ -613,8 +616,6 @@ which will run faster and will not set the mark or print anything."
               (region-end))
           (nth 3 common))))
   (perform-replace regexp to-string nil t delimited nil nil start end backward))
-(put 'replace-regexp 'interactive-only
-     "use `re-search-forward' and `replace-match' instead.")
 
 \f
 (defvar regexp-history nil
@@ -626,40 +627,93 @@ of `history-length', which see.")
 (defvar occur-collect-regexp-history '("\\1")
   "History of regexp for occur's collect operation")
 
+(defcustom read-regexp-defaults-function nil
+  "Function that provides default regexp(s) for `read-regexp'.
+This function should take no arguments and return one of: nil, a
+regexp, or a list of regexps.  Interactively, `read-regexp' uses
+the return value of this function for its DEFAULT argument.
+
+As an example, set this variable to `find-tag-default-as-regexp'
+to default to the symbol at point.
+
+To provide different default regexps for different commands,
+the function that you set this to can check `this-command'."
+  :type '(choice
+         (const :tag "No default regexp reading function" nil)
+         (const :tag "Latest regexp history" regexp-history-last)
+         (function-item :tag "Tag at point"
+                        find-tag-default)
+         (function-item :tag "Tag at point as regexp"
+                        find-tag-default-as-regexp)
+         (function-item :tag "Tag at point as symbol regexp"
+                        find-tag-default-as-symbol-regexp)
+         (function :tag "Your choice of function"))
+  :group 'matching
+  :version "24.4")
+
+(defun read-regexp-suggestions ()
+  "Return a list of standard suggestions for `read-regexp'.
+By default, the list includes the tag at point, the last isearch regexp,
+the last isearch string, and the last replacement regexp.  `read-regexp'
+appends the list returned by this function to the end of values available
+via \\<minibuffer-local-map>\\[next-history-element]."
+  (list
+   (find-tag-default-as-regexp)
+   (find-tag-default-as-symbol-regexp)
+   (car regexp-search-ring)
+   (regexp-quote (or (car search-ring) ""))
+   (car (symbol-value query-replace-from-history-variable))))
+
 (defun read-regexp (prompt &optional defaults history)
   "Read and return a regular expression as a string.
-When PROMPT doesn't end with a colon and space, it adds a final \": \".
-If the first element of DEFAULTS is non-nil, it's added to the prompt.
-
-Optional arg DEFAULTS has the form (DEFAULT . SUGGESTIONS)
-or simply DEFAULT where DEFAULT, if non-nil, should be a string that
-is returned as the default value when the user enters empty input.
-SUGGESTIONS is a list of strings that can be inserted into
-the minibuffer using \\<minibuffer-local-map>\\[next-history-element].  \
-The values supplied in SUGGESTIONS
-are prepended to the list of standard suggestions that include
-the tag at point, the last isearch regexp, the last isearch string,
-and the last replacement regexp.
-
-Optional arg HISTORY is a symbol to use for the history list.
-If HISTORY is nil, `regexp-history' is used."
-  (let* ((default     (if (consp defaults) (car defaults) defaults))
+Prompt with the string PROMPT.  If PROMPT ends in \":\" (followed by
+optional whitespace), use it as-is.  Otherwise, add \": \" to the end,
+possibly preceded by the default result (see below).
+
+The optional argument DEFAULTS can be either: nil, a string, a list
+of strings, or a symbol.  We use DEFAULTS to construct the default
+return value in case of empty input.
+
+If DEFAULTS is a string, we use it as-is.
+
+If DEFAULTS is a list of strings, the first element is the
+default return value, but all the elements are accessible
+using the history command \\<minibuffer-local-map>\\[next-history-element].
+
+If DEFAULTS is a non-nil symbol, then if `read-regexp-defaults-function'
+is non-nil, we use that in place of DEFAULTS in the following:
+  If DEFAULTS is the symbol `regexp-history-last', we use the first
+  element of HISTORY (if specified) or `regexp-history'.
+  If DEFAULTS is a function, we call it with no arguments and use
+  what it returns, which should be either nil, a string, or a list of strings.
+
+We append the standard values from `read-regexp-suggestions' to DEFAULTS
+before using it.
+
+If the first element of DEFAULTS is non-nil (and if PROMPT does not end
+in \":\", followed by optional whitespace), we add it to the prompt.
+
+The optional argument HISTORY is a symbol to use for the history list.
+If nil, uses `regexp-history'."
+  (let* ((defaults
+          (if (and defaults (symbolp defaults))
+              (cond
+               ((eq (or read-regexp-defaults-function defaults)
+                    'regexp-history-last)
+                (car (symbol-value (or history 'regexp-history))))
+               ((functionp (or read-regexp-defaults-function defaults))
+                (funcall (or read-regexp-defaults-function defaults))))
+            defaults))
+        (default     (if (consp defaults) (car defaults) defaults))
         (suggestions (if (listp defaults) defaults (list defaults)))
-        (suggestions
-         (append
-          suggestions
-          (list
-           (find-tag-default-as-regexp)
-           (car regexp-search-ring)
-           (regexp-quote (or (car search-ring) ""))
-           (car (symbol-value query-replace-from-history-variable)))))
+        (suggestions (append suggestions (read-regexp-suggestions)))
         (suggestions (delete-dups (delq nil (delete "" suggestions))))
         ;; Do not automatically add default to the history for empty input.
         (history-add-new-input nil)
         (input (read-from-minibuffer
                 (cond ((string-match-p ":[ \t]*\\'" prompt)
                        prompt)
-                      (default
+                      ((and default (> (length default) 0))
                         (format "%s (default %s): " prompt
                                 (query-replace-descr default)))
                       (t
@@ -667,7 +721,9 @@ If HISTORY is nil, `regexp-history' is used."
                 nil nil nil (or history 'regexp-history) suggestions t)))
     (if (equal input "")
        ;; Return the default value when the user enters empty input.
-       (or default input)
+       (prog1 (or default input)
+         (when default
+           (add-to-history (or history 'regexp-history) default)))
       ;; Otherwise, add non-empty input to the history and return input.
       (prog1 input
        (add-to-history (or history 'regexp-history) input)))))
@@ -1192,32 +1248,12 @@ which means to discard all text properties."
   :group 'matching
   :version "22.1")
 
-(defvar occur-read-regexp-defaults-function
-  'occur-read-regexp-defaults
-  "Function that provides default regexp(s) for occur commands.
-This function should take no arguments and return one of nil, a
-regexp or a list of regexps for use with occur commands -
-`occur', `multi-occur' and `multi-occur-in-matching-buffers'.
-The return value of this function is used as DEFAULTS param of
-`read-regexp' while executing the occur command.  This function
-is called only during interactive use.
-
-For example, to check for occurrence of symbol at point use
-
-    (setq occur-read-regexp-defaults-function
-         'find-tag-default-as-regexp).")
-
-(defun occur-read-regexp-defaults ()
-  "Return the latest regexp from `regexp-history'.
-See `occur-read-regexp-defaults-function' for details."
-  (car regexp-history))
-
 (defun occur-read-primary-args ()
   (let* ((perform-collect (consp current-prefix-arg))
          (regexp (read-regexp (if perform-collect
                                   "Collect strings matching regexp"
                                 "List lines matching regexp")
-                              (funcall occur-read-regexp-defaults-function))))
+                              'regexp-history-last)))
     (list regexp
          (if perform-collect
              ;; Perform collect operation
@@ -1869,9 +1905,11 @@ but coerced to the correct value of INTEGERS."
 
 (defun replace-match-maybe-edit (newtext fixedcase literal noedit match-data backward)
   "Make a replacement with `replace-match', editing `\\?'.
-NEWTEXT, FIXEDCASE, LITERAL are just passed on.  If NOEDIT is true, no
-check for `\\?' is made to save time.  MATCH-DATA is used for the
-replacement.  In case editing is done, it is changed to use markers.
+FIXEDCASE, LITERAL are passed to `replace-match' (which see).
+After possibly editing it (if `\\?' is present), NEWTEXT is also
+passed to `replace-match'.  If NOEDIT is true, no check for `\\?'
+is made (to save time).  MATCH-DATA is used for the replacement.
+In case editing is done, it is changed to use markers.
 
 The return value is non-nil if there has been no `\\?' or NOEDIT was
 passed in.  If LITERAL is set, no checking is done, anyway."