comparison lisp/replace.el @ 732:a8d94735277e

*** empty log message ***
author Jim Blandy <jimb@redhat.com>
date Tue, 30 Jun 1992 13:54:21 +0000
parents 7cbd4fcd8b0f
children c8d4eb38ebfc
comparison
equal deleted inserted replaced
731:5c6db33a9ef6 732:a8d94735277e
1 ;;; replace.el --- replace commands for Emacs. 1 ;;; replace.el --- replace commands for Emacs.
2 2
3 ;; Copyright (C) 1985-1991 Free Software Foundation, Inc. 3 ;; Copyright (C) 1985, 86, 87, 88, 89, 90, 91, 92 Free Software Foundation, Inc.
4 4
5 ;; This file is part of GNU Emacs. 5 ;; This file is part of GNU Emacs.
6 6
7 ;; GNU Emacs is free software; you can redistribute it and/or modify 7 ;; GNU Emacs is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by 8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 1, or (at your option) 9 ;; the Free Software Foundation; either version 2, or (at your option)
10 ;; any later version. 10 ;; any later version.
11 11
12 ;; GNU Emacs is distributed in the hope that it will be useful, 12 ;; GNU Emacs is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of 13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; You should have received a copy of the GNU General Public License 17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GNU Emacs; see the file COPYING. If not, write to 18 ;; along with GNU Emacs; see the file COPYING. If not, write to
19 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 19 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
20 20
21 21
22 ;;;###autoload
23 (defconst case-replace t "\ 22 (defconst case-replace t "\
24 *Non-nil means query-replace should preserve case in replacements.") 23 *Non-nil means query-replace should preserve case in replacements.")
25 24
26 ;;;###autoload
27 (defun query-replace (from-string to-string &optional arg) 25 (defun query-replace (from-string to-string &optional arg)
28 "Replace some occurrences of FROM-STRING with TO-STRING. 26 "Replace some occurrences of FROM-STRING with TO-STRING.
29 As each match is found, the user must type a character saying 27 As each match is found, the user must type a character saying
30 what to do with it. For directions, type \\[help-command] at that time. 28 what to do with it. For directions, type \\[help-command] at that time.
31 29
34 Third arg DELIMITED (prefix arg if interactive) non-nil means replace 32 Third arg DELIMITED (prefix arg if interactive) non-nil means replace
35 only matches surrounded by word boundaries." 33 only matches surrounded by word boundaries."
36 (interactive "sQuery replace: \nsQuery replace %s with: \nP") 34 (interactive "sQuery replace: \nsQuery replace %s with: \nP")
37 (perform-replace from-string to-string t nil arg) 35 (perform-replace from-string to-string t nil arg)
38 (message "Done")) 36 (message "Done"))
39 ;;;###autoload
40 (define-key esc-map "%" 'query-replace) 37 (define-key esc-map "%" 'query-replace)
41 38
42 ;;;###autoload
43 (defun query-replace-regexp (regexp to-string &optional arg) 39 (defun query-replace-regexp (regexp to-string &optional arg)
44 "Replace some things after point matching REGEXP with TO-STRING. 40 "Replace some things after point matching REGEXP with TO-STRING.
45 As each match is found, the user must type a character saying 41 As each match is found, the user must type a character saying
46 what to do with it. For directions, type \\[help-command] at that time. 42 what to do with it. For directions, type \\[help-command] at that time.
47 43
53 and \\=\\<n> means insert what matched <n>th \\(...\\) in REGEXP." 49 and \\=\\<n> means insert what matched <n>th \\(...\\) in REGEXP."
54 (interactive "sQuery replace regexp: \nsQuery replace regexp %s with: \nP") 50 (interactive "sQuery replace regexp: \nsQuery replace regexp %s with: \nP")
55 (perform-replace regexp to-string t t arg) 51 (perform-replace regexp to-string t t arg)
56 (message "Done")) 52 (message "Done"))
57 53
58 ;;;###autoload
59 (defun map-query-replace-regexp (regexp to-strings &optional arg) 54 (defun map-query-replace-regexp (regexp to-strings &optional arg)
60 "Replace some matches for REGEXP with various strings, in rotation. 55 "Replace some matches for REGEXP with various strings, in rotation.
61 The second argument TO-STRINGS contains the replacement strings, separated 56 The second argument TO-STRINGS contains the replacement strings, separated
62 by spaces. This command works like `query-replace-regexp' except 57 by spaces. This command works like `query-replace-regexp' except
63 that each successive replacement uses the next successive replacement string, 58 that each successive replacement uses the next successive replacement string,
82 (setq replacements (append replacements (list to-strings)) 77 (setq replacements (append replacements (list to-strings))
83 to-strings "")))) 78 to-strings ""))))
84 (perform-replace regexp replacements t t nil arg)) 79 (perform-replace regexp replacements t t nil arg))
85 (message "Done")) 80 (message "Done"))
86 81
87 ;;;###autoload
88 (defun replace-string (from-string to-string &optional delimited) 82 (defun replace-string (from-string to-string &optional delimited)
89 "Replace occurrences of FROM-STRING with TO-STRING. 83 "Replace occurrences of FROM-STRING with TO-STRING.
90 Preserve case in each match if `case-replace' and `case-fold-search' 84 Preserve case in each match if `case-replace' and `case-fold-search'
91 are non-nil and FROM-STRING has no uppercase letters. 85 are non-nil and FROM-STRING has no uppercase letters.
92 Third arg DELIMITED (prefix arg if interactive) non-nil means replace 86 Third arg DELIMITED (prefix arg if interactive) non-nil means replace
99 which will run faster and will not set the mark or print anything." 93 which will run faster and will not set the mark or print anything."
100 (interactive "sReplace string: \nsReplace string %s with: \nP") 94 (interactive "sReplace string: \nsReplace string %s with: \nP")
101 (perform-replace from-string to-string nil nil delimited) 95 (perform-replace from-string to-string nil nil delimited)
102 (message "Done")) 96 (message "Done"))
103 97
104 ;;;###autoload
105 (defun replace-regexp (regexp to-string &optional delimited) 98 (defun replace-regexp (regexp to-string &optional delimited)
106 "Replace things after point matching REGEXP with TO-STRING. 99 "Replace things after point matching REGEXP with TO-STRING.
107 Preserve case in each match if case-replace and case-fold-search 100 Preserve case in each match if case-replace and case-fold-search
108 are non-nil and REGEXP has no uppercase letters. 101 are non-nil and REGEXP has no uppercase letters.
109 Third arg DELIMITED (prefix arg if interactive) non-nil means replace 102 Third arg DELIMITED (prefix arg if interactive) non-nil means replace
346 C-l to clear the screen, redisplay, and offer same replacement again, 339 C-l to clear the screen, redisplay, and offer same replacement again,
347 ! to replace all remaining matches with no more questions, 340 ! to replace all remaining matches with no more questions,
348 ^ to move point back to previous match." 341 ^ to move point back to previous match."
349 "Help message while in query-replace") 342 "Help message while in query-replace")
350 343
351 ;;;###autoload
352 (defun perform-replace (from-string replacements 344 (defun perform-replace (from-string replacements
353 query-flag regexp-flag delimited-flag 345 query-flag regexp-flag delimited-flag
354 &optional repeat-count) 346 &optional repeat-count)
355 "Subroutine of `query-replace'. Its complexity handles interactive queries. 347 "Subroutine of `query-replace'. Its complexity handles interactive queries.
356 Don't use this in your own program unless you want to query and set the mark 348 Don't use this in your own program unless you want to query and set the mark
362 (string-equal from-string 354 (string-equal from-string
363 (downcase from-string))))) 355 (downcase from-string)))))
364 (literal (not regexp-flag)) 356 (literal (not regexp-flag))
365 (search-function (if regexp-flag 're-search-forward 'search-forward)) 357 (search-function (if regexp-flag 're-search-forward 'search-forward))
366 (search-string from-string) 358 (search-string from-string)
359 (real-match-data nil) ; the match data for the current match
367 (next-replacement nil) 360 (next-replacement nil)
368 (replacement-index 0) 361 (replacement-index 0)
369 (keep-going t) 362 (keep-going t)
370 (stack nil) 363 (stack nil)
371 (next-rotate-count 0) 364 (next-rotate-count 0)
398 ;; Don't replace the null string 391 ;; Don't replace the null string
399 ;; right after end of previous replacement. 392 ;; right after end of previous replacement.
400 (forward-char 1) 393 (forward-char 1)
401 (funcall search-function search-string nil t)) 394 (funcall search-function search-string nil t))
402 t)) 395 t))
396
397 ;; Save the data associated with the real match.
398 (setq real-match-data (match-data))
399
403 ;; Before we make the replacement, decide whether the search string 400 ;; Before we make the replacement, decide whether the search string
404 ;; can match again just after this match. 401 ;; can match again just after this match.
405 (if regexp-flag 402 (if regexp-flag
406 (setq match-again (looking-at search-string))) 403 (setq match-again (looking-at search-string)))
407 ;; If time for a change, advance to next replacement string. 404 ;; If time for a change, advance to next replacement string.
412 (+ next-rotate-count repeat-count)) 409 (+ next-rotate-count repeat-count))
413 (setq next-replacement (nth replacement-index replacements)) 410 (setq next-replacement (nth replacement-index replacements))
414 (setq replacement-index (% (1+ replacement-index) (length replacements))))) 411 (setq replacement-index (% (1+ replacement-index) (length replacements)))))
415 (if (not query-flag) 412 (if (not query-flag)
416 (progn 413 (progn
414 (store-match-data real-match-data)
417 (replace-match next-replacement nocasify literal) 415 (replace-match next-replacement nocasify literal)
418 (setq replace-count (1+ replace-count))) 416 (setq replace-count (1+ replace-count)))
419 (undo-boundary) 417 (undo-boundary)
420 (let (done replaced) 418 (let (done replaced)
421 (while (not done) 419 (while (not done)
422 ;; Preserve the match data. Process filters and sentinels 420 (let ((help-form
423 ;; could run inside read-char..
424 (let ((data (match-data))
425 (help-form
426 '(concat "Query replacing " 421 '(concat "Query replacing "
427 (if regexp-flag "regexp " "") 422 (if regexp-flag "regexp " "")
428 from-string " with " next-replacement ".\n\n" 423 from-string " with " next-replacement ".\n\n"
429 (substitute-command-keys query-replace-help)))) 424 (substitute-command-keys query-replace-help))))
430 (setq char help-char) 425 (setq char help-char)
431 (while (or (not (numberp char)) (= char help-char)) 426 (while (or (not (numberp char)) (= char help-char))
432 (message "Query replacing %s with %s: " from-string next-replacement) 427 (message "Query replacing %s with %s: " from-string next-replacement)
433 (setq char (read-event)) 428 (setq char (read-event))
434 (if (and (numberp char) (= char ??)) 429 (if (and (numberp char) (= char ??))
435 (setq unread-command-char help-char char help-char))) 430 (setq unread-command-char help-char char help-char))))
436 (store-match-data data)) 431 ;; Restore the match data while we process the command.
432 (store-match-data real-match-data)
437 (cond ((or (= char ?\e) 433 (cond ((or (= char ?\e)
438 (= char ?q)) 434 (= char ?q))
439 (setq keep-going nil) 435 (setq keep-going nil)
440 (setq done t)) 436 (setq done t))
441 ((= char ?^) 437 ((= char ?^)