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