1 |
;;; replace.el --- replace commands for Emacs |
;;; replace.el --- replace commands for Emacs |
2 |
|
|
3 |
;; Copyright (C) 1985, 86, 87, 92, 94, 96, 1997, 2000, 2001, 2002, |
;; Copyright (C) 1985, 1986, 1987, 1992, 1994, 1996, 1997, 2000, 2001, 2002, |
4 |
;; 2003, 2004 Free Software Foundation, Inc. |
;; 2003, 2004 Free Software Foundation, Inc. |
5 |
|
|
6 |
;; Maintainer: FSF |
;; Maintainer: FSF |
7 |
|
|
36 |
|
|
37 |
(defvar query-replace-history nil) |
(defvar query-replace-history nil) |
38 |
|
|
39 |
(defcustom query-replace-interactive nil |
(defvar query-replace-interactive nil |
40 |
"Non-nil means `query-replace' uses the last search string. |
"Non-nil means `query-replace' uses the last search string. |
41 |
That becomes the \"string to replace\"." |
That becomes the \"string to replace\".") |
|
:type 'boolean |
|
|
:group 'matching) |
|
42 |
|
|
43 |
(defcustom query-replace-from-history-variable 'query-replace-history |
(defcustom query-replace-from-history-variable 'query-replace-history |
44 |
"History list to use for the FROM argument of `query-replace' commands. |
"History list to use for the FROM argument of `query-replace' commands. |
64 |
:group 'matching |
:group 'matching |
65 |
:version "21.4") |
:version "21.4") |
66 |
|
|
67 |
(defun query-replace-read-args (string regexp-flag &optional noerror) |
(defun query-replace-descr (string) |
68 |
(unless noerror |
(mapconcat 'isearch-text-char-description string "")) |
|
(barf-if-buffer-read-only)) |
|
|
(let (from to) |
|
|
(if query-replace-interactive |
|
|
(setq from (car (if regexp-flag regexp-search-ring search-ring))) |
|
|
;; 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 |
|
|
(setq from (read-from-minibuffer (format "%s: " string) |
|
|
nil nil nil |
|
|
query-replace-from-history-variable |
|
|
nil t))) |
|
|
;; Warn if user types \n or \t, but don't reject the input. |
|
|
(and regexp-flag |
|
|
(string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\[nt]\\)" from) |
|
|
(let ((match (match-string 3 from))) |
|
|
(cond |
|
|
((string= match "\\n") |
|
|
(message "Note: `\\n' here doesn't match a newline; to do that, type C-q C-j instead")) |
|
|
((string= match "\\t") |
|
|
(message "Note: `\\t' here doesn't match a tab; to do that, just type TAB"))) |
|
|
(sit-for 2)))) |
|
69 |
|
|
70 |
(save-excursion |
(defun query-replace-read-from (string regexp-flag) |
71 |
(setq to (read-from-minibuffer (format "%s %s with: " string from) |
"Query and return the `from' argument of a query-replace operation. |
72 |
nil nil nil |
The return value can also be a pair (FROM . TO) indicating that the user |
73 |
query-replace-to-history-variable from t))) |
wants to replace FROM with TO." |
74 |
|
(if query-replace-interactive |
75 |
|
(car (if regexp-flag regexp-search-ring search-ring)) |
76 |
|
(let* ((lastfrom (car (symbol-value query-replace-from-history-variable))) |
77 |
|
(lastto (car (symbol-value query-replace-to-history-variable))) |
78 |
|
(from |
79 |
|
;; The save-excursion here is in case the user marks and copies |
80 |
|
;; a region in order to specify the minibuffer input. |
81 |
|
;; That should not clobber the region for the query-replace itself. |
82 |
|
(save-excursion |
83 |
|
(when (equal lastfrom lastto) |
84 |
|
;; Typically, this is because the two histlists are shared. |
85 |
|
(setq lastfrom (cadr (symbol-value |
86 |
|
query-replace-from-history-variable)))) |
87 |
|
(read-from-minibuffer |
88 |
|
(if (and lastto lastfrom) |
89 |
|
(format "%s (default %s -> %s): " string |
90 |
|
(query-replace-descr lastfrom) |
91 |
|
(query-replace-descr lastto)) |
92 |
|
(format "%s: " string)) |
93 |
|
nil nil nil |
94 |
|
query-replace-from-history-variable |
95 |
|
nil t)))) |
96 |
|
(if (and (zerop (length from)) lastto lastfrom) |
97 |
|
(cons lastfrom lastto) |
98 |
|
;; Warn if user types \n or \t, but don't reject the input. |
99 |
|
(and regexp-flag |
100 |
|
(string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\[nt]\\)" from) |
101 |
|
(let ((match (match-string 3 from))) |
102 |
|
(cond |
103 |
|
((string= match "\\n") |
104 |
|
(message "Note: `\\n' here doesn't match a newline; to do that, type C-q C-j instead")) |
105 |
|
((string= match "\\t") |
106 |
|
(message "Note: `\\t' here doesn't match a tab; to do that, just type TAB"))) |
107 |
|
(sit-for 2))) |
108 |
|
from)))) |
109 |
|
|
110 |
|
(defun query-replace-read-to (from string regexp-flag) |
111 |
|
"Query and return the `from' argument of a query-replace operation." |
112 |
|
(let ((to (save-excursion |
113 |
|
(read-from-minibuffer |
114 |
|
(format "%s %s with: " string (query-replace-descr from)) |
115 |
|
nil nil nil |
116 |
|
query-replace-to-history-variable from t)))) |
117 |
(when (and regexp-flag |
(when (and regexp-flag |
118 |
(string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to)) |
(string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to)) |
119 |
(let (pos list char) |
(let (pos list char) |
128 |
((eq char ?\,) |
((eq char ?\,) |
129 |
(setq pos (read-from-string to)) |
(setq pos (read-from-string to)) |
130 |
(push `(replace-quote ,(car pos)) list) |
(push `(replace-quote ,(car pos)) list) |
131 |
(setq to (substring |
(let ((end |
132 |
to (+ (cdr pos) |
;; Swallow a space after a symbol |
133 |
;; Swallow a space after a symbol |
;; if there is a space. |
134 |
;; if there is a space. |
(if (and (or (symbolp (car pos)) |
135 |
(if (string-match |
;; Swallow a space after 'foo |
136 |
"^[^])\"] " |
;; but not after (quote foo). |
137 |
(substring to (1- (cdr pos)))) |
(and (eq (car-safe (car pos)) 'quote) |
138 |
1 0)))))) |
(not (= ?\( (aref to 0))))) |
139 |
|
(eq (string-match " " to (cdr pos)) |
140 |
|
(cdr pos))) |
141 |
|
(1+ (cdr pos)) |
142 |
|
(cdr pos)))) |
143 |
|
(setq to (substring to end))))) |
144 |
(string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to))) |
(string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to))) |
145 |
(setq to (nreverse (delete "" (cons to list))))) |
(setq to (nreverse (delete "" (cons to list))))) |
146 |
(replace-match-string-symbols to) |
(replace-match-string-symbols to) |
148 |
(if (> (length to) 1) |
(if (> (length to) 1) |
149 |
(cons 'concat to) |
(cons 'concat to) |
150 |
(car to))))) |
(car to))))) |
151 |
|
to)) |
152 |
|
|
153 |
|
(defun query-replace-read-args (string regexp-flag &optional noerror) |
154 |
|
(unless noerror |
155 |
|
(barf-if-buffer-read-only)) |
156 |
|
(let* ((from (query-replace-read-from string regexp-flag)) |
157 |
|
(to (if (consp from) (prog1 (cdr from) (setq from (car from))) |
158 |
|
(query-replace-read-to from string regexp-flag)))) |
159 |
(list from to current-prefix-arg))) |
(list from to current-prefix-arg))) |
160 |
|
|
161 |
(defun query-replace (from-string to-string &optional delimited start end) |
(defun query-replace (from-string to-string &optional delimited start end) |
231 |
followed by a Lisp expression. Each |
followed by a Lisp expression. Each |
232 |
replacement evaluates that expression to compute the replacement |
replacement evaluates that expression to compute the replacement |
233 |
string. Inside of that expression, `\\&' is a string denoting the |
string. Inside of that expression, `\\&' is a string denoting the |
234 |
whole match as a sting, `\\N' for a partial match, `\\#&' and `\\#N' |
whole match as a string, `\\N' for a partial match, `\\#&' and `\\#N' |
235 |
for the whole or a partial match converted to a number with |
for the whole or a partial match converted to a number with |
236 |
`string-to-number', and `\\#' itself for the number of replacements |
`string-to-number', and `\\#' itself for the number of replacements |
237 |
done so far (starting with zero). |
done so far (starting with zero). |
287 |
only matches that are surrounded by word boundaries. |
only matches that are surrounded by word boundaries. |
288 |
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." |
289 |
(interactive |
(interactive |
290 |
(let (from to) |
(barf-if-buffer-read-only) |
291 |
(if query-replace-interactive |
(let* ((from |
292 |
(setq from (car regexp-search-ring)) |
;; Let-bind the history var to disable the "foo -> bar" default. |
293 |
(setq from (read-from-minibuffer "Query replace regexp: " |
;; Maybe we shouldn't disable this default, but for now I'll |
294 |
nil nil nil |
;; leave it off. --Stef |
295 |
query-replace-from-history-variable |
(let ((query-replace-to-history-variable nil)) |
296 |
nil t))) |
(query-replace-read-from "Query replace regexp" t))) |
297 |
(setq to (list (read-from-minibuffer |
(to (list (read-from-minibuffer |
298 |
(format "Query replace regexp %s with eval: " from) |
(format "Query replace regexp %s with eval: " |
299 |
nil nil t query-replace-to-history-variable from t))) |
(query-replace-descr from)) |
300 |
|
nil nil t query-replace-to-history-variable from t)))) |
301 |
;; We make TO a list because replace-match-string-symbols requires one, |
;; We make TO a list because replace-match-string-symbols requires one, |
302 |
;; and the user might enter a single token. |
;; and the user might enter a single token. |
303 |
(replace-match-string-symbols to) |
(replace-match-string-symbols to) |
330 |
before rotating to the next. |
before rotating to the next. |
331 |
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." |
332 |
(interactive |
(interactive |
333 |
(let (from to) |
(let* ((from (if query-replace-interactive |
|
(setq from (if query-replace-interactive |
|
334 |
(car regexp-search-ring) |
(car regexp-search-ring) |
335 |
(read-from-minibuffer "Map query replace (regexp): " |
(read-from-minibuffer "Map query replace (regexp): " |
336 |
nil nil nil |
nil nil nil |
337 |
'query-replace-history nil t))) |
'query-replace-history nil t))) |
338 |
(setq to (read-from-minibuffer |
(to (read-from-minibuffer |
339 |
(format "Query replace %s with (space-separated strings): " |
(format "Query replace %s with (space-separated strings): " |
340 |
from) |
(query-replace-descr from)) |
341 |
nil nil nil |
nil nil nil |
342 |
'query-replace-history from t)) |
'query-replace-history from t))) |
343 |
(list from to |
(list from to |
344 |
(and current-prefix-arg |
(and current-prefix-arg |
345 |
(prefix-numeric-value current-prefix-arg)) |
(prefix-numeric-value current-prefix-arg)) |
780 |
(read-from-minibuffer |
(read-from-minibuffer |
781 |
(if default |
(if default |
782 |
(format "List lines matching regexp (default `%s'): " |
(format "List lines matching regexp (default `%s'): " |
783 |
default) |
(query-replace-descr default)) |
784 |
"List lines matching regexp: ") |
"List lines matching regexp: ") |
785 |
nil |
nil |
786 |
nil |
nil |
943 |
(let ((matches 0) ;; count of matched lines |
(let ((matches 0) ;; count of matched lines |
944 |
(lines 1) ;; line count |
(lines 1) ;; line count |
945 |
(matchbeg 0) |
(matchbeg 0) |
|
(matchend 0) |
|
946 |
(origpt nil) |
(origpt nil) |
947 |
(begpt nil) |
(begpt nil) |
948 |
(endpt nil) |
(endpt nil) |
962 |
(setq origpt (point)) |
(setq origpt (point)) |
963 |
(when (setq endpt (re-search-forward regexp nil t)) |
(when (setq endpt (re-search-forward regexp nil t)) |
964 |
(setq matches (1+ matches)) ;; increment match count |
(setq matches (1+ matches)) ;; increment match count |
965 |
(setq matchbeg (match-beginning 0) |
(setq matchbeg (match-beginning 0)) |
|
matchend (match-end 0)) |
|
966 |
(setq begpt (save-excursion |
(setq begpt (save-excursion |
967 |
(goto-char matchbeg) |
(goto-char matchbeg) |
968 |
(line-beginning-position))) |
(line-beginning-position))) |
1558 |
(if (facep 'query-replace) |
(if (facep 'query-replace) |
1559 |
'query-replace 'region))))) |
'query-replace 'region))))) |
1560 |
|
|
1561 |
;;; arch-tag: 16b4cd61-fd40-497b-b86f-b667c4cf88e4 |
;; arch-tag: 16b4cd61-fd40-497b-b86f-b667c4cf88e4 |
1562 |
;;; replace.el ends here |
;;; replace.el ends here |