]> code.delx.au - gnu-emacs/blobdiff - lisp/replace.el
Auto-commit of generated files.
[gnu-emacs] / lisp / replace.el
index fb98a714dff8bc70b9a578390db45536a35146f2..86b1aa27069c2868a7f6466c0bb1b6a2acf8bf02 100644 (file)
@@ -1,7 +1,7 @@
 ;;; replace.el --- replace commands for Emacs
 
-;; Copyright (C) 1985-1987, 1992, 1994, 1996-1997, 2000-2011
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1985-1987, 1992, 1994, 1996-1997, 2000-2013 Free
+;; Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Package: emacs
   :type 'boolean
   :group 'matching)
 
+(defcustom replace-lax-whitespace nil
+  "Non-nil means `query-replace' matches a sequence of whitespace chars.
+When you enter a space or spaces in the strings to be replaced,
+it will match any sequence matched by the regexp `search-whitespace-regexp'."
+  :type 'boolean
+  :group 'matching
+  :version "24.3")
+
+(defcustom replace-regexp-lax-whitespace nil
+  "Non-nil means `query-replace-regexp' matches a sequence of whitespace chars.
+When you enter a space or spaces in the regexps to be replaced,
+it will match any sequence matched by the regexp `search-whitespace-regexp'."
+  :type 'boolean
+  :group 'matching
+  :version "24.3")
+
 (defvar query-replace-history nil
   "Default history list for query-replace commands.
 See `query-replace-from-history-variable' and
@@ -46,6 +62,10 @@ no default value.")
 (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.
@@ -112,20 +132,22 @@ wants to replace FROM with TO."
   (if query-replace-interactive
       (car (if regexp-flag regexp-search-ring search-ring))
     (let* ((history-add-new-input nil)
+          (prompt
+           (if query-replace-defaults
+               (format "%s (default %s -> %s): " prompt
+                       (query-replace-descr (car query-replace-defaults))
+                       (query-replace-descr (cdr query-replace-defaults)))
+             (format "%s: " prompt)))
           (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
-             (read-from-minibuffer
-              (if query-replace-defaults
-                  (format "%s (default %s -> %s): " prompt
-                          (query-replace-descr (car query-replace-defaults))
-                          (query-replace-descr (cdr query-replace-defaults)))
-                (format "%s: " prompt))
-              nil nil nil
-              query-replace-from-history-variable
-              nil t))))
+             (if regexp-flag
+                 (read-regexp prompt nil query-replace-from-history-variable)
+               (read-from-minibuffer
+                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
@@ -214,9 +236,11 @@ what to do with it.  For directions, type \\[help-command] at that time.
 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
@@ -226,6 +250,10 @@ letters.  \(Transferring the case pattern means that if the old text
 matched is all caps, or capitalized, then its replacement is upcased
 or capitalized.)
 
+If `replace-lax-whitespace' is non-nil, a space or spaces in the string
+to be replaced will match a sequence of whitespace chars defined by the
+regexp in `search-whitespace-regexp'.
+
 Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
 only matches surrounded by word boundaries.
 Fourth and fifth arg START and END specify the region to operate on.
@@ -258,9 +286,11 @@ what to do with it.  For directions, type \\[help-command] at that time.
 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
@@ -270,6 +300,10 @@ pattern of the old text to the new text, if `case-replace' and
 all caps, or capitalized, then its replacement is upcased or
 capitalized.)
 
+If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp
+to be replaced will match a sequence of whitespace chars defined by the
+regexp in `search-whitespace-regexp'.
+
 Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
 only matches surrounded by word boundaries.
 Fourth and fifth arg START and END specify the region to operate on.
@@ -339,45 +373,47 @@ In interactive use, `\\#' in itself stands for `replace-count'.
 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.
 
+If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp
+to be replaced will match a sequence of whitespace chars defined by the
+regexp in `search-whitespace-regexp'.
+
 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."
+  (declare (obsolete "use the `\\,' feature of `query-replace-regexp'
+for interactive calls, and `search-forward-regexp'/`replace-match'
+for Lisp calls." "22.1"))
   (interactive
    (progn
-   (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: "
-                            (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.
-     (replace-match-string-symbols to)
-     (list from (car to) current-prefix-arg
-          (if (and transient-mark-mode mark-active)
-              (region-beginning))
-          (if (and transient-mark-mode mark-active)
-              (region-end))))))
+     (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: "
+                              (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.
+       (replace-match-string-symbols to)
+       (list from (car to) current-prefix-arg
+            (if (and transient-mark-mode mark-active)
+                (region-beginning))
+            (if (and transient-mark-mode mark-active)
+                (region-end))))))
   (perform-replace regexp (cons 'replace-eval-replacement to-expr)
                   t 'literal delimited nil nil start end))
 
-(make-obsolete 'query-replace-regexp-eval
-  "for interactive use, use the special `\\,' feature of
-`query-replace-regexp' instead.  Non-interactively, a loop
-using `search-forward-regexp' and `replace-match' is preferred." "22.1")
-
 (defun map-query-replace-regexp (regexp to-strings &optional n start end)
   "Replace some matches for REGEXP with various strings, in rotation.
 The second argument TO-STRINGS contains the replacement strings, separated
@@ -390,19 +426,16 @@ of the region.  Otherwise, operate from point to the end of the buffer.
 
 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))
@@ -437,6 +470,10 @@ are non-nil and FROM-STRING has no uppercase letters.
 \(Preserving case means that if the string matched is all caps, or capitalized,
 then its replacement is upcased or capitalized.)
 
+If `replace-lax-whitespace' is non-nil, a space or spaces in the string
+to be replaced will match a sequence of whitespace chars defined by the
+regexp in `search-whitespace-regexp'.
+
 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.
 
@@ -444,9 +481,9 @@ Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace
 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:
@@ -475,6 +512,10 @@ and TO-STRING is also null.)"
 Preserve case in each match if `case-replace' and `case-fold-search'
 are non-nil and REGEXP has no uppercase letters.
 
+If `replace-regexp-lax-whitespace' is non-nil, a space or spaces in the regexp
+to be replaced will match a sequence of whitespace chars defined by the
+regexp in `search-whitespace-regexp'.
+
 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.
 
@@ -505,8 +546,9 @@ 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.
 
-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:
@@ -538,38 +580,59 @@ of `history-length', which see.")
 (defvar occur-collect-regexp-history '("\\1")
   "History of regexp for occur's collect operation")
 
-(defun read-regexp (prompt &optional default-value)
-  "Read regexp as a string using the regexp history and some useful defaults.
-Prompt for a regular expression with PROMPT (without a colon and
-space) in the minibuffer.  The optional argument DEFAULT-VALUE
-provides the value to display in the minibuffer prompt that is
-returned if the user just types RET.
-Values available via M-n are the string at point, the last isearch
-regexp, the last isearch string, and the last replacement regexp."
-  (let* ((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))))
-        ;; Don't add automatically the car of defaults for empty input
+(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))
+        (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
-          (if default-value
-              (format "%s (default %s): " prompt
-                      (query-replace-descr default-value))
-            (format "%s: " prompt))
-          nil nil nil 'regexp-history defaults t)))
+        (input (read-from-minibuffer
+                (cond ((string-match-p ":[ \t]*\\'" prompt)
+                       prompt)
+                      (default
+                        (format "%s (default %s): " prompt
+                                (query-replace-descr default)))
+                      (t
+                       (format "%s: " prompt)))
+                nil nil nil (or history 'regexp-history) suggestions t)))
     (if (equal input "")
-       (or default-value 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 'regexp-history input)))))
+       (add-to-history (or history 'regexp-history) input)))))
 
 
 (defalias 'delete-non-matching-lines 'keep-lines)
@@ -763,45 +826,47 @@ a previously found match."
 \f
 (defvar occur-menu-map
   (let ((map (make-sparse-keymap)))
-    (define-key map [next-error-follow-minor-mode]
-      `(menu-item ,(purecopy "Auto Occurrence Display")
+    (bindings--define-key map [next-error-follow-minor-mode]
+      '(menu-item "Auto Occurrence Display"
                  next-error-follow-minor-mode
-                 :help ,(purecopy
-                         "Display another occurrence when moving the cursor")
+                 :help "Display another occurrence when moving the cursor"
                  :button (:toggle . (and (boundp 'next-error-follow-minor-mode)
                                          next-error-follow-minor-mode))))
-    (define-key map [separator-1] menu-bar-separator)
-    (define-key map [kill-this-buffer]
-      `(menu-item ,(purecopy "Kill Occur Buffer") kill-this-buffer
-                 :help ,(purecopy "Kill the current *Occur* buffer")))
-    (define-key map [quit-window]
-      `(menu-item ,(purecopy "Quit Occur Window") quit-window
-                 :help ,(purecopy "Quit the current *Occur* buffer.  Bury it, and maybe delete the selected frame")))
-    (define-key map [revert-buffer]
-      `(menu-item ,(purecopy "Revert Occur Buffer") revert-buffer
-                 :help ,(purecopy "Replace the text in the *Occur* buffer with the results of rerunning occur")))
-    (define-key map [clone-buffer]
-      `(menu-item ,(purecopy "Clone Occur Buffer") clone-buffer
-                 :help ,(purecopy "Create and return a twin copy of the current *Occur* buffer")))
-    (define-key map [occur-rename-buffer]
-      `(menu-item ,(purecopy "Rename Occur Buffer") occur-rename-buffer
-                 :help ,(purecopy "Rename the current *Occur* buffer to *Occur: original-buffer-name*.")))
-    (define-key map [separator-2] menu-bar-separator)
-    (define-key map [occur-mode-goto-occurrence-other-window]
-      `(menu-item ,(purecopy "Go To Occurrence Other Window") occur-mode-goto-occurrence-other-window
-                 :help ,(purecopy "Go to the occurrence the current line describes, in another window")))
-    (define-key map [occur-mode-goto-occurrence]
-      `(menu-item ,(purecopy "Go To Occurrence") occur-mode-goto-occurrence
-                 :help ,(purecopy "Go to the occurrence the current line describes")))
-    (define-key map [occur-mode-display-occurrence]
-      `(menu-item ,(purecopy "Display Occurrence") occur-mode-display-occurrence
-                 :help ,(purecopy "Display in another window the occurrence the current line describes")))
-    (define-key map [occur-next]
-      `(menu-item ,(purecopy "Move to Next Match") occur-next
-                 :help ,(purecopy "Move to the Nth (default 1) next match in an Occur mode buffer")))
-    (define-key map [occur-prev]
-      `(menu-item ,(purecopy "Move to Previous Match") occur-prev
-                 :help ,(purecopy "Move to the Nth (default 1) previous match in an Occur mode buffer")))
+    (bindings--define-key map [separator-1] menu-bar-separator)
+    (bindings--define-key map [kill-this-buffer]
+      '(menu-item "Kill Occur Buffer" kill-this-buffer
+                 :help "Kill the current *Occur* buffer"))
+    (bindings--define-key map [quit-window]
+      '(menu-item "Quit Occur Window" quit-window
+                 :help "Quit the current *Occur* buffer.  Bury it, and maybe delete the selected frame"))
+    (bindings--define-key map [revert-buffer]
+      '(menu-item "Revert Occur Buffer" revert-buffer
+                 :help "Replace the text in the *Occur* buffer with the results of rerunning occur"))
+    (bindings--define-key map [clone-buffer]
+      '(menu-item "Clone Occur Buffer" clone-buffer
+                 :help "Create and return a twin copy of the current *Occur* buffer"))
+    (bindings--define-key map [occur-rename-buffer]
+      '(menu-item "Rename Occur Buffer" occur-rename-buffer
+                 :help "Rename the current *Occur* buffer to *Occur: original-buffer-name*."))
+    (bindings--define-key map [occur-edit-buffer]
+      '(menu-item "Edit Occur Buffer" occur-edit-mode
+                 :help "Edit the *Occur* buffer and apply changes to the original buffers."))
+    (bindings--define-key map [separator-2] menu-bar-separator)
+    (bindings--define-key map [occur-mode-goto-occurrence-other-window]
+      '(menu-item "Go To Occurrence Other Window" occur-mode-goto-occurrence-other-window
+                 :help "Go to the occurrence the current line describes, in another window"))
+    (bindings--define-key map [occur-mode-goto-occurrence]
+      '(menu-item "Go To Occurrence" occur-mode-goto-occurrence
+                 :help "Go to the occurrence the current line describes"))
+    (bindings--define-key map [occur-mode-display-occurrence]
+      '(menu-item "Display Occurrence" occur-mode-display-occurrence
+                 :help "Display in another window the occurrence the current line describes"))
+    (bindings--define-key map [occur-next]
+      '(menu-item "Move to Next Match" occur-next
+                 :help "Move to the Nth (default 1) next match in an Occur mode buffer"))
+    (bindings--define-key map [occur-prev]
+      '(menu-item "Move to Previous Match" occur-prev
+                 :help "Move to the Nth (default 1) previous match in an Occur mode buffer"))
     map)
   "Menu keymap for `occur-mode'.")
 
@@ -810,7 +875,7 @@ a previously found match."
     ;; We use this alternative name, so we can use \\[occur-mode-mouse-goto].
     (define-key map [mouse-2] 'occur-mode-mouse-goto)
     (define-key map "\C-c\C-c" 'occur-mode-goto-occurrence)
-    (define-key map "\C-x\C-q" 'occur-edit-mode)
+    (define-key map "e" 'occur-edit-mode)
     (define-key map "\C-m" 'occur-mode-goto-occurrence)
     (define-key map "o" 'occur-mode-goto-occurrence-other-window)
     (define-key map "\C-o" 'occur-mode-display-occurrence)
@@ -819,13 +884,15 @@ a previously found match."
     (define-key map "r" 'occur-rename-buffer)
     (define-key map "c" 'clone-buffer)
     (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
-    (define-key map [menu-bar occur] (cons (purecopy "Occur") occur-menu-map))
+    (bindings--define-key map [menu-bar occur] (cons "Occur" occur-menu-map))
     map)
   "Keymap for `occur-mode'.")
 
 (defvar occur-revert-arguments nil
   "Arguments to pass to `occur-1' to revert an Occur mode buffer.
 See `occur-revert-function'.")
+(make-variable-buffer-local 'occur-revert-arguments)
+(put 'occur-revert-arguments 'permanent-local t)
 
 (defcustom occur-mode-hook '(turn-on-font-lock)
   "Hook run when entering Occur mode."
@@ -853,8 +920,6 @@ Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
 
 \\{occur-mode-map}"
   (set (make-local-variable 'revert-buffer-function) 'occur-revert-function)
-  (make-local-variable 'occur-revert-arguments)
-  (add-hook 'change-major-mode-hook 'font-lock-defontify nil t)
   (setq next-error-function 'occur-next-error))
 
 \f
@@ -864,10 +929,10 @@ Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
   (let ((map (make-sparse-keymap)))
     (set-keymap-parent map text-mode-map)
     (define-key map [mouse-2] 'occur-mode-mouse-goto)
-    (define-key map "\C-c\C-c" 'occur-mode-goto-occurrence)
-    (define-key map "\C-x\C-q" 'occur-mode)
+    (define-key map "\C-c\C-c" 'occur-cease-edit)
+    (define-key map "\C-o" 'occur-mode-display-occurrence)
     (define-key map "\C-c\C-f" 'next-error-follow-minor-mode)
-    (define-key map [menu-bar occur] (cons (purecopy "Occur") occur-menu-map))
+    (bindings--define-key map [menu-bar occur] (cons "Occur" occur-menu-map))
     map)
   "Keymap for `occur-edit-mode'.")
 
@@ -876,42 +941,58 @@ Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
 In this mode, changes to the *Occur* buffer are also applied to
 the originating buffer.
 
-To return to ordinary Occur mode, use \\[occur-mode]."
+To return to ordinary Occur mode, use \\[occur-cease-edit]."
   (setq buffer-read-only nil)
-  (add-hook 'after-change-functions 'occur-after-change-function nil t))
+  (add-hook 'after-change-functions 'occur-after-change-function nil t)
+  (message (substitute-command-keys
+           "Editing: Type \\[occur-cease-edit] to return to Occur mode.")))
+
+(defun occur-cease-edit ()
+  "Switch from Occur Edit mode to Occur mode."
+  (interactive)
+  (when (derived-mode-p 'occur-edit-mode)
+    (occur-mode)
+    (message "Switching to Occur mode.")))
 
 (defun occur-after-change-function (beg end length)
   (save-excursion
     (goto-char beg)
-    (let* ((m (get-text-property (line-beginning-position) 'occur-target))
+    (let* ((line-beg (line-beginning-position))
+          (m (get-text-property line-beg 'occur-target))
           (buf (marker-buffer m))
-          (col (current-column)))
-      (when (= length 0)
-       ;; Apply occur-target property to inserted (e.g. yanked) text.
-       (put-text-property beg end 'occur-target m)
-       ;; Did we insert a newline?  Occur Edit mode can't create new
-       ;; Occur entries; just discard everything after the newline.
-       (save-excursion
-         (and (search-forward "\n" end t)
-              (delete-region (1- (point)) end))))
-      (let ((line (- (line-number-at-pos)
-                    (line-number-at-pos (window-start))))
-           (readonly (with-current-buffer buf buffer-read-only))
-           (win (or (get-buffer-window buf)
-                    (display-buffer buf t)))
-           (text (save-excursion
-                   (forward-line 0)
-                   (search-forward ":" nil t)
-                   (setq col (- col (current-column)))
-                   (buffer-substring-no-properties (point) (line-end-position)))))
-       (with-selected-window win
-         (goto-char m)
-         (recenter line)
-         (if readonly
-             (message "Buffer `%s' is read only." buf)
-           (delete-region (line-beginning-position) (line-end-position))
-           (insert text))
-         (move-to-column col))))))
+          col)
+      (when (and (get-text-property line-beg 'occur-prefix)
+                (not (get-text-property end 'occur-prefix)))
+       (when (= length 0)
+         ;; Apply occur-target property to inserted (e.g. yanked) text.
+         (put-text-property beg end 'occur-target m)
+         ;; Did we insert a newline?  Occur Edit mode can't create new
+         ;; Occur entries; just discard everything after the newline.
+         (save-excursion
+           (and (search-forward "\n" end t)
+                (delete-region (1- (point)) end))))
+       (let* ((line (- (line-number-at-pos)
+                       (line-number-at-pos (window-start))))
+              (readonly (with-current-buffer buf buffer-read-only))
+              (win (or (get-buffer-window buf)
+                       (display-buffer buf
+                                       '(nil (inhibit-same-window . t)
+                                             (inhibit-switch-frame . t)))))
+              (line-end (line-end-position))
+              (text (save-excursion
+                      (goto-char (next-single-property-change
+                                  line-beg 'occur-prefix nil
+                                  line-end))
+                      (setq col (- (point) line-beg))
+                      (buffer-substring-no-properties (point) line-end))))
+         (with-selected-window win
+           (goto-char m)
+           (recenter line)
+           (if readonly
+               (message "Buffer `%s' is read only." buf)
+             (delete-region (line-beginning-position) (line-end-position))
+             (insert text))
+           (move-to-column col)))))))
 
 \f
 (defun occur-revert-function (_ignore1 _ignore2)
@@ -928,7 +1009,7 @@ To return to ordinary Occur mode, use \\[occur-mode]."
 
 (defalias 'occur-mode-mouse-goto 'occur-mode-goto-occurrence)
 (defun occur-mode-goto-occurrence (&optional event)
-  "Go to the occurrence the current line describes."
+  "Go to the occurrence on the current line."
   (interactive (list last-nonmenu-event))
   (let ((pos
          (if (null event)
@@ -939,9 +1020,7 @@ To return to ordinary Occur mode, use \\[occur-mode]."
            (with-current-buffer (window-buffer (posn-window (event-end event)))
              (save-excursion
                (goto-char (posn-point (event-end event)))
-               (occur-mode-find-occurrence)))))
-        same-window-buffer-names
-        same-window-regexps)
+               (occur-mode-find-occurrence))))))
     (pop-to-buffer (marker-buffer pos))
     (goto-char pos)
     (run-hooks 'occur-mode-find-occurrence-hook)))
@@ -958,11 +1037,8 @@ To return to ordinary Occur mode, use \\[occur-mode]."
   "Display in another window the occurrence the current line describes."
   (interactive)
   (let ((pos (occur-mode-find-occurrence))
-       window
-       ;; Bind these to ensure `display-buffer' puts it in another window.
-       same-window-buffer-names
-       same-window-regexps)
-    (setq window (display-buffer (marker-buffer pos)))
+       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)
@@ -1081,9 +1157,9 @@ which means to discard all text properties."
                  "\\&"
                ;; Get the regexp for collection pattern.
                (let ((default (car occur-collect-regexp-history)))
-                 (read-string
+                 (read-regexp
                   (format "Regexp to collect (default %s): " default)
-                  nil 'occur-collect-regexp-history default)))
+                  default 'occur-collect-regexp-history)))
            ;; Otherwise normal occur takes numerical prefix argument.
            (when current-prefix-arg
              (prefix-numeric-value current-prefix-arg))))))
@@ -1129,8 +1205,8 @@ contain \\& and \\N which convention follows `replace-match'.
 For example, providing \"defun\\s +\\(\\S +\\)\" for REGEXP and
 \"\\1\" for NLINES collects all the function names in a lisp
 program.  When there is no parenthesized subexpressions in REGEXP
-the entire match is collected.  In any case the searched buffers
-are not modified."
+the entire match is collected.  In any case the searched buffer
+is not modified."
   (interactive (occur-read-primary-args))
   (occur-1 regexp nlines (list (current-buffer))))
 
@@ -1170,14 +1246,10 @@ See also `multi-occur'."
    (cons
     (let* ((default (car regexp-history))
           (input
-           (read-from-minibuffer
+           (read-regexp
             (if current-prefix-arg
                 "List lines in buffers whose names match regexp: "
-              "List lines in buffers whose filenames match regexp: ")
-            nil
-            nil
-            nil
-            'regexp-history)))
+              "List lines in buffers whose filenames match regexp: "))))
       (if (equal input "")
          default
        input))
@@ -1216,7 +1288,7 @@ See also `multi-occur'."
 
     (with-current-buffer occur-buf
       (if (stringp nlines)
-         (fundamental-mode) ;; This is for collect opeartion.
+         (fundamental-mode) ;; This is for collect operation.
        (occur-mode))
       (let ((inhibit-read-only t)
            ;; Don't generate undo entries for creation of the initial contents.
@@ -1341,9 +1413,12 @@ See also `multi-occur'."
                                    (when prefix-face
                                      `(font-lock-face prefix-face))
                                    `(occur-prefix t mouse-face (highlight)
-                                                  occur-target ,marker follow-link t
-                                                  read-only t
-                                                  help-echo "mouse-2: go to this occurrence"))))
+                                     ;; Allow insertion of text at
+                                     ;; the end of the prefix (for
+                                     ;; Occur Edit mode).
+                                     front-sticky 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,
                            ;; because that loses.  And don't put it
@@ -1540,9 +1615,13 @@ Comma to replace but not move point immediately,
 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
@@ -1573,14 +1652,28 @@ E to edit the replacement string"
     (define-key map "?" 'help)
     (define-key map "\C-g" 'quit)
     (define-key map "\C-]" 'quit)
-    (define-key map "\e" 'exit-prefix)
+    (define-key map "\C-v" 'scroll-up)
+    (define-key map "\M-v" 'scroll-down)
+    (define-key map [next] 'scroll-up)
+    (define-key map [prior] 'scroll-down)
+    (define-key map [?\C-\M-v] 'scroll-other-window)
+    (define-key map [M-next] 'scroll-other-window)
+    (define-key map [?\C-\M-\S-v] 'scroll-other-window-down)
+    (define-key map [M-prior] 'scroll-other-window-down)
+    ;; Binding ESC would prohibit the M-v binding.  Instead, callers
+    ;; should check for ESC specially.
+    ;; (define-key map "\e" 'exit-prefix)
     (define-key map [escape] 'exit-prefix)
     map)
-  "Keymap that defines the responses to questions in `query-replace'.
+  "Keymap of responses to questions posed by commands like `query-replace'.
 The \"bindings\" in this map are not commands; they are answers.
 The valid answers include `act', `skip', `act-and-show',
-`exit', `act-and-exit', `edit', `delete-and-edit', `recenter',
-`automatic', `backup', `exit-prefix', and `help'.")
+`act-and-exit', `exit', `exit-prefix', `recenter', `scroll-up',
+`scroll-down', `scroll-other-window', `scroll-other-window-down',
+`edit', `edit-replacement', `delete-and-edit', `automatic',
+`backup', `quit', and `help'.
+
+This keymap is used by `y-or-n-p' as well as `query-replace'.")
 
 (defvar multi-query-replace-map
   (let ((map (make-sparse-keymap)))
@@ -1651,7 +1744,7 @@ with the `noescape' argument set.
                              t t)))
 
 (defun replace-loop-through-replacements (data count)
-  ;; DATA is a vector contaning the following values:
+  ;; DATA is a vector containing the following values:
   ;;   0 next-rotate-count
   ;;   1 repeat-count
   ;;   2 next-replacement
@@ -1701,12 +1794,12 @@ passed in.  If LITERAL is set, no checking is done, anyway."
   (replace-match newtext fixedcase literal)
   noedit)
 
-(defvar replace-search-function 'search-forward
+(defvar replace-search-function nil
   "Function to use when searching for strings to replace.
 It is used by `query-replace' and `replace-string', and is called
 with three arguments, as if it were `search-forward'.")
 
-(defvar replace-re-search-function 're-search-forward
+(defvar replace-re-search-function nil
   "Function to use when searching for regexps to replace.
 It is used by `query-replace-regexp', `replace-regexp',
 `query-replace-regexp-eval', and `map-query-replace-regexp'.
@@ -1738,10 +1831,6 @@ make, or the user didn't cancel the call."
            case-fold-search))
          (nocasify (not (and case-replace case-fold-search)))
          (literal (or (not regexp-flag) (eq regexp-flag 'literal)))
-         (search-function
-         (if regexp-flag
-             replace-re-search-function
-           replace-search-function))
          (search-string from-string)
          (real-match-data nil)       ; The match data for the current match.
          (next-replacement nil)
@@ -1795,12 +1884,6 @@ make, or the user didn't cancel the call."
                                (vector repeat-count repeat-count
                                        replacements replacements)))))
 
-    (if delimited-flag
-       (setq search-function 're-search-forward
-             search-string (concat "\\b"
-                                   (if regexp-flag from-string
-                                     (regexp-quote from-string))
-                                   "\\b")))
     (when query-replace-lazy-highlight
       (setq isearch-lazy-highlight-last-string nil))
 
@@ -1810,39 +1893,62 @@ make, or the user didn't cancel the call."
        ;; 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.
@@ -1882,7 +1988,7 @@ make, or the user didn't cancel the call."
                    (replace-highlight
                     (nth 0 real-match-data) (nth 1 real-match-data)
                     start end search-string
-                    (or delimited-flag regexp-flag) case-fold-search))
+                    regexp-flag delimited-flag case-fold-search))
                  (setq noedit
                        (replace-match-maybe-edit
                         next-replacement nocasify literal
@@ -1901,7 +2007,7 @@ make, or the user didn't cancel the call."
                  (replace-highlight
                   (match-beginning 0) (match-end 0)
                   start end search-string
-                  (or delimited-flag regexp-flag) case-fold-search)
+                  regexp-flag delimited-flag case-fold-search)
                  ;; Bind message-log-max so we don't fill up the message log
                  ;; with a bunch of identical messages.
                  (let ((message-log-max nil)
@@ -2083,15 +2189,11 @@ make, or the user didn't cancel the call."
                 (if (= replace-count 1) "" "s")))
     (or (and keep-going stack) multi-buffer)))
 
-(defvar isearch-error)
-(defvar isearch-forward)
-(defvar isearch-case-fold-search)
-(defvar isearch-string)
-
 (defvar replace-overlay nil)
 
 (defun replace-highlight (match-beg match-end range-beg range-end
-                         string regexp case-fold)
+                         search-string regexp-flag delimited-flag
+                         case-fold-search)
   (if query-replace-highlight
       (if replace-overlay
          (move-overlay replace-overlay match-beg match-end (current-buffer))
@@ -2099,15 +2201,17 @@ make, or the user didn't cancel the call."
        (overlay-put replace-overlay 'priority 1001) ;higher than lazy overlays
        (overlay-put replace-overlay 'face 'query-replace)))
   (if query-replace-lazy-highlight
-      (let ((isearch-string string)
-           (isearch-regexp regexp)
-           (search-whitespace-regexp nil)
-           (isearch-case-fold-search case-fold)
+      (let ((isearch-string search-string)
+           (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-other-end match-beg)
            (isearch-error nil))
-       ;; Set isearch-word to nil because word-replace is regexp-based,
-       ;; so `isearch-search-fun' should not use `word-search-forward'.
-       (if (and isearch-word isearch-regexp) (setq isearch-word nil))
        (isearch-lazy-highlight-new-loop range-beg range-end))))
 
 (defun replace-dehighlight ()