;;; replace.el --- replace commands for Emacs
-;; Copyright (C) 1985-1987, 1992, 1994, 1996-1997, 2000-2012
-;; Free Software Foundation, Inc.
+;; Copyright (C) 1985-1987, 1992, 1994, 1996-1997, 2000-2013 Free
+;; Software Foundation, Inc.
;; Maintainer: FSF
;; Package: emacs
(defvar query-replace-interactive nil
"Non-nil means `query-replace' uses the last search string.
That becomes the \"string to replace\".")
+(make-obsolete-variable 'query-replace-interactive
+ "use `M-n' to pull the last incremental search string
+to the minibuffer that reads the string to replace, or invoke replacements
+from Isearch by using a key sequence like `C-s C-s M-%'." "24.3")
(defcustom query-replace-from-history-variable 'query-replace-history
"History list to use for the FROM argument of `query-replace' commands.
(if regexp-flag
(read-regexp prompt nil query-replace-from-history-variable)
(read-from-minibuffer
- prompt nil nil nil query-replace-from-history-variable nil t)))))
+ prompt nil nil nil query-replace-from-history-variable
+ (car (if regexp-flag regexp-search-ring search-ring)) t)))))
(if (and (zerop (length from)) query-replace-defaults)
(cons (car query-replace-defaults)
(query-replace-compile-replacement
In Transient Mark mode, if the mark is active, operate on the contents
of the region. Otherwise, operate from point to the end of the buffer.
-If `query-replace-interactive' is non-nil, the last incremental search
-string is used as FROM-STRING--you don't have to specify it with the
-minibuffer.
+Use \\<minibuffer-local-map>\\[next-history-element] \
+to pull the last incremental search string to the minibuffer
+that reads FROM-STRING, or invoke replacements from
+incremental search with a key sequence like `C-s C-s M-%'
+to use its current search string as the string to replace.
Matching is independent of case if `case-fold-search' is non-nil and
FROM-STRING has no uppercase letters. Replacement transfers the case
In Transient Mark mode, if the mark is active, operate on the contents
of the region. Otherwise, operate from point to the end of the buffer.
-If `query-replace-interactive' is non-nil, the last incremental search
-regexp is used as REGEXP--you don't have to specify it with the
-minibuffer.
+Use \\<minibuffer-local-map>\\[next-history-element] \
+to pull the last incremental search regexp to the minibuffer
+that reads REGEXP, or invoke replacements from
+incremental search with a key sequence like `C-M-s C-M-s C-M-%'
+to use its current search regexp as the regexp to replace.
Matching is independent of case if `case-fold-search' is non-nil and
REGEXP has no uppercase letters. Replacement transfers the case
In Transient Mark mode, if the mark is active, operate on the contents
of the region. Otherwise, operate from point to the end of the buffer.
-If `query-replace-interactive' is non-nil, the last incremental search
-regexp is used as REGEXP--you don't have to specify it with the
-minibuffer.
+Use \\<minibuffer-local-map>\\[next-history-element] \
+to pull the last incremental search regexp to the minibuffer
+that reads REGEXP.
Preserves case in each replacement if `case-replace' and `case-fold-search'
are non-nil and REGEXP has no uppercase letters.
Non-interactively, TO-STRINGS may be a list of replacement strings.
-If `query-replace-interactive' is non-nil, the last incremental search
-regexp is used as REGEXP--you don't have to specify it with the minibuffer.
+Use \\<minibuffer-local-map>\\[next-history-element] \
+to pull the last incremental search regexp to the minibuffer
+that reads REGEXP.
A prefix argument N says to use each replacement string N times
before rotating to the next.
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 "Map query replace (regexp): "
- nil nil nil
- query-replace-from-history-variable
- nil t)))
+ (let* ((from (read-regexp "Map query replace (regexp): " nil
+ query-replace-from-history-variable))
(to (read-from-minibuffer
(format "Query replace %s with (space-separated strings): "
(query-replace-descr from))
only matches surrounded by word boundaries.
Fourth and fifth arg START and END specify the region to operate on.
-If `query-replace-interactive' is non-nil, the last incremental search
-string is used as FROM-STRING--you don't have to specify it with the
-minibuffer.
+Use \\<minibuffer-local-map>\\[next-history-element] \
+to pull the last incremental search string to the minibuffer
+that reads FROM-STRING.
This function is usually the wrong thing to use in a Lisp program.
What you probably want is a loop like this:
text, TO-STRING is actually made a list instead of a string.
Use \\[repeat-complex-command] after this command for details.
-If `query-replace-interactive' is non-nil, the last incremental search
-regexp is used as REGEXP--you don't have to specify it with the minibuffer.
+Use \\<minibuffer-local-map>\\[next-history-element] \
+to pull the last incremental search regexp to the minibuffer
+that reads REGEXP.
This function is usually the wrong thing to use in a Lisp program.
What you probably want is a loop like this:
(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 DEFAULTS is non-nil, it displays the first default in the prompt.
-
-Non-nil optional arg DEFAULTS is a string or a list of strings that
-are prepended to a list of standard default values, which include the
-string at point, the last isearch regexp, the last isearch string, and
-the last replacement regexp.
-
-Non-nil HISTORY is a symbol to use for the history list.
+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))
- (defaults
- (append
- (if (listp defaults) defaults (list defaults))
- (list (regexp-quote
- (or (funcall (or find-tag-default-function
- (get major-mode 'find-tag-default-function)
- 'find-tag-default))
- ""))
- (car regexp-search-ring)
- (regexp-quote (or (car search-ring) ""))
- (car (symbol-value
- query-replace-from-history-variable)))))
- (defaults (delete-dups (delq nil (delete "" defaults))))
+ (let* ((default (if (consp defaults) (car defaults) defaults))
+ (suggestions (if (listp defaults) defaults (list defaults)))
+ (suggestions
+ (append
+ suggestions
+ (list
+ ;; Regexp for tag at point.
+ (let* ((tagf (or find-tag-default-function
+ (get major-mode 'find-tag-default-function)
+ 'find-tag-default))
+ (tag (funcall tagf)))
+ (cond ((not tag) "")
+ ((eq tagf 'find-tag-default)
+ (format "\\_<%s\\_>" (regexp-quote tag)))
+ (t (regexp-quote tag))))
+ (car regexp-search-ring)
+ (regexp-quote (or (car search-ring) ""))
+ (car (symbol-value query-replace-from-history-variable)))))
+ (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
(query-replace-descr default)))
(t
(format "%s: " prompt)))
- nil nil nil (or history 'regexp-history) defaults t)))
+ 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)
+ ;; Otherwise, add non-empty input to the history and return input.
(prog1 input
(add-to-history (or history 'regexp-history) input)))))
C-r to enter recursive edit (\\[exit-recursive-edit] to get out again),
C-w to delete match and recursive edit,
C-l to clear the screen, redisplay, and offer same replacement again,
-! to replace all remaining matches with no more questions,
+! to replace all remaining matches in this buffer with no more questions,
^ to move point back to previous match,
-E to edit the replacement string"
+E to edit the replacement string.
+In multi-buffer replacements type `Y' to replace all remaining
+matches in all remaining buffers with no more questions,
+`N' to skip to the next buffer without replacing remaining matches
+in the current buffer."
"Help message while in `query-replace'.")
(defvar query-replace-map
case-fold-search))
(nocasify (not (and case-replace case-fold-search)))
(literal (or (not regexp-flag) (eq regexp-flag 'literal)))
- (search-function
- (or (if regexp-flag
- replace-re-search-function
- replace-search-function)
- (let ((isearch-regexp regexp-flag)
- (isearch-word delimited-flag)
- (isearch-lax-whitespace
- replace-lax-whitespace)
- (isearch-regexp-lax-whitespace
- replace-regexp-lax-whitespace)
- (isearch-case-fold-search case-fold-search)
- (isearch-forward t))
- (isearch-search-fun))))
(search-string from-string)
(real-match-data nil) ; The match data for the current match.
(next-replacement nil)
;; Loop finding occurrences that perhaps should be replaced.
(while (and keep-going
(not (or (eobp) (and limit (>= (point) limit))))
- ;; Use the next match if it is already known;
- ;; otherwise, search for a match after moving forward
- ;; one char if progress is required.
- (setq real-match-data
- (cond ((consp match-again)
- (goto-char (nth 1 match-again))
- (replace-match-data
- t real-match-data match-again))
- ;; MATCH-AGAIN non-nil means accept an
- ;; adjacent match.
- (match-again
- (and
- (funcall search-function search-string
- limit t)
- ;; For speed, use only integers and
- ;; reuse the list used last time.
- (replace-match-data t real-match-data)))
- ((and (< (1+ (point)) (point-max))
- (or (null limit)
- (< (1+ (point)) limit)))
- ;; If not accepting adjacent matches,
- ;; move one char to the right before
- ;; searching again. Undo the motion
- ;; if the search fails.
- (let ((opoint (point)))
- (forward-char 1)
- (if (funcall
- search-function search-string
- limit t)
- (replace-match-data
- t real-match-data)
- (goto-char opoint)
- nil))))))
+ ;; Let-bind global isearch-* variables to values used
+ ;; to search the next replacement. These let-bindings
+ ;; should be effective both at the time of calling
+ ;; `isearch-search-fun-default' and also at the
+ ;; time of funcalling `search-function'.
+ ;; These isearch-* bindings can't be placed higher
+ ;; outside of this loop because then another I-search
+ ;; used after `recursive-edit' might override them.
+ (let* ((isearch-regexp regexp-flag)
+ (isearch-word delimited-flag)
+ (isearch-lax-whitespace
+ replace-lax-whitespace)
+ (isearch-regexp-lax-whitespace
+ replace-regexp-lax-whitespace)
+ (isearch-case-fold-search case-fold-search)
+ (isearch-adjusted nil)
+ (isearch-nonincremental t) ; don't use lax word mode
+ (isearch-forward t)
+ (search-function
+ (or (if regexp-flag
+ replace-re-search-function
+ replace-search-function)
+ (isearch-search-fun-default))))
+ ;; Use the next match if it is already known;
+ ;; otherwise, search for a match after moving forward
+ ;; one char if progress is required.
+ (setq real-match-data
+ (cond ((consp match-again)
+ (goto-char (nth 1 match-again))
+ (replace-match-data
+ t real-match-data match-again))
+ ;; MATCH-AGAIN non-nil means accept an
+ ;; adjacent match.
+ (match-again
+ (and
+ (funcall search-function search-string
+ limit t)
+ ;; For speed, use only integers and
+ ;; reuse the list used last time.
+ (replace-match-data t real-match-data)))
+ ((and (< (1+ (point)) (point-max))
+ (or (null limit)
+ (< (1+ (point)) limit)))
+ ;; If not accepting adjacent matches,
+ ;; move one char to the right before
+ ;; searching again. Undo the motion
+ ;; if the search fails.
+ (let ((opoint (point)))
+ (forward-char 1)
+ (if (funcall
+ search-function search-string
+ limit t)
+ (replace-match-data
+ t real-match-data)
+ (goto-char opoint)
+ nil)))))))
;; Record whether the match is nonempty, to avoid an infinite loop
;; repeatedly matching the same empty string.
replace-regexp-lax-whitespace)
(isearch-case-fold-search case-fold-search)
(isearch-forward t)
+ (isearch-other-end match-beg)
(isearch-error nil))
(isearch-lazy-highlight-new-loop range-beg range-end))))