aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/replace.el
diff options
context:
space:
mode:
authorRichard M. Stallman1993-03-09 19:51:29 +0000
committerRichard M. Stallman1993-03-09 19:51:29 +0000
commit81bdc14db5596d5c80c08bd4f5eaeb1b59cf132c (patch)
tree6f7fb9f3cc1e8e6d8d3a48c76dc30ca621d11d54 /lisp/replace.el
parent78e3ef3ce66a4f6f5b53fdc920370915bd07b08f (diff)
downloademacs-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.el105
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.
43Preserves case in each replacement if case-replace and case-fold-search 43Preserves case in each replacement if case-replace and case-fold-search
44are non-nil and FROM-STRING has no uppercase letters. 44are non-nil and FROM-STRING has no uppercase letters.
45Third arg DELIMITED (prefix arg if interactive) non-nil means replace 45Third arg DELIMITED (prefix arg if interactive) non-nil means replace
46only matches surrounded by word boundaries." 46only matches surrounded by word boundaries.
47
48To 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,
62and \\=\\<n> means insert what matched <n>th \\(...\\) in REGEXP." 64and \\=\\<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:
116which will run faster and will not set the mark or print anything." 118which 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:
134which will run faster and will not set the mark or print anything." 136which 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,
351ESC or `q' to exit, Period to replace one match and exit, 355ESC 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'.
366The \"bindings\" in this map are not commands; they are answers.
367The 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.
364Don't use this in your own program unless you want to query and set the mark 395Don't use this in your own program unless you want to query and set the mark
365just as `query-replace' does. Instead, write a simple loop like this: 396just 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))
368which will run faster and do exactly what you probably want." 399which 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