diff options
| author | Richard M. Stallman | 1993-03-09 19:51:29 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1993-03-09 19:51:29 +0000 |
| commit | 81bdc14db5596d5c80c08bd4f5eaeb1b59cf132c (patch) | |
| tree | 6f7fb9f3cc1e8e6d8d3a48c76dc30ca621d11d54 /lisp/replace.el | |
| parent | 78e3ef3ce66a4f6f5b53fdc920370915bd07b08f (diff) | |
| download | emacs-81bdc14db5596d5c80c08bd4f5eaeb1b59cf132c.tar.gz emacs-81bdc14db5596d5c80c08bd4f5eaeb1b59cf132c.zip | |
(query-replace-map): New keymap.
(perform-replace): Use query-replace-map.
(query-replace, query-replace-regexp, map-query-replace-regexp):
(replace-string, replace-regexp): Don't print `done' if unread chars.
Diffstat (limited to 'lisp/replace.el')
| -rw-r--r-- | lisp/replace.el | 105 |
1 files changed, 70 insertions, 35 deletions
diff --git a/lisp/replace.el b/lisp/replace.el index daa9d728131..3c1789eb254 100644 --- a/lisp/replace.el +++ b/lisp/replace.el | |||
| @@ -43,10 +43,12 @@ what to do with it. For directions, type \\[help-command] at that time. | |||
| 43 | Preserves case in each replacement if case-replace and case-fold-search | 43 | Preserves case in each replacement if case-replace and case-fold-search |
| 44 | are non-nil and FROM-STRING has no uppercase letters. | 44 | are non-nil and FROM-STRING has no uppercase letters. |
| 45 | Third arg DELIMITED (prefix arg if interactive) non-nil means replace | 45 | Third arg DELIMITED (prefix arg if interactive) non-nil means replace |
| 46 | only matches surrounded by word boundaries." | 46 | only matches surrounded by word boundaries. |
| 47 | |||
| 48 | To customize possible responses, change the \"bindings\" in `query-replace-map'." | ||
| 47 | (interactive (query-replace-read-args "Query replace")) | 49 | (interactive (query-replace-read-args "Query replace")) |
| 48 | (perform-replace from-string to-string t nil arg) | 50 | (perform-replace from-string to-string t nil arg) |
| 49 | (message "Done")) | 51 | (or unread-command-events (message "Done"))) |
| 50 | (define-key esc-map "%" 'query-replace) | 52 | (define-key esc-map "%" 'query-replace) |
| 51 | 53 | ||
| 52 | (defun query-replace-regexp (regexp to-string &optional arg) | 54 | (defun query-replace-regexp (regexp to-string &optional arg) |
| @@ -62,7 +64,7 @@ In TO-STRING, \\& means insert what matched REGEXP, | |||
| 62 | and \\=\\<n> means insert what matched <n>th \\(...\\) in REGEXP." | 64 | and \\=\\<n> means insert what matched <n>th \\(...\\) in REGEXP." |
| 63 | (interactive (query-replace-read-args "Query replace regexp")) | 65 | (interactive (query-replace-read-args "Query replace regexp")) |
| 64 | (perform-replace regexp to-string t t arg) | 66 | (perform-replace regexp to-string t t arg) |
| 65 | (message "Done")) | 67 | (or unread-command-events (message "Done"))) |
| 66 | 68 | ||
| 67 | (defun map-query-replace-regexp (regexp to-strings &optional arg) | 69 | (defun map-query-replace-regexp (regexp to-strings &optional arg) |
| 68 | "Replace some matches for REGEXP with various strings, in rotation. | 70 | "Replace some matches for REGEXP with various strings, in rotation. |
| @@ -100,7 +102,7 @@ before rotating to the next." | |||
| 100 | (setq replacements (append replacements (list to-strings)) | 102 | (setq replacements (append replacements (list to-strings)) |
| 101 | to-strings "")))) | 103 | to-strings "")))) |
| 102 | (perform-replace regexp replacements t t nil arg)) | 104 | (perform-replace regexp replacements t t nil arg)) |
| 103 | (message "Done")) | 105 | (or unread-command-events (message "Done"))) |
| 104 | 106 | ||
| 105 | (defun replace-string (from-string to-string &optional delimited) | 107 | (defun replace-string (from-string to-string &optional delimited) |
| 106 | "Replace occurrences of FROM-STRING with TO-STRING. | 108 | "Replace occurrences of FROM-STRING with TO-STRING. |
| @@ -116,7 +118,7 @@ What you probably want is a loop like this: | |||
| 116 | which will run faster and will not set the mark or print anything." | 118 | which will run faster and will not set the mark or print anything." |
| 117 | (interactive (query-replace-read-args "Replace string")) | 119 | (interactive (query-replace-read-args "Replace string")) |
| 118 | (perform-replace from-string to-string nil nil delimited) | 120 | (perform-replace from-string to-string nil nil delimited) |
| 119 | (message "Done")) | 121 | (or unread-command-events (message "Done"))) |
| 120 | 122 | ||
| 121 | (defun replace-regexp (regexp to-string &optional delimited) | 123 | (defun replace-regexp (regexp to-string &optional delimited) |
| 122 | "Replace things after point matching REGEXP with TO-STRING. | 124 | "Replace things after point matching REGEXP with TO-STRING. |
| @@ -134,7 +136,7 @@ What you probably want is a loop like this: | |||
| 134 | which will run faster and will not set the mark or print anything." | 136 | which will run faster and will not set the mark or print anything." |
| 135 | (interactive (query-replace-read-args "Replace regexp")) | 137 | (interactive (query-replace-read-args "Replace regexp")) |
| 136 | (perform-replace regexp to-string nil t delimited) | 138 | (perform-replace regexp to-string nil t delimited) |
| 137 | (message "Done")) | 139 | (or unread-command-events (message "Done"))) |
| 138 | 140 | ||
| 139 | (fset 'delete-non-matching-lines 'keep-lines) | 141 | (fset 'delete-non-matching-lines 'keep-lines) |
| 140 | (defun keep-lines (regexp) | 142 | (defun keep-lines (regexp) |
| @@ -346,6 +348,8 @@ It serves as a menu to find any of the occurrences in this buffer. | |||
| 346 | (if (interactive-p) | 348 | (if (interactive-p) |
| 347 | (message "%d matching lines." (length occur-pos-list))))))) | 349 | (message "%d matching lines." (length occur-pos-list))))))) |
| 348 | 350 | ||
| 351 | ;; It would be nice to use \\[...], but there is no reasonable way | ||
| 352 | ;; to make that display both SPC and Y. | ||
| 349 | (defconst query-replace-help | 353 | (defconst query-replace-help |
| 350 | "Type Space or `y' to replace one match, Delete or `n' to skip to next, | 354 | "Type Space or `y' to replace one match, Delete or `n' to skip to next, |
| 351 | ESC or `q' to exit, Period to replace one match and exit, | 355 | ESC or `q' to exit, Period to replace one match and exit, |
| @@ -357,15 +361,43 @@ C-l to clear the screen, redisplay, and offer same replacement again, | |||
| 357 | ^ to move point back to previous match." | 361 | ^ to move point back to previous match." |
| 358 | "Help message while in query-replace") | 362 | "Help message while in query-replace") |
| 359 | 363 | ||
| 364 | (defvar query-replace-map (make-sparse-keymap) | ||
| 365 | "Keymap that defines the responses to questions in `query-replace'. | ||
| 366 | The \"bindings\" in this map are not commands; they are answers. | ||
| 367 | The valid answers include `act', `skip', `act-and-show', | ||
| 368 | `exit', `act-and-exit', `edit', `delete-and-edit', `recenter', | ||
| 369 | `automatic', `backup', and `help'.") | ||
| 370 | |||
| 371 | (define-key query-replace-map " " 'act) | ||
| 372 | (define-key query-replace-map "\d" 'skip) | ||
| 373 | (define-key query-replace-map [delete] 'skip) | ||
| 374 | (define-key query-replace-map "y" 'act) | ||
| 375 | (define-key query-replace-map "n" 'skip) | ||
| 376 | (define-key query-replace-map "," 'act-and-show) | ||
| 377 | (define-key query-replace-map "\e" 'exit) | ||
| 378 | (define-key query-replace-map "q" 'exit) | ||
| 379 | (define-key query-replace-map "." 'act-and-exit) | ||
| 380 | (define-key query-replace-map "\C-r" 'edit) | ||
| 381 | (define-key query-replace-map "\C-w" 'delete-and-edit) | ||
| 382 | (define-key query-replace-map "\C-l" 'recenter) | ||
| 383 | (define-key query-replace-map "!" 'automatic) | ||
| 384 | (define-key query-replace-map "^" 'backup) | ||
| 385 | (define-key query-replace-map "\C-h" 'help) | ||
| 386 | (define-key query-replace-map "?" 'help) | ||
| 387 | ;; Cause all other types of events to be unread immediately, | ||
| 388 | ;; without regard to the global map. | ||
| 389 | (define-key query-replace-map [t] 'ignore) | ||
| 390 | |||
| 360 | (defun perform-replace (from-string replacements | 391 | (defun perform-replace (from-string replacements |
| 361 | query-flag regexp-flag delimited-flag | 392 | query-flag regexp-flag delimited-flag |
| 362 | &optional repeat-count) | 393 | &optional repeat-count map) |
| 363 | "Subroutine of `query-replace'. Its complexity handles interactive queries. | 394 | "Subroutine of `query-replace'. Its complexity handles interactive queries. |
| 364 | Don't use this in your own program unless you want to query and set the mark | 395 | Don't use this in your own program unless you want to query and set the mark |
| 365 | just as `query-replace' does. Instead, write a simple loop like this: | 396 | just as `query-replace' does. Instead, write a simple loop like this: |
| 366 | (while (re-search-forward \"foo[ \t]+bar\" nil t) | 397 | (while (re-search-forward \"foo[ \t]+bar\" nil t) |
| 367 | (replace-match \"foobar\" nil nil)) | 398 | (replace-match \"foobar\" nil nil)) |
| 368 | which will run faster and do exactly what you probably want." | 399 | which will run faster and do exactly what you probably want." |
| 400 | (or map (setq map query-replace-map)) | ||
| 369 | (let ((nocasify (not (and case-fold-search case-replace | 401 | (let ((nocasify (not (and case-fold-search case-replace |
| 370 | (string-equal from-string | 402 | (string-equal from-string |
| 371 | (downcase from-string))))) | 403 | (downcase from-string))))) |
| @@ -392,6 +424,7 @@ which will run faster and do exactly what you probably want." | |||
| 392 | "\\b"))) | 424 | "\\b"))) |
| 393 | (push-mark) | 425 | (push-mark) |
| 394 | (undo-boundary) | 426 | (undo-boundary) |
| 427 | ;; Loop finding occurrences that perhaps should be replaced. | ||
| 395 | (while (and keep-going | 428 | (while (and keep-going |
| 396 | (not (eobp)) | 429 | (not (eobp)) |
| 397 | (funcall search-function search-string nil t) | 430 | (funcall search-function search-string nil t) |
| @@ -431,58 +464,58 @@ which will run faster and do exactly what you probably want." | |||
| 431 | (replace-match next-replacement nocasify literal) | 464 | (replace-match next-replacement nocasify literal) |
| 432 | (setq replace-count (1+ replace-count))) | 465 | (setq replace-count (1+ replace-count))) |
| 433 | (undo-boundary) | 466 | (undo-boundary) |
| 434 | (let (done replaced char) | 467 | (let (done replaced key) |
| 468 | ;; Loop reading commands until one of them sets done, | ||
| 469 | ;; which means it has finished handling this occurrence. | ||
| 435 | (while (not done) | 470 | (while (not done) |
| 436 | (let ((help-form | 471 | (message "Query replacing %s with %s: " |
| 437 | '(concat "Query replacing " | 472 | from-string next-replacement) |
| 438 | (if regexp-flag "regexp " "") | 473 | (setq key (vector (read-event))) |
| 439 | from-string " with " next-replacement ".\n\n" | 474 | (setq def (lookup-key map key)) |
| 440 | (substitute-command-keys query-replace-help)))) | ||
| 441 | (setq char help-char) | ||
| 442 | (while (or (not (numberp char)) (= char help-char)) | ||
| 443 | (message "Query replacing %s with %s: " from-string next-replacement) | ||
| 444 | (setq char (read-event)) | ||
| 445 | (if (and (numberp char) (= char ??)) | ||
| 446 | (setq unread-command-events (list help-char) | ||
| 447 | char help-char)))) | ||
| 448 | ;; Restore the match data while we process the command. | 475 | ;; Restore the match data while we process the command. |
| 449 | (store-match-data real-match-data) | 476 | (store-match-data real-match-data) |
| 450 | (cond ((or (= char ?\e) | 477 | (cond ((eq def 'help) |
| 451 | (= char ?q)) | 478 | (with-output-to-temp-buffer "*Help*" |
| 479 | (princ | ||
| 480 | (concat "Query replacing " | ||
| 481 | (if regexp-flag "regexp " "") | ||
| 482 | from-string " with " | ||
| 483 | next-replacement ".\n\n" | ||
| 484 | (substitute-command-keys | ||
| 485 | query-replace-help))))) | ||
| 486 | ((eq def 'exit) | ||
| 452 | (setq keep-going nil) | 487 | (setq keep-going nil) |
| 453 | (setq done t)) | 488 | (setq done t)) |
| 454 | ((= char ?^) | 489 | ((eq def 'backup) |
| 455 | (let ((elt (car stack))) | 490 | (let ((elt (car stack))) |
| 456 | (goto-char (car elt)) | 491 | (goto-char (car elt)) |
| 457 | (setq replaced (eq t (cdr elt))) | 492 | (setq replaced (eq t (cdr elt))) |
| 458 | (or replaced | 493 | (or replaced |
| 459 | (store-match-data (cdr elt))) | 494 | (store-match-data (cdr elt))) |
| 460 | (setq stack (cdr stack)))) | 495 | (setq stack (cdr stack)))) |
| 461 | ((or (= char ?\ ) | 496 | ((eq def 'act) |
| 462 | (= char ?y)) | ||
| 463 | (or replaced | 497 | (or replaced |
| 464 | (replace-match next-replacement nocasify literal)) | 498 | (replace-match next-replacement nocasify literal)) |
| 465 | (setq done t replaced t)) | 499 | (setq done t replaced t)) |
| 466 | ((= char ?\.) | 500 | ((eq def 'act-and-exit) |
| 467 | (or replaced | 501 | (or replaced |
| 468 | (replace-match next-replacement nocasify literal)) | 502 | (replace-match next-replacement nocasify literal)) |
| 469 | (setq keep-going nil) | 503 | (setq keep-going nil) |
| 470 | (setq done t replaced t)) | 504 | (setq done t replaced t)) |
| 471 | ((= char ?\,) | 505 | ((eq def 'act-and-show) |
| 472 | (if (not replaced) | 506 | (if (not replaced) |
| 473 | (progn | 507 | (progn |
| 474 | (replace-match next-replacement nocasify literal) | 508 | (replace-match next-replacement nocasify literal) |
| 475 | (setq replaced t)))) | 509 | (setq replaced t)))) |
| 476 | ((= char ?!) | 510 | ((eq def 'automatic) |
| 477 | (or replaced | 511 | (or replaced |
| 478 | (replace-match next-replacement nocasify literal)) | 512 | (replace-match next-replacement nocasify literal)) |
| 479 | (setq done t query-flag nil replaced t)) | 513 | (setq done t query-flag nil replaced t)) |
| 480 | ((or (= char ?\177) | 514 | ((eq def 'skip) |
| 481 | (= char ?n)) | ||
| 482 | (setq done t)) | 515 | (setq done t)) |
| 483 | ((= char ?\C-l) | 516 | ((eq def 'recenter) |
| 484 | (recenter nil)) | 517 | (recenter nil)) |
| 485 | ((= char ?\C-r) | 518 | ((eq def 'edit) |
| 486 | (store-match-data | 519 | (store-match-data |
| 487 | (prog1 (match-data) | 520 | (prog1 (match-data) |
| 488 | (save-excursion (recursive-edit)))) | 521 | (save-excursion (recursive-edit)))) |
| @@ -491,7 +524,7 @@ which will run faster and do exactly what you probably want." | |||
| 491 | ;; can match again just after this match. | 524 | ;; can match again just after this match. |
| 492 | (if regexp-flag | 525 | (if regexp-flag |
| 493 | (setq match-again (looking-at search-string)))) | 526 | (setq match-again (looking-at search-string)))) |
| 494 | ((= char ?\C-w) | 527 | ((eq def 'delete-and-edit) |
| 495 | (delete-region (match-beginning 0) (match-end 0)) | 528 | (delete-region (match-beginning 0) (match-end 0)) |
| 496 | (store-match-data | 529 | (store-match-data |
| 497 | (prog1 (match-data) | 530 | (prog1 (match-data) |
| @@ -499,7 +532,9 @@ which will run faster and do exactly what you probably want." | |||
| 499 | (setq replaced t)) | 532 | (setq replaced t)) |
| 500 | (t | 533 | (t |
| 501 | (setq keep-going nil) | 534 | (setq keep-going nil) |
| 502 | (setq unread-command-events (list char)) | 535 | (setq unread-command-events |
| 536 | (append (listify-key-sequence key) | ||
| 537 | unread-command-events)) | ||
| 503 | (setq done t)))) | 538 | (setq done t)))) |
| 504 | ;; Record previous position for ^ when we move on. | 539 | ;; Record previous position for ^ when we move on. |
| 505 | ;; Change markers to numbers in the match data | 540 | ;; Change markers to numbers in the match data |
| @@ -515,6 +550,6 @@ which will run faster and do exactly what you probably want." | |||
| 515 | stack)) | 550 | stack)) |
| 516 | (if replaced (setq replace-count (1+ replace-count))))) | 551 | (if replaced (setq replace-count (1+ replace-count))))) |
| 517 | (setq lastrepl (point))) | 552 | (setq lastrepl (point))) |
| 518 | (and keep-going stack))) | 553 | (and keep-going stack))) |
| 519 | 554 | ||
| 520 | ;;; replace.el ends here | 555 | ;;; replace.el ends here |