diff options
| author | Miles Bader | 2004-06-29 16:46:06 +0000 |
|---|---|---|
| committer | Miles Bader | 2004-06-29 16:46:06 +0000 |
| commit | 12483a9413619e286efc673a2b277d85cebf3b0c (patch) | |
| tree | d489e0fa758c0d51d792d42140cbeafa4aede31b /lisp/replace.el | |
| parent | c786a8ae1c5e84d0f0903d516dd0fc190dc1193c (diff) | |
| parent | 619b6adbd2b96accbbf18051bf69149a029557ee (diff) | |
| download | emacs-12483a9413619e286efc673a2b277d85cebf3b0c.tar.gz emacs-12483a9413619e286efc673a2b277d85cebf3b0c.zip | |
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-17
Merge from emacs--cvs-trunk--0
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-417
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-419
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-420
Tweak permissions
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-421
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-430
Update from CVS
Diffstat (limited to 'lisp/replace.el')
| -rw-r--r-- | lisp/replace.el | 318 |
1 files changed, 216 insertions, 102 deletions
diff --git a/lisp/replace.el b/lisp/replace.el index 89f55c2829e..c2305cdecc6 100644 --- a/lisp/replace.el +++ b/lisp/replace.el | |||
| @@ -95,6 +95,35 @@ strings or patterns." | |||
| 95 | (setq to (read-from-minibuffer (format "%s %s with: " string from) | 95 | (setq to (read-from-minibuffer (format "%s %s with: " string from) |
| 96 | nil nil nil | 96 | nil nil nil |
| 97 | query-replace-to-history-variable from t))) | 97 | query-replace-to-history-variable from t))) |
| 98 | (when (and regexp-flag | ||
| 99 | (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to)) | ||
| 100 | (let (pos list char) | ||
| 101 | (while | ||
| 102 | (progn | ||
| 103 | (setq pos (match-end 0)) | ||
| 104 | (push (substring to 0 (- pos 2)) list) | ||
| 105 | (setq char (aref to (1- pos)) | ||
| 106 | to (substring to pos)) | ||
| 107 | (cond ((eq char ?\#) | ||
| 108 | (push '(number-to-string replace-count) list)) | ||
| 109 | ((eq char ?\,) | ||
| 110 | (setq pos (read-from-string to)) | ||
| 111 | (push `(replace-quote ,(car pos)) list) | ||
| 112 | (setq to (substring | ||
| 113 | to (+ (cdr pos) | ||
| 114 | ;; Swallow a space after a symbol | ||
| 115 | ;; if there is a space. | ||
| 116 | (if (string-match | ||
| 117 | "^[^])\"] " | ||
| 118 | (substring to (1- (cdr pos)))) | ||
| 119 | 1 0)))))) | ||
| 120 | (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" to))) | ||
| 121 | (setq to (nreverse (delete "" (cons to list))))) | ||
| 122 | (replace-match-string-symbols to) | ||
| 123 | (setq to (cons 'replace-eval-replacement | ||
| 124 | (if (> (length to) 1) | ||
| 125 | (cons 'concat to) | ||
| 126 | (car to))))) | ||
| 98 | (list from to current-prefix-arg))) | 127 | (list from to current-prefix-arg))) |
| 99 | 128 | ||
| 100 | (defun query-replace (from-string to-string &optional delimited start end) | 129 | (defun query-replace (from-string to-string &optional delimited start end) |
| @@ -163,59 +192,35 @@ Fourth and fifth arg START and END specify the region to operate on. | |||
| 163 | In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP, | 192 | In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP, |
| 164 | and `\\=\\N' (where N is a digit) stands for | 193 | and `\\=\\N' (where N is a digit) stands for |
| 165 | whatever what matched the Nth `\\(...\\)' in REGEXP. | 194 | whatever what matched the Nth `\\(...\\)' in REGEXP. |
| 166 | 195 | `\\?' lets you edit the replacement text in the minibuffer | |
| 167 | When this function is called interactively, the replacement text | 196 | at the given position for each replacement. |
| 168 | can also contain `\\,' followed by a Lisp expression. The escaped | 197 | |
| 169 | shorthands for `query-replace-regexp-eval' are also valid | 198 | In interactive calls, the replacement text can contain `\\,' |
| 170 | here: within the Lisp expression, you can use `\\&' for the whole | 199 | followed by a Lisp expression. Each |
| 171 | match string, `\\N' for partial matches, `\\#&' and `\\#N' for | 200 | replacement evaluates that expression to compute the replacement |
| 172 | the respective numeric values, and `\\#' for `replace-count'. | 201 | string. Inside of that expression, `\\&' is a string denoting the |
| 173 | 202 | whole match as a sting, `\\N' for a partial match, `\\#&' and `\\#N' | |
| 174 | If your Lisp expression is an identifier and the next | 203 | for the whole or a partial match converted to a number with |
| 175 | letter in the replacement string would be interpreted as part of it, | 204 | `string-to-number', and `\\#' itself for the number of replacements |
| 176 | you can wrap it with an expression like `\\,(or \\#)'. Incidentally, | 205 | done so far (starting with zero). |
| 177 | for this particular case you may also enter `\\#' in the replacement | 206 | |
| 178 | text directly. | 207 | If the replacement expression is a symbol, write a space after it |
| 179 | 208 | to terminate it. One space there, if any, will be discarded. | |
| 180 | When you use `\\,' or `\\#' in the replacement, TO-STRING actually | 209 | |
| 181 | becomes a list with expanded shorthands. | 210 | When using those Lisp features interactively in the replacement |
| 182 | Use \\[repeat-complex-command] after this command to see details." | 211 | text, TO-STRING is actually made a list instead of a string. |
| 212 | Use \\[repeat-complex-command] after this command for details." | ||
| 183 | (interactive | 213 | (interactive |
| 184 | (let ((common | 214 | (let ((common |
| 185 | (query-replace-read-args "Query replace regexp" t))) | 215 | (query-replace-read-args "Query replace regexp" t))) |
| 186 | (list | 216 | (list (nth 0 common) (nth 1 common) (nth 2 common) |
| 187 | (nth 0 common) | 217 | ;; These are done separately here |
| 188 | (if (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" | 218 | ;; so that command-history will record these expressions |
| 189 | (nth 1 common)) | 219 | ;; rather than the values they had this time. |
| 190 | (let ((to-string (nth 1 common)) pos to-expr char prompt) | 220 | (if (and transient-mark-mode mark-active) |
| 191 | (while (string-match | 221 | (region-beginning)) |
| 192 | "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\\\[,#]" | 222 | (if (and transient-mark-mode mark-active) |
| 193 | to-string) | 223 | (region-end))))) |
| 194 | (setq pos (match-end 0)) | ||
| 195 | (push (substring to-string 0 (- pos 2)) to-expr) | ||
| 196 | (setq char (aref to-string (1- pos)) | ||
| 197 | to-string (substring to-string pos)) | ||
| 198 | (cond ((eq char ?\#) | ||
| 199 | (push '(number-to-string replace-count) to-expr)) | ||
| 200 | ((eq char ?\,) | ||
| 201 | (setq pos (read-from-string to-string)) | ||
| 202 | (push `(replace-quote ,(car pos)) to-expr) | ||
| 203 | (setq to-string (substring to-string (cdr pos)))))) | ||
| 204 | (setq to-expr (nreverse (delete "" (cons to-string to-expr)))) | ||
| 205 | (replace-match-string-symbols to-expr) | ||
| 206 | (cons 'replace-eval-replacement | ||
| 207 | (if (> (length to-expr) 1) | ||
| 208 | (cons 'concat to-expr) | ||
| 209 | (car to-expr)))) | ||
| 210 | (nth 1 common)) | ||
| 211 | (nth 2 common) | ||
| 212 | ;; These are done separately here | ||
| 213 | ;; so that command-history will record these expressions | ||
| 214 | ;; rather than the values they had this time. | ||
| 215 | (if (and transient-mark-mode mark-active) | ||
| 216 | (region-beginning)) | ||
| 217 | (if (and transient-mark-mode mark-active) | ||
| 218 | (region-end))))) | ||
| 219 | (perform-replace regexp to-string t t delimited nil nil start end)) | 224 | (perform-replace regexp to-string t t delimited nil nil start end)) |
| 220 | 225 | ||
| 221 | (define-key esc-map [?\C-%] 'query-replace-regexp) | 226 | (define-key esc-map [?\C-%] 'query-replace-regexp) |
| @@ -374,7 +379,27 @@ Fourth and fifth arg START and END specify the region to operate on. | |||
| 374 | 379 | ||
| 375 | In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP, | 380 | In TO-STRING, `\\&' stands for whatever matched the whole of REGEXP, |
| 376 | and `\\=\\N' (where N is a digit) stands for | 381 | and `\\=\\N' (where N is a digit) stands for |
| 377 | whatever what matched the Nth `\\(...\\)' in REGEXP. | 382 | whatever what matched the Nth `\\(...\\)' in REGEXP. |
| 383 | `\\?' lets you edit the replacement text in the minibuffer | ||
| 384 | at the given position for each replacement. | ||
| 385 | |||
| 386 | In interactive calls, the replacement text may contain `\\,' | ||
| 387 | followed by a Lisp expression used as part of the replacement | ||
| 388 | text. Inside of that expression, `\\&' is a string denoting the | ||
| 389 | whole match, `\\N' a partial matches, `\\#&' and `\\#N' the | ||
| 390 | respective numeric values from `string-to-number', and `\\#' | ||
| 391 | itself for `replace-count', the number of replacements occured so | ||
| 392 | far. | ||
| 393 | |||
| 394 | If your Lisp expression is an identifier and the next letter in | ||
| 395 | the replacement string would be interpreted as part of it, you | ||
| 396 | can wrap it with an expression like `\\,(or \\#)'. Incidentally, | ||
| 397 | for this particular case you may also enter `\\#' in the | ||
| 398 | replacement text directly. | ||
| 399 | |||
| 400 | When using those Lisp features interactively in the replacement | ||
| 401 | text, TO-STRING is actually made a list instead of a string. | ||
| 402 | Use \\[repeat-complex-command] after this command for details. | ||
| 378 | 403 | ||
| 379 | If `query-replace-interactive' is non-nil, the last incremental search | 404 | If `query-replace-interactive' is non-nil, the last incremental search |
| 380 | regexp is used as REGEXP--you don't have to specify it with the minibuffer. | 405 | regexp is used as REGEXP--you don't have to specify it with the minibuffer. |
| @@ -1115,6 +1140,49 @@ with the `noescape' argument set. | |||
| 1115 | (aset data 2 (if (consp next) next (aref data 3)))))) | 1140 | (aset data 2 (if (consp next) next (aref data 3)))))) |
| 1116 | (car (aref data 2))) | 1141 | (car (aref data 2))) |
| 1117 | 1142 | ||
| 1143 | (defun replace-match-data (integers reuse &optional new) | ||
| 1144 | "Like `match-data', but markers in REUSE get invalidated. | ||
| 1145 | If NEW is non-NIL, it is set and returned instead of fresh data, | ||
| 1146 | but coerced to the correct value of INTEGERS." | ||
| 1147 | (or (and new | ||
| 1148 | (progn | ||
| 1149 | (set-match-data new) | ||
| 1150 | (and (eq new reuse) | ||
| 1151 | (eq (null integers) (markerp (car reuse))) | ||
| 1152 | new))) | ||
| 1153 | (match-data integers | ||
| 1154 | (prog1 reuse | ||
| 1155 | (while reuse | ||
| 1156 | (if (markerp (car reuse)) | ||
| 1157 | (set-marker (car reuse) nil)) | ||
| 1158 | (setq reuse (cdr reuse))))))) | ||
| 1159 | |||
| 1160 | (defun replace-match-maybe-edit (newtext fixedcase literal noedit match-data) | ||
| 1161 | "Make a replacement with `replace-match', editing `\\?'. | ||
| 1162 | NEXTEXT, FIXEDCASE, LITERAL are just passed on. If NOEDIT is true, no | ||
| 1163 | check for `\\?' is made to save time. MATCH-DATA is used for the | ||
| 1164 | replacement. In case editing is done, it is changed to use markers. | ||
| 1165 | |||
| 1166 | The return value is non-NIL if there has been no `\\?' or NOEDIT was | ||
| 1167 | passed in. If LITERAL is set, no checking is done, anyway." | ||
| 1168 | (unless (or literal noedit) | ||
| 1169 | (setq noedit t) | ||
| 1170 | (while (string-match "\\(\\`\\|[^\\]\\)\\(\\\\\\\\\\)*\\(\\\\\\?\\)" | ||
| 1171 | newtext) | ||
| 1172 | (setq newtext | ||
| 1173 | (read-input "Edit replacement string: " | ||
| 1174 | (prog1 | ||
| 1175 | (cons | ||
| 1176 | (replace-match "" t t newtext 3) | ||
| 1177 | (1+ (match-beginning 3))) | ||
| 1178 | (setq match-data | ||
| 1179 | (replace-match-data | ||
| 1180 | nil match-data match-data)))) | ||
| 1181 | noedit nil))) | ||
| 1182 | (set-match-data match-data) | ||
| 1183 | (replace-match newtext fixedcase literal) | ||
| 1184 | noedit) | ||
| 1185 | |||
| 1118 | (defun perform-replace (from-string replacements | 1186 | (defun perform-replace (from-string replacements |
| 1119 | query-flag regexp-flag delimited-flag | 1187 | query-flag regexp-flag delimited-flag |
| 1120 | &optional repeat-count map start end) | 1188 | &optional repeat-count map start end) |
| @@ -1145,6 +1213,7 @@ make, or the user didn't cancel the call." | |||
| 1145 | (search-string from-string) | 1213 | (search-string from-string) |
| 1146 | (real-match-data nil) ; the match data for the current match | 1214 | (real-match-data nil) ; the match data for the current match |
| 1147 | (next-replacement nil) | 1215 | (next-replacement nil) |
| 1216 | (noedit nil) | ||
| 1148 | (keep-going t) | 1217 | (keep-going t) |
| 1149 | (stack nil) | 1218 | (stack nil) |
| 1150 | (replace-count 0) | 1219 | (replace-count 0) |
| @@ -1201,7 +1270,9 @@ make, or the user didn't cancel the call." | |||
| 1201 | (setq real-match-data | 1270 | (setq real-match-data |
| 1202 | (if (consp match-again) | 1271 | (if (consp match-again) |
| 1203 | (progn (goto-char (nth 1 match-again)) | 1272 | (progn (goto-char (nth 1 match-again)) |
| 1204 | match-again) | 1273 | (replace-match-data t |
| 1274 | real-match-data | ||
| 1275 | match-again)) | ||
| 1205 | (and (or match-again | 1276 | (and (or match-again |
| 1206 | ;; MATCH-AGAIN non-nil means we | 1277 | ;; MATCH-AGAIN non-nil means we |
| 1207 | ;; accept an adjacent match. If | 1278 | ;; accept an adjacent match. If |
| @@ -1217,7 +1288,7 @@ make, or the user didn't cancel the call." | |||
| 1217 | (funcall search-function search-string limit t) | 1288 | (funcall search-function search-string limit t) |
| 1218 | ;; For speed, use only integers and | 1289 | ;; For speed, use only integers and |
| 1219 | ;; reuse the list used last time. | 1290 | ;; reuse the list used last time. |
| 1220 | (match-data t real-match-data))))) | 1291 | (replace-match-data t real-match-data))))) |
| 1221 | ;; Optionally ignore matches that have a read-only property. | 1292 | ;; Optionally ignore matches that have a read-only property. |
| 1222 | (unless (and query-replace-skip-read-only | 1293 | (unless (and query-replace-skip-read-only |
| 1223 | (text-property-not-all | 1294 | (text-property-not-all |
| @@ -1249,16 +1320,27 @@ make, or the user didn't cancel the call." | |||
| 1249 | (set-match-data real-match-data) | 1320 | (set-match-data real-match-data) |
| 1250 | (setq next-replacement | 1321 | (setq next-replacement |
| 1251 | (funcall (car replacements) (cdr replacements) | 1322 | (funcall (car replacements) (cdr replacements) |
| 1252 | replace-count))) | 1323 | replace-count) |
| 1324 | noedit nil)) | ||
| 1253 | (if (not query-flag) | 1325 | (if (not query-flag) |
| 1254 | (let ((inhibit-read-only query-replace-skip-read-only)) | 1326 | (let ((inhibit-read-only |
| 1255 | (set-match-data real-match-data) | 1327 | query-replace-skip-read-only)) |
| 1256 | (replace-match next-replacement nocasify literal) | 1328 | (unless noedit |
| 1257 | (setq replace-count (1+ replace-count))) | 1329 | (replace-highlight (nth 0 real-match-data) |
| 1330 | (nth 1 real-match-data))) | ||
| 1331 | (setq noedit | ||
| 1332 | (replace-match-maybe-edit | ||
| 1333 | next-replacement nocasify literal | ||
| 1334 | noedit real-match-data) | ||
| 1335 | replace-count (1+ replace-count))) | ||
| 1258 | (undo-boundary) | 1336 | (undo-boundary) |
| 1259 | (let (done replaced key def) | 1337 | (let (done replaced key def) |
| 1260 | ;; Loop reading commands until one of them sets done, | 1338 | ;; Loop reading commands until one of them sets done, |
| 1261 | ;; which means it has finished handling this occurrence. | 1339 | ;; which means it has finished handling this |
| 1340 | ;; occurrence. Any command that sets `done' should | ||
| 1341 | ;; leave behind proper match data for the stack. | ||
| 1342 | ;; Commands not setting `done' need to adjust | ||
| 1343 | ;; `real-match-data'. | ||
| 1262 | (while (not done) | 1344 | (while (not done) |
| 1263 | (set-match-data real-match-data) | 1345 | (set-match-data real-match-data) |
| 1264 | (replace-highlight (match-beginning 0) (match-end 0)) | 1346 | (replace-highlight (match-beginning 0) (match-end 0)) |
| @@ -1290,37 +1372,49 @@ make, or the user didn't cancel the call." | |||
| 1290 | ((eq def 'backup) | 1372 | ((eq def 'backup) |
| 1291 | (if stack | 1373 | (if stack |
| 1292 | (let ((elt (pop stack))) | 1374 | (let ((elt (pop stack))) |
| 1293 | (goto-char (car elt)) | 1375 | (goto-char (nth 0 elt)) |
| 1294 | (setq replaced (eq t (cdr elt))) | 1376 | (setq replaced (nth 1 elt) |
| 1295 | (or replaced | 1377 | real-match-data |
| 1296 | (set-match-data (cdr elt)))) | 1378 | (replace-match-data |
| 1379 | t real-match-data | ||
| 1380 | (nth 2 elt)))) | ||
| 1297 | (message "No previous match") | 1381 | (message "No previous match") |
| 1298 | (ding 'no-terminate) | 1382 | (ding 'no-terminate) |
| 1299 | (sit-for 1))) | 1383 | (sit-for 1))) |
| 1300 | ((eq def 'act) | 1384 | ((eq def 'act) |
| 1301 | (or replaced | 1385 | (or replaced |
| 1302 | (progn | 1386 | (setq noedit |
| 1303 | (replace-match next-replacement nocasify literal) | 1387 | (replace-match-maybe-edit |
| 1304 | (setq replace-count (1+ replace-count)))) | 1388 | next-replacement nocasify literal |
| 1389 | noedit real-match-data) | ||
| 1390 | replace-count (1+ replace-count))) | ||
| 1305 | (setq done t replaced t)) | 1391 | (setq done t replaced t)) |
| 1306 | ((eq def 'act-and-exit) | 1392 | ((eq def 'act-and-exit) |
| 1307 | (or replaced | 1393 | (or replaced |
| 1308 | (progn | 1394 | (setq noedit |
| 1309 | (replace-match next-replacement nocasify literal) | 1395 | (replace-match-maybe-edit |
| 1310 | (setq replace-count (1+ replace-count)))) | 1396 | next-replacement nocasify literal |
| 1397 | noedit real-match-data) | ||
| 1398 | replace-count (1+ replace-count))) | ||
| 1311 | (setq keep-going nil) | 1399 | (setq keep-going nil) |
| 1312 | (setq done t replaced t)) | 1400 | (setq done t replaced t)) |
| 1313 | ((eq def 'act-and-show) | 1401 | ((eq def 'act-and-show) |
| 1314 | (if (not replaced) | 1402 | (if (not replaced) |
| 1315 | (progn | 1403 | (setq noedit |
| 1316 | (replace-match next-replacement nocasify literal) | 1404 | (replace-match-maybe-edit |
| 1317 | (setq replace-count (1+ replace-count)) | 1405 | next-replacement nocasify literal |
| 1318 | (setq replaced t)))) | 1406 | noedit real-match-data) |
| 1407 | replace-count (1+ replace-count) | ||
| 1408 | real-match-data (replace-match-data | ||
| 1409 | t real-match-data) | ||
| 1410 | replaced t))) | ||
| 1319 | ((eq def 'automatic) | 1411 | ((eq def 'automatic) |
| 1320 | (or replaced | 1412 | (or replaced |
| 1321 | (progn | 1413 | (setq noedit |
| 1322 | (replace-match next-replacement nocasify literal) | 1414 | (replace-match-maybe-edit |
| 1323 | (setq replace-count (1+ replace-count)))) | 1415 | next-replacement nocasify literal |
| 1416 | noedit real-match-data) | ||
| 1417 | replace-count (1+ replace-count))) | ||
| 1324 | (setq done t query-flag nil replaced t)) | 1418 | (setq done t query-flag nil replaced t)) |
| 1325 | ((eq def 'skip) | 1419 | ((eq def 'skip) |
| 1326 | (setq done t)) | 1420 | (setq done t)) |
| @@ -1328,36 +1422,45 @@ make, or the user didn't cancel the call." | |||
| 1328 | (recenter nil)) | 1422 | (recenter nil)) |
| 1329 | ((eq def 'edit) | 1423 | ((eq def 'edit) |
| 1330 | (let ((opos (point-marker))) | 1424 | (let ((opos (point-marker))) |
| 1425 | (setq real-match-data (replace-match-data | ||
| 1426 | nil real-match-data | ||
| 1427 | real-match-data)) | ||
| 1331 | (goto-char (match-beginning 0)) | 1428 | (goto-char (match-beginning 0)) |
| 1332 | (save-excursion | 1429 | (save-excursion |
| 1333 | (funcall search-function search-string limit t) | ||
| 1334 | (setq real-match-data (match-data))) | ||
| 1335 | (save-excursion | ||
| 1336 | (save-window-excursion | 1430 | (save-window-excursion |
| 1337 | (recursive-edit))) | 1431 | (recursive-edit))) |
| 1338 | (goto-char opos)) | 1432 | (goto-char opos) |
| 1339 | (set-match-data real-match-data) | 1433 | (set-marker opos nil)) |
| 1340 | ;; Before we make the replacement, | 1434 | ;; Before we make the replacement, |
| 1341 | ;; decide whether the search string | 1435 | ;; decide whether the search string |
| 1342 | ;; can match again just after this match. | 1436 | ;; can match again just after this match. |
| 1343 | (if (and regexp-flag nonempty-match) | 1437 | (if (and regexp-flag nonempty-match) |
| 1344 | (setq match-again (and (looking-at search-string) | 1438 | (setq match-again (and (looking-at search-string) |
| 1345 | (match-data))))) | 1439 | (match-data))))) |
| 1346 | |||
| 1347 | ;; Edit replacement. | 1440 | ;; Edit replacement. |
| 1348 | ((eq def 'edit-replacement) | 1441 | ((eq def 'edit-replacement) |
| 1349 | (setq next-replacement | 1442 | (setq real-match-data (replace-match-data |
| 1443 | nil real-match-data | ||
| 1444 | real-match-data) | ||
| 1445 | next-replacement | ||
| 1350 | (read-input "Edit replacement string: " | 1446 | (read-input "Edit replacement string: " |
| 1351 | next-replacement)) | 1447 | next-replacement) |
| 1352 | (or replaced | 1448 | noedit nil) |
| 1353 | (replace-match next-replacement nocasify literal)) | 1449 | (if replaced |
| 1450 | (set-match-data real-match-data) | ||
| 1451 | (setq noedit | ||
| 1452 | (replace-match-maybe-edit | ||
| 1453 | next-replacement nocasify literal noedit | ||
| 1454 | real-match-data) | ||
| 1455 | replaced t)) | ||
| 1354 | (setq done t)) | 1456 | (setq done t)) |
| 1355 | 1457 | ||
| 1356 | ((eq def 'delete-and-edit) | 1458 | ((eq def 'delete-and-edit) |
| 1357 | (delete-region (match-beginning 0) (match-end 0)) | 1459 | (replace-match "" t t) |
| 1358 | (set-match-data | 1460 | (setq real-match-data (replace-match-data |
| 1359 | (prog1 (match-data) | 1461 | nil real-match-data)) |
| 1360 | (save-excursion (recursive-edit)))) | 1462 | (replace-dehighlight) |
| 1463 | (save-excursion (recursive-edit)) | ||
| 1361 | (setq replaced t)) | 1464 | (setq replaced t)) |
| 1362 | ;; Note: we do not need to treat `exit-prefix' | 1465 | ;; Note: we do not need to treat `exit-prefix' |
| 1363 | ;; specially here, since we reread | 1466 | ;; specially here, since we reread |
| @@ -1372,10 +1475,23 @@ make, or the user didn't cancel the call." | |||
| 1372 | ;; Record previous position for ^ when we move on. | 1475 | ;; Record previous position for ^ when we move on. |
| 1373 | ;; Change markers to numbers in the match data | 1476 | ;; Change markers to numbers in the match data |
| 1374 | ;; since lots of markers slow down editing. | 1477 | ;; since lots of markers slow down editing. |
| 1375 | (setq stack | 1478 | (push (list (point) replaced |
| 1376 | (cons (cons (point) | 1479 | ;;; If the replacement has already happened, all we need is the |
| 1377 | (or replaced (match-data t))) | 1480 | ;;; current match start and end. We could get this with a trivial |
| 1378 | stack)))))) | 1481 | ;;; match like |
| 1482 | ;;; (save-excursion (goto-char (match-beginning 0)) | ||
| 1483 | ;;; (search-forward (match-string 0)) | ||
| 1484 | ;;; (match-data t)) | ||
| 1485 | ;;; if we really wanted to avoid manually constructing match data. | ||
| 1486 | ;;; Adding current-buffer is necessary so that match-data calls can | ||
| 1487 | ;;; return markers which are appropriate for editing. | ||
| 1488 | (if replaced | ||
| 1489 | (list | ||
| 1490 | (match-beginning 0) | ||
| 1491 | (match-end 0) | ||
| 1492 | (current-buffer)) | ||
| 1493 | (match-data t))) | ||
| 1494 | stack))))) | ||
| 1379 | 1495 | ||
| 1380 | ;; The code preventing adjacent regexp matches in the condition | 1496 | ;; The code preventing adjacent regexp matches in the condition |
| 1381 | ;; of the while-loop above will haven taken us one character | 1497 | ;; of the while-loop above will haven taken us one character |
| @@ -1405,14 +1521,12 @@ make, or the user didn't cancel the call." | |||
| 1405 | 1521 | ||
| 1406 | (defun replace-highlight (start end) | 1522 | (defun replace-highlight (start end) |
| 1407 | (and query-replace-highlight | 1523 | (and query-replace-highlight |
| 1408 | (progn | 1524 | (if replace-overlay |
| 1409 | (or replace-overlay | 1525 | (move-overlay replace-overlay start end (current-buffer)) |
| 1410 | (progn | 1526 | (setq replace-overlay (make-overlay start end)) |
| 1411 | (setq replace-overlay (make-overlay start end)) | 1527 | (overlay-put replace-overlay 'face |
| 1412 | (overlay-put replace-overlay 'face | 1528 | (if (facep 'query-replace) |
| 1413 | (if (facep 'query-replace) | 1529 | 'query-replace 'region))))) |
| 1414 | 'query-replace 'region)))) | ||
| 1415 | (move-overlay replace-overlay start end (current-buffer))))) | ||
| 1416 | 1530 | ||
| 1417 | ;;; arch-tag: 16b4cd61-fd40-497b-b86f-b667c4cf88e4 | 1531 | ;;; arch-tag: 16b4cd61-fd40-497b-b86f-b667c4cf88e4 |
| 1418 | ;;; replace.el ends here | 1532 | ;;; replace.el ends here |