summaryrefslogtreecommitdiff
path: root/lisp/replace.el
diff options
context:
space:
mode:
Diffstat (limited to 'lisp/replace.el')
-rw-r--r--lisp/replace.el153
1 files changed, 103 insertions, 50 deletions
diff --git a/lisp/replace.el b/lisp/replace.el
index 09bdf28dbce..5287be2c524 100644
--- a/lisp/replace.el
+++ b/lisp/replace.el
@@ -63,7 +63,7 @@ it will match any sequence matched by the regexp `search-whitespace-regexp'."
:version "24.3")
(defvar query-replace-history nil
- "Default history list for query-replace commands.
+ "Default history list for `query-replace' commands.
See `query-replace-from-history-variable' and
`query-replace-to-history-variable'.")
@@ -83,7 +83,7 @@ from Isearch by using a key sequence like `C-s C-s M-%'." "24.3")
(defcustom query-replace-from-to-separator " → "
"String that separates FROM and TO in the history of replacement pairs.
When nil, the pair will not be added to the history (same behavior
-as in emacs 24.5)."
+as in Emacs 24.5)."
:group 'matching
:type '(choice
(const :tag "Disabled" nil)
@@ -202,7 +202,7 @@ by this function to the end of values available via
(car (symbol-value query-replace-from-history-variable)))))
(defun query-replace-read-from (prompt regexp-flag)
- "Query and return the `from' argument of a query-replace operation.
+ "Query and return the `from' argument of a `query-replace' operation.
Prompt with PROMPT. REGEXP-FLAG non-nil means the response should be a regexp.
The return value can also be a pair (FROM . TO) indicating that the user
wants to replace FROM with TO."
@@ -213,7 +213,7 @@ wants to replace FROM with TO."
(when query-replace-from-to-separator
;; Check if the first non-whitespace char is displayable
(if (char-displayable-p
- (string-to-char (replace-regexp-in-string
+ (string-to-char (string-replace
" " "" query-replace-from-to-separator)))
query-replace-from-to-separator
" -> ")))
@@ -310,7 +310,7 @@ the original string if not."
;; but not after (quote foo).
(and (eq (car-safe (car pos)) 'quote)
(not (= ?\( (aref to 0)))))
- (eq (string-match " " to (cdr pos))
+ (eq (string-search " " to (cdr pos))
(cdr pos)))
(1+ (cdr pos))
(cdr pos))))
@@ -326,8 +326,9 @@ the original string if not."
(defun query-replace-read-to (from prompt regexp-flag)
- "Query and return the `to' argument of a query-replace operation.
-Prompt with PROMPT. REGEXP-FLAG non-nil means the response should a regexp."
+ "Query and return the `to' argument of a `query-replace' operation.
+Prompt with PROMPT. REGEXP-FLAG non-nil means the response
+should a regexp."
(query-replace-compile-replacement
(save-excursion
(let* ((history-add-new-input nil)
@@ -633,13 +634,13 @@ Arguments REGEXP, START, END, and REGION-NONCONTIGUOUS-P are passed to
(if (listp to-strings)
(setq replacements to-strings)
(while (/= (length to-strings) 0)
- (if (string-match " " to-strings)
+ (if (string-search " " to-strings)
(setq replacements
(append replacements
(list (substring to-strings 0
- (string-match " " to-strings))))
+ (string-search " " to-strings))))
to-strings (substring to-strings
- (1+ (string-match " " to-strings))))
+ (1+ (string-search " " to-strings))))
(setq replacements (append replacements (list to-strings))
to-strings ""))))
(perform-replace regexp replacements t t nil n nil start end nil region-noncontiguous-p)))
@@ -796,7 +797,7 @@ of `history-length', which see.")
"Overlays used to temporarily highlight occur matches.")
(defvar occur-collect-regexp-history '("\\1")
- "History of regexp for occur's collect operation")
+ "History of regexp for occur's collect operation.")
(defcustom read-regexp-defaults-function nil
"Function that provides default regexp(s) for `read-regexp'.
@@ -1300,7 +1301,7 @@ See `occur-revert-function'.")
(defcustom occur-mode-find-occurrence-hook nil
"Hook run by Occur after locating an occurrence.
This will be called with the cursor position at the occurrence. An application
-for this is to reveal context in an outline-mode when the occurrence is hidden."
+for this is to reveal context in an outline mode when the occurrence is hidden."
:type 'hook
:group 'matching)
@@ -1407,9 +1408,9 @@ To return to ordinary Occur mode, use \\[occur-cease-edit]."
(common-prefix
(lambda (s1 s2)
(let ((c (compare-strings s1 nil nil s2 nil nil)))
- (if (zerop c)
- (length s1)
- (1- (abs c))))))
+ (if (numberp c)
+ (1- (abs c))
+ (length s1)))))
(prefix-len (funcall common-prefix buf-str text))
(suffix-len (funcall common-prefix
(reverse buf-str) (reverse text))))
@@ -1426,6 +1427,11 @@ To return to ordinary Occur mode, use \\[occur-cease-edit]."
"Handle `revert-buffer' for Occur mode buffers."
(apply #'occur-1 (append occur-revert-arguments (list (buffer-name)))))
+;; Retained for compatibility.
+(defun occur-mode-find-occurrence ()
+ "Return a marker to the first match of the line at point."
+ (occur--targets-start (occur-mode--find-occurrences)))
+
(defun occur-mode--find-occurrences ()
;; The `occur-target' property value is a list of (BEG . END) for each
;; match on the line, or (for compatibility) a single marker to the start
@@ -1438,6 +1444,18 @@ To return to ordinary Occur mode, use \\[occur-cease-edit]."
(error "Buffer for this occurrence was killed"))
targets))
+(defun occur--set-arrow ()
+ "Set the overlay arrow at the first line of the occur match at point."
+ (save-excursion
+ (let ((target (get-text-property (point) 'occur-target))
+ ;; Find the start of the occur match, in case it's multi-line.
+ (prev (previous-single-property-change (point) 'occur-target)))
+ (when (and prev (eq (get-text-property prev 'occur-target) target))
+ (goto-char prev))
+ (setq overlay-arrow-position
+ (set-marker (or overlay-arrow-position (make-marker))
+ (line-beginning-position))))))
+
(defalias 'occur-mode-mouse-goto 'occur-mode-goto-occurrence)
(defun occur-mode-goto-occurrence (&optional event)
"Go to the occurrence specified by EVENT, a mouse click.
@@ -1455,6 +1473,7 @@ If not invoked by a mouse click, go to occurrence on the current line."
(goto-char (posn-point (event-end event)))
(occur-mode--find-occurrences)))))
(pos (occur--targets-start targets)))
+ (occur--set-arrow)
(pop-to-buffer (marker-buffer pos))
(goto-char pos)
(occur--highlight-occurrences targets)
@@ -1466,6 +1485,7 @@ If not invoked by a mouse click, go to occurrence on the current line."
(interactive)
(let ((buffer (current-buffer))
(pos (occur--targets-start (occur-mode--find-occurrences))))
+ (occur--set-arrow)
(switch-to-buffer-other-window (marker-buffer pos))
(goto-char pos)
(next-error-found buffer (current-buffer))
@@ -1525,6 +1545,7 @@ If not invoked by a mouse click, go to occurrence on the current line."
'(nil (inhibit-same-window . t)))
window)
(setq window (display-buffer (marker-buffer pos) t))
+ (occur--set-arrow)
;; This is the way to set point in the proper window.
(save-selected-window
(select-window window)
@@ -1740,7 +1761,7 @@ If REGEXP contains upper case characters (excluding those preceded by `\\')
and `search-upper-case' is non-nil, the matching is case-sensitive.
When NLINES is a string or when the function is called
-interactively with prefix argument without a number (`C-u' alone
+interactively with prefix argument without a number (\\[universal-argument] alone
as prefix) the matching strings are collected into the `*Occur*'
buffer by using NLINES as a replacement regexp. NLINES may
contain \\& and \\N which convention follows `replace-match'.
@@ -1878,6 +1899,7 @@ See also `multi-occur'."
;; Make the default-directory of the *Occur* buffer match that of
;; the buffer where the occurrences come from
(setq default-directory source-buffer-default-directory)
+ (setq overlay-arrow-position nil)
(if (stringp nlines)
(fundamental-mode) ;; This is for collect operation.
(occur-mode))
@@ -2080,12 +2102,14 @@ See also `multi-occur'."
;; Add non-numeric prefix to all non-first lines
;; of multi-line matches.
(concat
- (replace-regexp-in-string
+ (string-replace
"\n"
(if prefix-face
(propertize
- "\n :" 'font-lock-face prefix-face)
- "\n :")
+ "\n :" 'font-lock-face prefix-face
+ 'occur-target markers)
+ (propertize
+ "\n :" 'occur-target markers))
;; Add mouse face in one section to
;; ensure the prefix and the string
;; get a contiguous highlight.
@@ -2239,11 +2263,11 @@ See also `multi-occur'."
(defun occur-engine-add-prefix (lines &optional prefix-face)
(mapcar
- #'(lambda (line)
- (concat (if prefix-face
- (propertize " :" 'font-lock-face prefix-face)
- " :")
- line "\n"))
+ (lambda (line)
+ (concat (if prefix-face
+ (propertize " :" 'font-lock-face prefix-face)
+ " :")
+ line "\n"))
lines))
(defun occur-accumulate-lines (count &optional keep-props pt)
@@ -2344,6 +2368,36 @@ See also `multi-occur'."
;; And the second element is the list of context after-lines.
(if (> nlines 0) after-lines))))
+(defun occur-word-at-mouse (event)
+ "Display an occur buffer for the word at EVENT."
+ (interactive "e")
+ (let ((word (thing-at-mouse event 'word t)))
+ (occur (concat "\\<" (regexp-quote word) "\\>"))))
+
+(defun occur-symbol-at-mouse (event)
+ "Display an occur buffer for the symbol at EVENT."
+ (interactive "e")
+ (let ((symbol (thing-at-mouse event 'symbol t)))
+ (occur (concat "\\_<" (regexp-quote symbol) "\\_>"))))
+
+(defun occur-context-menu (menu click)
+ "Populate MENU with occur commands at CLICK.
+To be added to `context-menu-functions'."
+ (let ((word (thing-at-mouse click 'word))
+ (sym (thing-at-mouse click 'symbol)))
+ (when (or word sym)
+ (define-key-after menu [occur-separator] menu-bar-separator
+ 'middle-separator)
+ (when sym
+ (define-key-after menu [occur-symbol-at-mouse]
+ '(menu-item "Occur Symbol" occur-symbol-at-mouse)
+ 'occur-separator))
+ (when word
+ (define-key-after menu [occur-word-at-mouse]
+ '(menu-item "Occur Word" occur-word-at-mouse)
+ 'occur-separator))))
+ menu)
+
;; It would be nice to use \\[...], but there is no reasonable way
;; to make that display both SPC and Y.
@@ -2483,12 +2537,10 @@ a string, it is first passed through `prin1-to-string'
with the `noescape' argument set.
`match-data' is preserved across the call."
- (save-match-data
- (replace-regexp-in-string "\\\\" "\\\\"
- (if (stringp replacement)
- replacement
- (prin1-to-string replacement t))
- t t)))
+ (string-replace "\\" "\\\\"
+ (if (stringp replacement)
+ replacement
+ (prin1-to-string replacement t))))
(defun replace-loop-through-replacements (data count)
;; DATA is a vector containing the following values:
@@ -2555,7 +2607,7 @@ passed in. If LITERAL is set, no checking is done, anyway."
noedit)
(defvar replace-update-post-hook nil
- "Function(s) to call after query-replace has found a match in the buffer.")
+ "Function(s) to call after `query-replace' has found a match in the buffer.")
(defvar replace-search-function nil
"Function to use when searching for strings to replace.
@@ -2744,9 +2796,7 @@ characters."
;; If non-nil, it is marker saying where in the buffer to stop.
(limit nil)
- ;; Use local binding in add-function below.
- (isearch-filter-predicate isearch-filter-predicate)
- (region-bounds nil)
+ (region-filter nil)
;; Data for the next match. If a cons, it has the same format as
;; (match-data); otherwise it is t if a match is possible at point.
@@ -2770,21 +2820,22 @@ characters."
;; Unless a single contiguous chunk is selected, operate on multiple chunks.
(when region-noncontiguous-p
- (setq region-bounds
- (mapcar (lambda (position)
- (cons (copy-marker (car position))
- (copy-marker (cdr position))))
- (funcall region-extract-function 'bounds)))
- (add-function :after-while isearch-filter-predicate
- (lambda (start end)
- (delq nil (mapcar
- (lambda (bounds)
- (and
- (>= start (car bounds))
- (<= start (cdr bounds))
- (>= end (car bounds))
- (<= end (cdr bounds))))
- region-bounds)))))
+ (let ((region-bounds
+ (mapcar (lambda (position)
+ (cons (copy-marker (car position))
+ (copy-marker (cdr position))))
+ (funcall region-extract-function 'bounds))))
+ (setq region-filter
+ (lambda (start end)
+ (delq nil (mapcar
+ (lambda (bounds)
+ (and
+ (>= start (car bounds))
+ (<= start (cdr bounds))
+ (>= end (car bounds))
+ (<= end (cdr bounds))))
+ region-bounds))))
+ (add-function :after-while isearch-filter-predicate region-filter)))
;; If region is active, in Transient Mark mode, operate on region.
(if backward
@@ -3217,7 +3268,9 @@ characters."
(setq next-replacement-replaced nil
search-string-replaced nil
last-was-act-and-show nil))))))
- (replace-dehighlight))
+ (replace-dehighlight)
+ (when region-filter
+ (remove-function isearch-filter-predicate region-filter)))
(or unread-command-events
(message (ngettext "Replaced %d occurrence%s"
"Replaced %d occurrences%s"