summaryrefslogtreecommitdiff
path: root/lisp/replace.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/replace.el')
-rw-r--r--lisp/replace.el329
1 files changed, 207 insertions, 122 deletions
diff --git a/lisp/replace.el b/lisp/replace.el
index 6cee2253746..3503b656d9c 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -39,7 +39,7 @@
(defcustom replace-char-fold nil
"Non-nil means replacement commands should do character folding in matches.
This means, for instance, that \\=' will match a large variety of
-unicode quotes.
+Unicode quotes.
This variable affects `query-replace' and `replace-string', but not
`replace-regexp'."
:type 'boolean
@@ -147,15 +147,27 @@ is highlighted lazily using isearch lazy highlighting (see
See `replace-regexp' and `query-replace-regexp-eval'.")
(defun query-replace-descr (string)
- (mapconcat 'isearch-text-char-description string ""))
+ (setq string (copy-sequence string))
+ (dotimes (i (length string))
+ (let ((c (aref string i)))
+ (cond
+ ((< c ?\s) (add-text-properties
+ i (1+ i)
+ `(display ,(propertize (format "^%c" (+ c 64)) 'face 'escape-glyph))
+ string))
+ ((= c ?\^?) (add-text-properties
+ i (1+ i)
+ `(display ,(propertize "^?" 'face 'escape-glyph))
+ string)))))
+ string)
(defun query-replace--split-string (string)
"Split string STRING at a substring with property `separator'."
(let* ((length (length string))
(split-pos (text-property-any 0 length 'separator t string)))
(if (not split-pos)
- (substring-no-properties string)
- (cons (substring-no-properties string 0 split-pos)
+ string
+ (cons (substring string 0 split-pos)
(substring-no-properties
string (or (text-property-not-all
(1+ split-pos) length 'separator t string)
@@ -301,7 +313,9 @@ the original string if not."
(to (if (consp from) (prog1 (cdr from) (setq from (car from)))
(query-replace-read-to from prompt regexp-flag))))
(list from to
- (and current-prefix-arg (not (eq current-prefix-arg '-)))
+ (or (and current-prefix-arg (not (eq current-prefix-arg '-)))
+ (and (plist-member (text-properties-at 0 from) 'isearch-regexp-function)
+ (get-text-property 0 'isearch-regexp-function from)))
(and current-prefix-arg (eq current-prefix-arg '-)))))
(defun query-replace (from-string to-string &optional delimited start end backward region-noncontiguous-p)
@@ -345,6 +359,9 @@ character strings.
Fourth and fifth arg START and END specify the region to operate on.
+Arguments FROM-STRING, TO-STRING, DELIMITED, START, END, BACKWARD, and
+REGION-NONCONTIGUOUS-P are passed to `perform-replace' (which see).
+
To customize possible responses, change the bindings in `query-replace-map'."
(interactive
(let ((common
@@ -427,7 +444,10 @@ to terminate it. One space there, if any, will be discarded.
When using those Lisp features interactively in the replacement
text, TO-STRING is actually made a list instead of a string.
-Use \\[repeat-complex-command] after this command for details."
+Use \\[repeat-complex-command] after this command for details.
+
+Arguments REGEXP, TO-STRING, DELIMITED, START, END, BACKWARD, and
+REGION-NONCONTIGUOUS-P are passed to `perform-replace' (which see)."
(interactive
(let ((common
(query-replace-read-args
@@ -450,7 +470,7 @@ Use \\[repeat-complex-command] after this command for details."
(define-key esc-map [?\C-%] 'query-replace-regexp)
-(defun query-replace-regexp-eval (regexp to-expr &optional delimited start end)
+(defun query-replace-regexp-eval (regexp to-expr &optional delimited start end region-noncontiguous-p)
"Replace some things after point matching REGEXP with the result of TO-EXPR.
Interactive use of this function is deprecated in favor of the
@@ -496,7 +516,10 @@ This function is not affected by `replace-char-fold'.
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."
+Fourth and fifth arg START and END specify the region to operate on.
+
+Arguments REGEXP, DELIMITED, START, END, and REGION-NONCONTIGUOUS-P
+are passed to `perform-replace' (which see)."
(declare (obsolete "use the `\\,' feature of `query-replace-regexp'
for interactive calls, and `search-forward-regexp'/`replace-match'
for Lisp calls." "22.1"))
@@ -518,11 +541,12 @@ for Lisp calls." "22.1"))
(replace-match-string-symbols to)
(list from (car to) current-prefix-arg
(if (use-region-p) (region-beginning))
- (if (use-region-p) (region-end))))))
+ (if (use-region-p) (region-end))
+ (if (use-region-p) (region-noncontiguous-p))))))
(perform-replace regexp (cons 'replace-eval-replacement to-expr)
- t 'literal delimited nil nil start end))
+ t 'literal delimited nil nil start end nil region-noncontiguous-p))
-(defun map-query-replace-regexp (regexp to-strings &optional n start end)
+(defun map-query-replace-regexp (regexp to-strings &optional n start end region-noncontiguous-p)
"Replace some matches for REGEXP with various strings, in rotation.
The second argument TO-STRINGS contains the replacement strings, separated
by spaces. This command works like `query-replace-regexp' except that
@@ -542,7 +566,10 @@ 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."
+Fourth and fifth arg START and END specify the region to operate on.
+
+Arguments REGEXP, START, END, and REGION-NONCONTIGUOUS-P are passed to
+`perform-replace' (which see)."
(interactive
(let* ((from (read-regexp "Map query replace (regexp): " nil
query-replace-from-history-variable))
@@ -555,7 +582,8 @@ Fourth and fifth arg START and END specify the region to operate on."
(and current-prefix-arg
(prefix-numeric-value current-prefix-arg))
(if (use-region-p) (region-beginning))
- (if (use-region-p) (region-end)))))
+ (if (use-region-p) (region-end))
+ (if (use-region-p) (region-noncontiguous-p)))))
(let (replacements)
(if (listp to-strings)
(setq replacements to-strings)
@@ -569,9 +597,9 @@ Fourth and fifth arg START and END specify the region to operate on."
(1+ (string-match " " to-strings))))
(setq replacements (append replacements (list to-strings))
to-strings ""))))
- (perform-replace regexp replacements t t nil n nil start end)))
+ (perform-replace regexp replacements t t nil n nil start end nil region-noncontiguous-p)))
-(defun replace-string (from-string to-string &optional delimited start end backward)
+(defun replace-string (from-string to-string &optional delimited start end backward region-noncontiguous-p)
"Replace occurrences of FROM-STRING with TO-STRING.
Preserve case in each match if `case-replace' and `case-fold-search'
are non-nil and FROM-STRING has no uppercase letters.
@@ -625,10 +653,11 @@ and TO-STRING is also null.)"
(list (nth 0 common) (nth 1 common) (nth 2 common)
(if (use-region-p) (region-beginning))
(if (use-region-p) (region-end))
- (nth 3 common))))
- (perform-replace from-string to-string nil nil delimited nil nil start end backward))
+ (nth 3 common)
+ (if (use-region-p) (region-noncontiguous-p)))))
+ (perform-replace from-string to-string nil nil delimited nil nil start end backward region-noncontiguous-p))
-(defun replace-regexp (regexp to-string &optional delimited start end backward)
+(defun replace-regexp (regexp to-string &optional delimited start end backward region-noncontiguous-p)
"Replace things after point matching REGEXP with TO-STRING.
Preserve case in each match if `case-replace' and `case-fold-search'
are non-nil and REGEXP has no uppercase letters.
@@ -701,8 +730,9 @@ which will run faster and will not set the mark or print anything."
(list (nth 0 common) (nth 1 common) (nth 2 common)
(if (use-region-p) (region-beginning))
(if (use-region-p) (region-end))
- (nth 3 common))))
- (perform-replace regexp to-string nil t delimited nil nil start end backward))
+ (nth 3 common)
+ (if (use-region-p) (region-noncontiguous-p)))))
+ (perform-replace regexp to-string nil t delimited nil nil start end backward region-noncontiguous-p))
(defvar regexp-history nil
@@ -1192,7 +1222,8 @@ To return to ordinary Occur mode, use \\[occur-cease-edit]."
(defun occur-mode-goto-occurrence (&optional event)
"Go to the occurrence on the current line."
(interactive (list last-nonmenu-event))
- (let ((pos
+ (let ((buffer (when event (current-buffer)))
+ (pos
(if (null event)
;; Actually `event-end' works correctly with a nil argument as
;; well, so we could dispense with this test, but let's not
@@ -1204,26 +1235,31 @@ To return to ordinary Occur mode, use \\[occur-cease-edit]."
(occur-mode-find-occurrence))))))
(pop-to-buffer (marker-buffer pos))
(goto-char pos)
+ (when buffer (next-error-found buffer (current-buffer)))
(run-hooks 'occur-mode-find-occurrence-hook)))
(defun occur-mode-goto-occurrence-other-window ()
"Go to the occurrence the current line describes, in another window."
(interactive)
- (let ((pos (occur-mode-find-occurrence)))
+ (let ((buffer (current-buffer))
+ (pos (occur-mode-find-occurrence)))
(switch-to-buffer-other-window (marker-buffer pos))
(goto-char pos)
+ (next-error-found buffer (current-buffer))
(run-hooks 'occur-mode-find-occurrence-hook)))
(defun occur-mode-display-occurrence ()
"Display in another window the occurrence the current line describes."
(interactive)
- (let ((pos (occur-mode-find-occurrence))
+ (let ((buffer (current-buffer))
+ (pos (occur-mode-find-occurrence))
window)
(setq window (display-buffer (marker-buffer pos) t))
;; This is the way to set point in the proper window.
(save-selected-window
(select-window window)
(goto-char pos)
+ (next-error-found buffer (current-buffer))
(run-hooks 'occur-mode-find-occurrence-hook))))
(defun occur-find-match (n search message)
@@ -1236,7 +1272,7 @@ To return to ordinary Occur mode, use \\[occur-cease-edit]."
(setq r (funcall search r 'occur-match)))
(if r
(goto-char r)
- (error message))
+ (user-error message))
(setq n (1- n)))))
(defun occur-next (&optional n)
@@ -1253,29 +1289,20 @@ To return to ordinary Occur mode, use \\[occur-cease-edit]."
"Move to the Nth (default 1) next match in an Occur mode buffer.
Compatibility function for \\[next-error] invocations."
(interactive "p")
- ;; we need to run occur-find-match from within the Occur buffer
- (with-current-buffer
- ;; Choose the buffer and make it current.
- (if (next-error-buffer-p (current-buffer))
- (current-buffer)
- (next-error-find-buffer nil nil
- (lambda ()
- (eq major-mode 'occur-mode))))
-
- (goto-char (cond (reset (point-min))
- ((< argp 0) (line-beginning-position))
- ((> argp 0) (line-end-position))
- ((point))))
- (occur-find-match
- (abs argp)
- (if (> 0 argp)
- #'previous-single-property-change
- #'next-single-property-change)
- "No more matches")
- ;; In case the *Occur* buffer is visible in a nonselected window.
- (let ((win (get-buffer-window (current-buffer) t)))
- (if win (set-window-point win (point))))
- (occur-mode-goto-occurrence)))
+ (goto-char (cond (reset (point-min))
+ ((< argp 0) (line-beginning-position))
+ ((> argp 0) (line-end-position))
+ ((point))))
+ (occur-find-match
+ (abs argp)
+ (if (> 0 argp)
+ #'previous-single-property-change
+ #'next-single-property-change)
+ "No more matches")
+ ;; In case the *Occur* buffer is visible in a nonselected window.
+ (let ((win (get-buffer-window (current-buffer) t)))
+ (if win (set-window-point win (point))))
+ (occur-mode-goto-occurrence))
(defface match
'((((class color) (min-colors 88) (background light))
@@ -1387,9 +1414,8 @@ invoke `occur'."
;; Region limits when `occur' applies on a region.
(defvar occur--region-start nil)
(defvar occur--region-end nil)
-(defvar occur--matches-threshold nil)
+(defvar occur--region-start-line nil)
(defvar occur--orig-line nil)
-(defvar occur--orig-line-str nil)
(defvar occur--final-pos nil)
(defun occur (regexp &optional nlines region)
@@ -1442,17 +1468,15 @@ is not modified."
(or end (setq end (point-max))))
(let ((occur--region-start start)
(occur--region-end end)
- (occur--matches-threshold
+ (occur--region-start-line
(and in-region-p
(line-number-at-pos (min start end))))
(occur--orig-line
- (line-number-at-pos (point)))
- (occur--orig-line-str
- (buffer-substring-no-properties
- (line-beginning-position)
- (line-end-position))))
+ (line-number-at-pos (point))))
(save-excursion ; If no matches `occur-1' doesn't restore the point.
- (and in-region-p (narrow-to-region start end))
+ (and in-region-p (narrow-to-region
+ (save-excursion (goto-char start) (line-beginning-position))
+ (save-excursion (goto-char end) (line-end-position))))
(occur-1 regexp nlines (list (current-buffer)))
(and in-region-p (widen))))))
@@ -1550,7 +1574,7 @@ See also `multi-occur'."
(let ((inhibit-read-only t)
;; Don't generate undo entries for creation of the initial contents.
(buffer-undo-list t)
- (occur--final-pos nil))
+ (occur--final-pos nil))
(erase-buffer)
(let ((count
(if (stringp nlines)
@@ -1618,36 +1642,34 @@ See also `multi-occur'."
(global-matches 0) ;; total count of matches
(coding nil)
(case-fold-search case-fold)
- (in-region-p (and occur--region-start occur--region-end))
- (multi-occur-p (cdr buffers)))
+ (in-region-p (and occur--region-start occur--region-end))
+ (multi-occur-p (cdr buffers)))
;; Map over all the buffers
(dolist (buf buffers)
(when (buffer-live-p buf)
(let ((lines 0) ;; count of matching lines
(matches 0) ;; count of matches
(curr-line ;; line count
- (or occur--matches-threshold 1))
- (orig-line occur--orig-line)
- (orig-line-str occur--orig-line-str)
- (orig-line-shown-p)
+ (or occur--region-start-line 1))
+ (orig-line occur--orig-line)
+ (orig-line-shown-p)
(prev-line nil) ;; line number of prev match endpt
(prev-after-lines nil) ;; context lines of prev match
(matchbeg 0)
(origpt nil)
(begpt nil)
(endpt nil)
- (finalpt nil)
(marker nil)
(curstring "")
(ret nil)
(inhibit-field-text-motion t)
(headerpt (with-current-buffer out-buf (point))))
(with-current-buffer buf
- ;; The following binding is for when case-fold-search
- ;; has a local binding in the original buffer, in which
- ;; case we cannot bind it globally and let that have
- ;; effect in every buffer we search.
- (let ((case-fold-search case-fold))
+ ;; The following binding is for when case-fold-search
+ ;; has a local binding in the original buffer, in which
+ ;; case we cannot bind it globally and let that have
+ ;; effect in every buffer we search.
+ (let ((case-fold-search case-fold))
(or coding
;; Set CODING only if the current buffer locally
;; binds buffer-file-coding-system.
@@ -1677,6 +1699,16 @@ See also `multi-occur'."
;; Count empty lines that don't use next loop (Bug#22062).
(when (zerop len)
(setq matches (1+ matches)))
+ (when (and list-matching-lines-jump-to-current-line
+ (not multi-occur-p))
+ (when (= curr-line orig-line)
+ (add-face-text-property
+ 0 len list-matching-lines-current-line-face nil curstring)
+ (add-text-properties 0 len '(current-line t) curstring))
+ (when (and (>= orig-line (- curr-line nlines))
+ (<= orig-line (+ curr-line nlines)))
+ ;; Shown either here or will be shown by occur-context-lines
+ (setq orig-line-shown-p t)))
(while (and (< start len)
(string-match regexp curstring start))
(setq matches (1+ matches))
@@ -1703,9 +1735,9 @@ See also `multi-occur'."
;; at the end of the prefix
;; (for Occur Edit mode).
front-sticky t
- rear-nonsticky t
- occur-target ,marker
- follow-link t
+ rear-nonsticky t
+ occur-target ,marker
+ follow-link t
help-echo "mouse-2: go to this occurrence"))))
(match-str
;; We don't put `mouse-face' on the newline,
@@ -1725,7 +1757,7 @@ See also `multi-occur'."
"\n"
(if prefix-face
(propertize
- "\n :" 'font-lock-face prefix-face)
+ "\n :" 'font-lock-face prefix-face)
"\n :")
match-str)
;; Add marker at eol, but no mouse props.
@@ -1737,26 +1769,33 @@ See also `multi-occur'."
;; The complex multi-line display style.
(setq ret (occur-context-lines
out-line nlines keep-props begpt
- endpt curr-line prev-line
- prev-after-lines prefix-face))
+ endpt curr-line prev-line
+ prev-after-lines prefix-face
+ orig-line multi-occur-p))
;; Set first elem of the returned list to `data',
;; and the second elem to `prev-after-lines'.
(setq prev-after-lines (nth 1 ret))
- (nth 0 ret))))
+ (nth 0 ret)))
+ (orig-line-str
+ (when (and list-matching-lines-jump-to-current-line
+ (null orig-line-shown-p)
+ (> curr-line orig-line))
+ (setq orig-line-shown-p t)
+ (save-excursion
+ (goto-char (point-min))
+ (forward-line (- orig-line (or occur--region-start-line 1)))
+ (occur-engine-line (line-beginning-position)
+ (line-end-position) keep-props)))))
;; Actually insert the match display data
(with-current-buffer out-buf
- (when (and list-matching-lines-jump-to-current-line
- (not multi-occur-p)
- (not orig-line-shown-p)
- (>= curr-line orig-line))
- (insert
- (concat
- (propertize
- (format "%7d:%s" orig-line orig-line-str)
- 'face list-matching-lines-current-line-face
- 'mouse-face 'mode-line-highlight
- 'help-echo "Current line") "\n"))
- (setq orig-line-shown-p t finalpt (point)))
+ (when orig-line-str
+ (add-face-text-property
+ 0 (length orig-line-str)
+ list-matching-lines-current-line-face nil orig-line-str)
+ (add-text-properties 0 (length orig-line-str)
+ '(current-line t) orig-line-str)
+ (insert (car (occur-engine-add-prefix
+ (list orig-line-str) prefix-face))))
(insert data)))
(goto-char endpt))
(if endpt
@@ -1765,29 +1804,34 @@ See also `multi-occur'."
(setq curr-line (+ curr-line (count-lines begpt endpt)
;; Add 1 for empty last match line
;; since count-lines returns one
- ;; line less.
+ ;; line less.
(if (and (bolp) (eolp)) 1 0)))
;; On to the next match...
(forward-line 1))
(goto-char (point-max)))
(setq prev-line (1- curr-line)))
- ;; Insert original line if haven't done yet.
- (when (and list-matching-lines-jump-to-current-line
- (not multi-occur-p)
- (not orig-line-shown-p))
- (with-current-buffer out-buf
- (insert
- (concat
- (propertize
- (format "%7d:%s" orig-line orig-line-str)
- 'face list-matching-lines-current-line-face
- 'mouse-face 'mode-line-highlight
- 'help-echo "Current line") "\n"))))
;; Flush remaining context after-lines.
(when prev-after-lines
(with-current-buffer out-buf
(insert (apply #'concat (occur-engine-add-prefix
- prev-after-lines prefix-face)))))))
+ prev-after-lines prefix-face)))))
+ (when (and list-matching-lines-jump-to-current-line
+ (null orig-line-shown-p))
+ (setq orig-line-shown-p t)
+ (let ((orig-line-str
+ (save-excursion
+ (goto-char (point-min))
+ (forward-line (- orig-line (or occur--region-start-line 1)))
+ (occur-engine-line (line-beginning-position)
+ (line-end-position) keep-props))))
+ (add-face-text-property
+ 0 (length orig-line-str)
+ list-matching-lines-current-line-face nil orig-line-str)
+ (add-text-properties 0 (length orig-line-str)
+ '(current-line t) orig-line-str)
+ (with-current-buffer out-buf
+ (insert (car (occur-engine-add-prefix
+ (list orig-line-str) prefix-face))))))))
(when (not (zerop lines)) ;; is the count zero?
(setq global-lines (+ global-lines lines)
global-matches (+ global-matches matches))
@@ -1803,25 +1847,28 @@ See also `multi-occur'."
(if (= lines matches)
"" (format " in %d line%s"
lines
- (if (= lines 1) "" "s")))
+ (if (= lines 1) "" "s")))
;; Don't display regexp for multi-buffer.
(if (> (length buffers) 1)
"" (occur-regexp-descr regexp))
(buffer-name buf)
- (if in-region-p
- (format " within region: %d-%d"
- occur--region-start
- occur--region-end)
- ""))
+ (if in-region-p
+ (format " within region: %d-%d"
+ occur--region-start
+ occur--region-end)
+ ""))
'read-only t))
(setq end (point))
(add-text-properties beg end `(occur-title ,buf))
(when title-face
(add-face-text-property beg end title-face))
- (goto-char (if finalpt
- (setq occur--final-pos
- (cl-incf finalpt (- end beg)))
- (point-min))))))))))
+ (goto-char (if (and list-matching-lines-jump-to-current-line
+ (not multi-occur-p))
+ (setq occur--final-pos
+ (and (goto-char (point-max))
+ (or (previous-single-property-change (point) 'current-line)
+ (point-max))))
+ (point-min))))))))))
;; Display total match count and regexp for multi-buffer.
(when (and (not (zerop global-lines)) (> (length buffers) 1))
(goto-char (point-min))
@@ -1895,7 +1942,8 @@ See also `multi-occur'."
;; then concatenate them all together.
(defun occur-context-lines (out-line nlines keep-props begpt endpt
curr-line prev-line prev-after-lines
- &optional prefix-face)
+ &optional prefix-face
+ orig-line multi-occur-p)
;; Find after- and before-context lines of the current match.
(let ((before-lines
(nreverse (cdr (occur-accumulate-lines
@@ -1905,13 +1953,32 @@ See also `multi-occur'."
(1+ nlines) keep-props endpt)))
separator)
+ (when (and list-matching-lines-jump-to-current-line
+ (not multi-occur-p))
+ (when (and (>= orig-line (- curr-line nlines))
+ (< orig-line curr-line))
+ (let ((curstring (nth (- (length before-lines) (- curr-line orig-line)) before-lines)))
+ (add-face-text-property
+ 0 (length curstring)
+ list-matching-lines-current-line-face nil curstring)
+ (add-text-properties 0 (length curstring)
+ '(current-line t) curstring)))
+ (when (and (<= orig-line (+ curr-line nlines))
+ (> orig-line curr-line))
+ (let ((curstring (nth (- orig-line curr-line 1) after-lines)))
+ (add-face-text-property
+ 0 (length curstring)
+ list-matching-lines-current-line-face nil curstring)
+ (add-text-properties 0 (length curstring)
+ '(current-line t) curstring))))
+
;; Combine after-lines of the previous match
;; with before-lines of the current match.
(when prev-after-lines
;; Don't overlap prev after-lines with current before-lines.
(if (>= (+ prev-line (length prev-after-lines))
- (- curr-line (length before-lines)))
+ (- curr-line (length before-lines)))
(setq prev-after-lines
(butlast prev-after-lines
(- (length prev-after-lines)
@@ -2180,9 +2247,9 @@ It is called with three arguments, as if it were
;; used after `recursive-edit' might override them.
(let* ((isearch-regexp regexp-flag)
(isearch-regexp-function (or delimited-flag
- (and replace-char-fold
- (not regexp-flag)
- #'char-fold-to-regexp)))
+ (and replace-char-fold
+ (not regexp-flag)
+ #'char-fold-to-regexp)))
(isearch-lax-whitespace
replace-lax-whitespace)
(isearch-regexp-lax-whitespace
@@ -2212,7 +2279,10 @@ It is called with three arguments, as if it were
(if query-replace-lazy-highlight
(let ((isearch-string search-string)
(isearch-regexp regexp-flag)
- (isearch-regexp-function delimited-flag)
+ (isearch-regexp-function (or delimited-flag
+ (and replace-char-fold
+ (not regexp-flag)
+ #'char-fold-to-regexp)))
(isearch-lax-whitespace
replace-lax-whitespace)
(isearch-regexp-lax-whitespace
@@ -2273,7 +2343,12 @@ REPLACEMENTS is either a string, a list of strings, or a cons cell
containing a function and its first argument. The function is
called to generate each replacement like this:
(funcall (car replacements) (cdr replacements) replace-count)
-It must return a string."
+It must return a string.
+
+Non-nil REGION-NONCONTIGUOUS-P means that the region is composed of
+noncontiguous pieces. The most common example of this is a
+rectangular region, where the pieces are separated by newline
+characters."
(or map (setq map query-replace-map))
(and query-flag minibuffer-auto-raise
(raise-frame (window-frame (minibuffer-window))))
@@ -2318,8 +2393,17 @@ It must return a string."
(message
(if query-flag
(apply 'propertize
- (substitute-command-keys
- "Query replacing %s with %s: (\\<query-replace-map>\\[help] for help) ")
+ (concat "Query replacing "
+ (if backward "backward " "")
+ (if delimited-flag
+ (or (and (symbolp delimited-flag)
+ (get delimited-flag
+ 'isearch-message-prefix))
+ "word ") "")
+ (if regexp-flag "regexp " "")
+ "%s with %s: "
+ (substitute-command-keys
+ "(\\<query-replace-map>\\[help] for help) "))
minibuffer-prompt-properties))))
;; Unless a single contiguous chunk is selected, operate on multiple chunks.
@@ -2537,13 +2621,13 @@ It must return a string."
(with-output-to-temp-buffer "*Help*"
(princ
(concat "Query replacing "
+ (if backward "backward " "")
(if delimited-flag
(or (and (symbolp delimited-flag)
(get delimited-flag
'isearch-message-prefix))
"word ") "")
(if regexp-flag "regexp " "")
- (if backward "backward " "")
from-string " with "
next-replacement ".\n\n"
(substitute-command-keys
@@ -2576,6 +2660,7 @@ It must return a string."
(let ((stack-idx 0)
(stack-len (length stack))
(num-replacements 0)
+ (nocasify t) ; Undo must preserve case (Bug#31073).
search-string
next-replacement)
(while (and (< stack-idx stack-len)