Mercurial > hg > xemacs-beta
comparison lisp/prim/replace.el @ 72:b9518feda344 r20-0b31
Import from CVS: tag r20-0b31
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:03:46 +0200 |
parents | 131b0175ea99 |
children | 54cc21c15cbb |
comparison
equal
deleted
inserted
replaced
71:bae944334fa4 | 72:b9518feda344 |
---|---|
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of | 13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of |
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 ;; General Public License for more details. | 15 ;; General Public License for more details. |
16 | 16 |
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 XEmacs; see the file COPYING. If not, write to the | 18 ;; along with XEmacs; see the file COPYING. If not, write to the Free |
19 ;; Free Software Foundation, 59 Temple Place - Suite 330, | 19 ;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA |
20 ;; Boston, MA 02111-1307, USA. | 20 ;; 02111-1307, USA. |
21 | 21 |
22 ;;; Synched up with: FSF 19.30. | 22 ;;; Synched up with: FSF 19.34 [Partially]. |
23 | 23 |
24 ;;; Commentary: | 24 ;;; Commentary: |
25 | 25 |
26 ;; This package supplies the string and regular-expression replace functions | 26 ;; This package supplies the string and regular-expression replace functions |
27 ;; documented in the XEmacs Reference Manual. | 27 ;; documented in the XEmacs Reference Manual. |
28 | 28 |
29 ;; All the gettext calls are for XEmacs I18N3 message catalog support. | |
30 | |
29 ;;; Code: | 31 ;;; Code: |
30 | 32 |
31 (defvar case-replace t "\ | 33 (defconst case-replace t "\ |
32 *Non-nil means `query-replace' should preserve case in replacements. | 34 *Non-nil means `query-replace' should preserve case in replacements. |
33 What this means is that `query-replace' will change the case of the | 35 What this means is that `query-replace' will change the case of the |
34 replacement text so that it matches the text that was replaced. | 36 replacement text so that it matches the text that was replaced. |
35 If this variable is nil, the replacement text will be inserted | 37 If this variable is nil, the replacement text will be inserted |
36 exactly as it was specified by the user, irrespective of the case | 38 exactly as it was specified by the user, irrespective of the case |
143 | 145 |
144 (defun replace-string (from-string to-string &optional delimited) | 146 (defun replace-string (from-string to-string &optional delimited) |
145 "Replace occurrences of FROM-STRING with TO-STRING. | 147 "Replace occurrences of FROM-STRING with TO-STRING. |
146 Preserve case in each match if `case-replace' and `case-fold-search' | 148 Preserve case in each match if `case-replace' and `case-fold-search' |
147 are non-nil and FROM-STRING has no uppercase letters. | 149 are non-nil and FROM-STRING has no uppercase letters. |
150 \(Preserving case means that if the string matched is all caps, or capitalized, | |
151 then its replacement is upcased or capitalized.) | |
152 | |
148 Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace | 153 Third arg DELIMITED (prefix arg if interactive), if non-nil, means replace |
149 only matches surrounded by word boundaries. | 154 only matches surrounded by word boundaries. |
150 | 155 |
151 If `query-replace-interactive' is non-nil, the last incremental search | 156 If `query-replace-interactive' is non-nil, the last incremental search |
152 string is used as FROM-STRING--you don't have to specify it with the | 157 string is used as FROM-STRING--you don't have to specify it with the |
250 | 255 |
251 (defvar occur-mode-map ()) | 256 (defvar occur-mode-map ()) |
252 (if occur-mode-map | 257 (if occur-mode-map |
253 () | 258 () |
254 (setq occur-mode-map (make-sparse-keymap)) | 259 (setq occur-mode-map (make-sparse-keymap)) |
255 (set-keymap-name occur-mode-map 'occur-mode-map) | 260 (set-keymap-name occur-mode-map 'occur-mode-map) ; XEmacs |
256 (define-key occur-mode-map 'button2 'occur-mode-mouse-goto) | 261 (define-key occur-mode-map [mouse-2] 'occur-mode-mouse-goto) |
257 (define-key occur-mode-map "\C-c\C-c" 'occur-mode-goto-occurrence) | 262 (define-key occur-mode-map "\C-c\C-c" 'occur-mode-goto-occurrence) |
258 (define-key occur-mode-map "\C-m" 'occur-mode-goto-occurrence)) | 263 (define-key occur-mode-map "\C-m" 'occur-mode-goto-occurrence)) |
259 | 264 |
260 (defvar occur-buffer nil) | 265 (defvar occur-buffer nil) |
261 (defvar occur-nlines nil) | 266 (defvar occur-nlines nil) |
269 | 274 |
270 \\{occur-mode-map}" | 275 \\{occur-mode-map}" |
271 (kill-all-local-variables) | 276 (kill-all-local-variables) |
272 (use-local-map occur-mode-map) | 277 (use-local-map occur-mode-map) |
273 (setq major-mode 'occur-mode) | 278 (setq major-mode 'occur-mode) |
274 (setq mode-name (gettext "Occur")) | 279 (setq mode-name (gettext "Occur")) ; XEmacs |
275 (make-local-variable 'occur-buffer) | 280 (make-local-variable 'occur-buffer) |
276 (make-local-variable 'occur-nlines) | 281 (make-local-variable 'occur-nlines) |
277 (make-local-variable 'occur-pos-list) | 282 (make-local-variable 'occur-pos-list) |
278 (require 'mode-motion) | 283 (require 'mode-motion) ; XEmacs |
279 (setq mode-motion-hook 'mode-motion-highlight-line) | 284 (setq mode-motion-hook 'mode-motion-highlight-line) ; XEmacs |
280 (run-hooks 'occur-mode-hook)) | 285 (run-hooks 'occur-mode-hook)) |
281 | 286 |
282 (defun occur-mode-mouse-goto (e) | 287 ;; FSF Version of next function: |
288 ; (let (buffer pos) | |
289 ; (save-excursion | |
290 ; (set-buffer (window-buffer (posn-window (event-end event)))) | |
291 ; (save-excursion | |
292 ; (goto-char (posn-point (event-end event))) | |
293 ; (setq pos (occur-mode-find-occurrence)) | |
294 ; (setq buffer occur-buffer))) | |
295 ; (pop-to-buffer buffer) | |
296 ; (goto-char (marker-position pos)))) | |
297 | |
298 (defun occur-mode-mouse-goto (event) | |
283 "Go to the occurrence highlighted by mouse. | 299 "Go to the occurrence highlighted by mouse. |
284 This function is only reasonable when bound to a mouse key in the occur buffer" | 300 This function is only reasonable when bound to a mouse key in the occur buffer" |
285 (interactive "e") | 301 (interactive "e") |
286 (let ((window-save (selected-window)) | 302 (let ((window-save (selected-window)) |
287 (frame-save (selected-frame))) | 303 (frame-save (selected-frame))) |
291 (mouse-set-point e) | 307 (mouse-set-point e) |
292 (occur-mode-goto-occurrence)) | 308 (occur-mode-goto-occurrence)) |
293 (select-frame frame-save) | 309 (select-frame frame-save) |
294 (select-window window-save)))) | 310 (select-window window-save)))) |
295 | 311 |
312 ;; Called occur-mode-find-occurrence in FSF | |
296 (defun occur-mode-goto-occurrence () | 313 (defun occur-mode-goto-occurrence () |
297 "Go to the occurrence the current line describes." | 314 "Go to the occurrence the current line describes." |
298 (interactive) | 315 (interactive) |
299 (if (or (null occur-buffer) | 316 (if (or (null occur-buffer) |
300 (null (buffer-name occur-buffer))) | 317 (null (buffer-name occur-buffer))) |
321 (occur-source-buffer occur-buffer)) | 338 (occur-source-buffer occur-buffer)) |
322 (if (< line-count 1) | 339 (if (< line-count 1) |
323 (error "No occurrence on this line")) | 340 (error "No occurrence on this line")) |
324 (or pos | 341 (or pos |
325 (error "No occurrence on this line")) | 342 (error "No occurrence on this line")) |
326 ;; don't raise window unless it isn't visible | 343 ;; XEmacs: don't raise window unless it isn't visible |
327 ;; allow for the possibility that the occur buffer is on another frame | 344 ;; allow for the possibility that the occur buffer is on another frame |
328 (or (and window | 345 (or (and window |
329 (window-live-p window) | 346 (window-live-p window) |
330 (frame-visible-p (window-frame window)) | 347 (frame-visible-p (window-frame window)) |
331 (set-buffer occur-source-buffer)) | 348 (set-buffer occur-source-buffer)) |
342 | 359 |
343 ;; XEmacs addition | 360 ;; XEmacs addition |
344 ;;; Damn you Jamie, this is utter trash. | 361 ;;; Damn you Jamie, this is utter trash. |
345 (defvar list-matching-lines-whole-buffer t | 362 (defvar list-matching-lines-whole-buffer t |
346 "If t, occur operates on whole buffer, otherwise occur starts from point. | 363 "If t, occur operates on whole buffer, otherwise occur starts from point. |
347 default is nil.") | 364 default is t.") |
348 | 365 |
349 (define-function 'occur 'list-matching-lines) | 366 (define-function 'occur 'list-matching-lines) |
350 (defun list-matching-lines (regexp &optional nlines) | 367 (defun list-matching-lines (regexp &optional nlines) |
351 "Show all lines in the current buffer containing a match for REGEXP. | 368 "Show all lines in the current buffer containing a match for REGEXP. |
352 | 369 |
353 If a match spreads across multiple lines, all those lines are shown. | 370 If a match spreads across multiple lines, all those lines are shown. |
354 | 371 |
355 If variable `list-matching-lines-whole-buffer' is non-nil, the entire buffer is | 372 If variable `list-matching-lines-whole-buffer' is non-nil, the entire buffer is |
356 searched, otherwise search begins at point. | 373 searched, otherwise search begins at point. |
357 | 374 |
358 Each line is displayed with NLINES lines before and after, | 375 Each line is displayed with NLINES lines before and after, or -NLINES |
359 or -NLINES before if NLINES is negative. | 376 before if NLINES is negative. |
360 NLINES defaults to `list-matching-lines-default-context-lines'. | 377 NLINES defaults to `list-matching-lines-default-context-lines'. |
361 Interactively it is the prefix arg. | 378 Interactively it is the prefix arg. |
362 | 379 |
363 The lines are shown in a buffer named `*Occur*'. | 380 The lines are shown in a buffer named `*Occur*'. |
364 It serves as a menu to find any of the occurrences in this buffer. | 381 It serves as a menu to find any of the occurrences in this buffer. |
365 \\[describe-mode] in that buffer will explain how." | 382 \\[describe-mode] in that buffer will explain how." |
366 (interactive | 383 (interactive |
384 ;; XEmacs change | |
367 (list (let* ((default (or (symbol-near-point) | 385 (list (let* ((default (or (symbol-near-point) |
368 (and regexp-history | 386 (and regexp-history |
369 (car regexp-history)))) | 387 (car regexp-history)))) |
370 (minibuffer-history-minimum-string-length 0) | 388 (minibuffer-history-minimum-string-length 0) |
371 (input | 389 (input |
394 (let ((first t) | 412 (let ((first t) |
395 (dir default-directory) | 413 (dir default-directory) |
396 (buffer (current-buffer)) | 414 (buffer (current-buffer)) |
397 (linenum 1) | 415 (linenum 1) |
398 (prevpos (point-min)) | 416 (prevpos (point-min)) |
417 ;; The rest of this function is very different from FSF. | |
418 ;; Presumably that's due to Jamie's misfeature | |
399 (final-context-start (make-marker))) | 419 (final-context-start (make-marker))) |
400 (if (not list-matching-lines-whole-buffer) | 420 (if (not list-matching-lines-whole-buffer) |
401 (save-excursion | 421 (save-excursion |
402 (beginning-of-line) | 422 (beginning-of-line) |
403 (setq linenum (1+ (count-lines (point-min) (point)))) | 423 (setq linenum (1+ (count-lines (point-min) (point)))) |
418 (if (eq buffer standard-output) | 438 (if (eq buffer standard-output) |
419 (goto-char (point-max))) | 439 (goto-char (point-max))) |
420 (save-excursion | 440 (save-excursion |
421 (if list-matching-lines-whole-buffer | 441 (if list-matching-lines-whole-buffer |
422 (beginning-of-buffer)) | 442 (beginning-of-buffer)) |
423 (message "Searching for %s ..." regexp) | 443 (message (format "Searching for %s ..." regexp)) |
424 ;; Find next match, but give up if prev match was at end of buffer. | 444 ;; Find next match, but give up if prev match was at end of buffer. |
425 (while (and (not (= prevpos (point-max))) | 445 (while (and (not (= prevpos (point-max))) |
426 (re-search-forward regexp nil t)) | 446 (re-search-forward regexp nil t)) |
427 (goto-char (match-beginning 0)) | 447 (goto-char (match-beginning 0)) |
428 (beginning-of-line) | 448 (beginning-of-line) |
496 (if (interactive-p) | 516 (if (interactive-p) |
497 (message "%d matching lines." (length occur-pos-list))))))) | 517 (message "%d matching lines." (length occur-pos-list))))))) |
498 | 518 |
499 ;; It would be nice to use \\[...], but there is no reasonable way | 519 ;; It would be nice to use \\[...], but there is no reasonable way |
500 ;; to make that display both SPC and Y. | 520 ;; to make that display both SPC and Y. |
501 (defvar query-replace-help (purecopy | 521 (defconst query-replace-help |
502 "Type Space or `y' to replace one match, Delete or `n' to skip to next, | 522 (purecopy |
523 "Type Space or `y' to replace one match, Delete or `n' to skip to next, | |
503 RET or `q' to exit, Period to replace one match and exit, | 524 RET or `q' to exit, Period to replace one match and exit, |
504 Comma to replace but not move point immediately, | 525 Comma to replace but not move point immediately, |
505 C-r to enter recursive edit (\\[exit-recursive-edit] to get out again), | 526 C-r to enter recursive edit (\\[exit-recursive-edit] to get out again), |
506 C-w to delete match and recursive edit, | 527 C-w to delete match and recursive edit, |
507 C-l to clear the frame, redisplay, and offer same replacement again, | 528 C-l to clear the frame, redisplay, and offer same replacement again, |
508 ! to replace all remaining matches with no more questions, | 529 ! to replace all remaining matches with no more questions, |
509 ^ to move point back to previous match.") | 530 ^ to move point back to previous match." |
531 ) | |
510 "Help message while in query-replace") | 532 "Help message while in query-replace") |
511 | 533 |
512 (defvar query-replace-map nil | 534 (defvar query-replace-map nil |
513 "Keymap that defines the responses to questions in `query-replace'. | 535 "Keymap that defines the responses to questions in `query-replace'. |
514 The \"bindings\" in this map are not commands; they are answers. | 536 The \"bindings\" in this map are not commands; they are answers. |
515 The valid answers include `act', `skip', `act-and-show', | 537 The valid answers include `act', `skip', `act-and-show', |
516 `exit', `act-and-exit', `edit', `delete-and-edit', `recenter', | 538 `exit', `act-and-exit', `edit', `delete-and-edit', `recenter', |
517 `automatic', `backup', `exit-prefix', and `help'.") | 539 `automatic', `backup', `exit-prefix', and `help'.") |
518 | 540 |
541 ;; Why does it seem that ever file has a different method of doing this? | |
519 (if query-replace-map | 542 (if query-replace-map |
520 nil | 543 nil |
521 (let ((map (make-sparse-keymap))) | 544 (let ((map (make-sparse-keymap))) |
522 (set-keymap-name map 'query-replace-map) | 545 (set-keymap-name map 'query-replace-map) |
523 (define-key map " " 'act) | 546 (define-key map " " 'act) |
550 (setq query-replace-map map))) | 573 (setq query-replace-map map))) |
551 | 574 |
552 | 575 |
553 (autoload 'isearch-highlight "isearch") | 576 (autoload 'isearch-highlight "isearch") |
554 | 577 |
578 ;; XEmacs | |
555 (defun perform-replace-next-event (event) | 579 (defun perform-replace-next-event (event) |
556 (if isearch-highlight | 580 (if isearch-highlight |
557 (let ((aborted t)) | 581 (let ((aborted t)) |
558 (unwind-protect | 582 (unwind-protect |
559 (progn | 583 (progn |
573 (replace-match \"foobar\" nil nil)) | 597 (replace-match \"foobar\" nil nil)) |
574 which will run faster and probably do exactly what you want." | 598 which will run faster and probably do exactly what you want." |
575 (or map (setq map query-replace-map)) | 599 (or map (setq map query-replace-map)) |
576 (let* ((event (make-event)) | 600 (let* ((event (make-event)) |
577 (nocasify (not (and case-fold-search case-replace | 601 (nocasify (not (and case-fold-search case-replace |
578 (string-equal from-string | 602 (string-equal from-string |
579 (downcase from-string))))) | 603 (downcase from-string))))) |
580 (literal (not regexp-flag)) | 604 (literal (not regexp-flag)) |
581 (search-function (if regexp-flag 're-search-forward 'search-forward)) | 605 (search-function (if regexp-flag 're-search-forward 'search-forward)) |
582 (search-string from-string) | 606 (search-string from-string) |
583 (real-match-data nil) ; the match data for the current match | 607 (real-match-data nil) ; the match data for the current match |
584 (next-replacement nil) | 608 (next-replacement nil) |
607 (if regexp-flag from-string | 631 (if regexp-flag from-string |
608 (regexp-quote from-string)) | 632 (regexp-quote from-string)) |
609 "\\b"))) | 633 "\\b"))) |
610 (push-mark) | 634 (push-mark) |
611 (undo-boundary) | 635 (undo-boundary) |
612 ;; Loop finding occurrences that perhaps should be replaced. | 636 (unwind-protect |
613 (while (and keep-going | 637 ;; Loop finding occurrences that perhaps should be replaced. |
614 (not (eobp)) | 638 (while (and keep-going |
615 (let ((case-fold-search qr-case-fold-search)) | 639 (not (eobp)) |
616 (funcall search-function search-string nil t)) | 640 (let ((case-fold-search qr-case-fold-search)) |
617 ;; If the search string matches immediately after | 641 (funcall search-function search-string nil t)) |
618 ;; the previous match, but it did not match there | 642 ;; If the search string matches immediately after |
619 ;; before the replacement was done, ignore the match. | 643 ;; the previous match, but it did not match there |
620 (if (or (eq lastrepl (point)) | 644 ;; before the replacement was done, ignore the match. |
621 (and regexp-flag | 645 (if (or (eq lastrepl (point)) |
622 (eq lastrepl (match-beginning 0)) | 646 (and regexp-flag |
623 (not match-again))) | 647 (eq lastrepl (match-beginning 0)) |
624 | 648 (not match-again))) |
625 (if (eobp) | 649 (if (eobp) |
626 nil | 650 nil |
627 ;; Don't replace the null string | 651 ;; Don't replace the null string |
628 ;; right after end of previous replacement. | 652 ;; right after end of previous replacement. |
629 (forward-char 1) | 653 (forward-char 1) |
630 (let ((case-fold-search qr-case-fold-search)) | 654 (let ((case-fold-search qr-case-fold-search)) |
631 (funcall search-function search-string nil t))) | 655 (funcall search-function search-string nil t))) |
632 t)) | 656 t)) |
633 ;; Save the data associated with the real match. | 657 |
634 (setq real-match-data (match-data)) | 658 ;; Save the data associated with the real match. |
635 | 659 (setq real-match-data (match-data)) |
636 ;; Before we make the replacement, decide whether the search string | 660 |
637 ;; can match again just after this match. | 661 ;; Before we make the replacement, decide whether the search string |
638 (if regexp-flag | 662 ;; can match again just after this match. |
639 (progn | 663 (if regexp-flag |
640 (setq match-again (looking-at search-string)) | 664 (progn |
641 (store-match-data real-match-data))) | 665 (setq match-again (looking-at search-string)) |
642 | 666 ;; XEmacs addition |
643 ;; If time for a change, advance to next replacement string. | 667 (store-match-data real-match-data))) |
644 (if (and (listp replacements) | 668 ;; If time for a change, advance to next replacement string. |
645 (= next-rotate-count replace-count)) | 669 (if (and (listp replacements) |
646 (progn | 670 (= next-rotate-count replace-count)) |
647 (setq next-rotate-count | 671 (progn |
648 (+ next-rotate-count repeat-count)) | 672 (setq next-rotate-count |
649 (setq next-replacement (nth replacement-index replacements)) | 673 (+ next-rotate-count repeat-count)) |
650 (setq replacement-index (% (1+ replacement-index) (length replacements))))) | 674 (setq next-replacement (nth replacement-index replacements)) |
651 (if (not query-flag) | 675 (setq replacement-index (% (1+ replacement-index) (length replacements))))) |
652 (progn | 676 (if (not query-flag) |
653 (store-match-data real-match-data) | 677 (progn |
654 (replace-match next-replacement nocasify literal) | 678 (store-match-data real-match-data) |
655 (setq replace-count (1+ replace-count))) | 679 (replace-match next-replacement nocasify literal) |
656 (undo-boundary) | 680 (setq replace-count (1+ replace-count))) |
657 (let ((help-form | 681 (undo-boundary) |
658 '(concat (format "Query replacing %s%s with %s.\n\n" | 682 (let ((help-form |
659 (if regexp-flag (gettext "regexp ") "") | 683 '(concat (format "Query replacing %s%s with %s.\n\n" |
660 from-string next-replacement) | 684 (if regexp-flag (gettext "regexp ") "") |
661 (substitute-command-keys query-replace-help))) | 685 from-string next-replacement) |
662 (done nil) | 686 (substitute-command-keys query-replace-help))) |
663 (replaced nil) | 687 done replaced def) |
664 def) | 688 ;; Loop reading commands until one of them sets done, |
665 ;; Loop reading commands until one of them sets done, | 689 ;; which means it has finished handling this occurrence. |
666 ;; which means it has finished handling this occurrence. | 690 (while (not done) |
667 (while (not done) | 691 ;; Don't fill up the message log |
668 ;; Don't fill up the message log | 692 ;; with a bunch of identical messages. |
669 ;; with a bunch of identical messages. | 693 ;; XEmacs change |
670 (display-message 'prompt | 694 (display-message 'prompt |
671 (format message from-string next-replacement)) | 695 (format message from-string next-replacement)) |
672 (perform-replace-next-event event) | 696 (perform-replace-next-event event) |
673 (setq def (lookup-key map (vector event))) | 697 (setq def (lookup-key map (vector event))) |
674 ;; Restore the match data while we process the command. | 698 ;; Restore the match data while we process the command. |
675 (store-match-data real-match-data) | 699 (store-match-data real-match-data) |
676 (cond ((eq def 'help) | 700 (cond ((eq def 'help) |
677 (with-output-to-temp-buffer (gettext "*Help*") | 701 (with-output-to-temp-buffer (gettext "*Help*") |
678 (princ (concat | 702 (princ (concat |
679 (format "Query replacing %s%s with %s.\n\n" | 703 (format "Query replacing %s%s with %s.\n\n" |
680 (if regexp-flag "regexp " "") | 704 (if regexp-flag "regexp " "") |
681 from-string next-replacement) | 705 from-string next-replacement) |
682 (substitute-command-keys | 706 (substitute-command-keys |
683 query-replace-help))) | 707 query-replace-help))) |
684 (save-excursion | 708 (save-excursion |
685 (set-buffer standard-output) | 709 (set-buffer standard-output) |
686 (help-mode)))) | 710 (help-mode)))) |
687 ((eq def 'exit) | 711 ((eq def 'exit) |
688 (setq keep-going nil) | 712 (setq keep-going nil) |
689 (setq done t)) | 713 (setq done t)) |
690 ((eq def 'backup) | 714 ((eq def 'backup) |
691 (if stack | 715 (if stack |
692 (let ((elt (car stack))) | 716 (let ((elt (car stack))) |
693 (goto-char (car elt)) | 717 (goto-char (car elt)) |
694 (setq replaced (eq t (cdr elt))) | 718 (setq replaced (eq t (cdr elt))) |
695 (or replaced | 719 (or replaced |
696 (store-match-data (cdr elt))) | 720 (store-match-data (cdr elt))) |
697 (setq stack (cdr stack))) | 721 (setq stack (cdr stack))) |
698 (progn | |
699 (message "No previous match") | 722 (message "No previous match") |
700 (ding 'no-terminate) | 723 (ding 'no-terminate) |
701 (sit-for 1)))) | 724 (sit-for 1))) |
702 ((eq def 'act) | 725 ((eq def 'act) |
703 (or replaced | 726 (or replaced |
704 (replace-match next-replacement nocasify literal)) | 727 (replace-match next-replacement nocasify literal)) |
705 (setq done t replaced t)) | 728 (setq done t replaced t)) |
706 ((eq def 'act-and-exit) | 729 ((eq def 'act-and-exit) |
707 (or replaced | 730 (or replaced |
708 (replace-match next-replacement nocasify literal)) | 731 (replace-match next-replacement nocasify literal)) |
709 (setq keep-going nil) | 732 (setq keep-going nil) |
710 (setq done t replaced t)) | 733 (setq done t replaced t)) |
711 ((eq def 'act-and-show) | 734 ((eq def 'act-and-show) |
712 (if (not replaced) | 735 (if (not replaced) |
713 (progn | 736 (progn |
714 (replace-match next-replacement nocasify literal) | 737 (replace-match next-replacement nocasify literal) |
715 (setq replaced t)))) | 738 (setq replaced t)))) |
716 ((eq def 'automatic) | 739 ((eq def 'automatic) |
717 (or replaced | 740 (or replaced |
718 (replace-match next-replacement nocasify literal)) | 741 (replace-match next-replacement nocasify literal)) |
719 (setq done t query-flag nil replaced t)) | 742 (setq done t query-flag nil replaced t)) |
720 ((eq def 'skip) | 743 ((eq def 'skip) |
721 (setq done t)) | 744 (setq done t)) |
722 ((eq def 'recenter) | 745 ((eq def 'recenter) |
723 (recenter nil)) | 746 (recenter nil)) |
724 ((eq def 'edit) | 747 ((eq def 'edit) |
725 (store-match-data | 748 (store-match-data |
726 (prog1 (match-data) | 749 (prog1 (match-data) |
727 (save-excursion (recursive-edit)))) | 750 (save-excursion (recursive-edit)))) |
728 ;; Before we make the replacement, | 751 ;; Before we make the replacement, |
729 ;; decide whether the search string | 752 ;; decide whether the search string |
730 ;; can match again just after this match. | 753 ;; can match again just after this match. |
731 (if regexp-flag | 754 (if regexp-flag |
732 (setq match-again (looking-at search-string)))) | 755 (setq match-again (looking-at search-string)))) |
733 ((eq def 'delete-and-edit) | 756 ((eq def 'delete-and-edit) |
734 (delete-region (match-beginning 0) (match-end 0)) | 757 (delete-region (match-beginning 0) (match-end 0)) |
735 (store-match-data (prog1 (match-data) | 758 (store-match-data (prog1 (match-data) |
736 (save-excursion (recursive-edit)))) | 759 (save-excursion (recursive-edit)))) |
737 (setq replaced t)) | 760 (setq replaced t)) |
738 ;; Note: we do not need to treat `exit-prefix' | 761 ;; Note: we do not need to treat `exit-prefix' |
739 ;; specially here, since we reread | 762 ;; specially here, since we reread |
740 ;; any unrecognized character. | 763 ;; any unrecognized character. |
741 (t | 764 (t |
742 (setq this-command 'mode-exited) | 765 (setq this-command 'mode-exited) |
743 (setq keep-going nil) | 766 (setq keep-going nil) |
744 (setq unread-command-events | 767 (setq unread-command-events |
745 (cons event unread-command-events)) | 768 (cons event unread-command-events)) |
746 (setq done t)))) | 769 (setq done t)))) |
747 ;; Record previous position for ^ when we move on. | 770 ;; Record previous position for ^ when we move on. |
748 ;; Change markers to numbers in the match data | 771 ;; Change markers to numbers in the match data |
749 ;; since lots of markers slow down editing. | 772 ;; since lots of markers slow down editing. |
750 (setq stack | 773 (setq stack |
751 (cons (cons (point) | 774 (cons (cons (point) |
752 (or replaced | 775 (or replaced |
753 (mapcar | 776 (mapcar |
754 #'(lambda (elt) | 777 #'(lambda (elt) |
755 (if (markerp elt) | 778 (if (markerp elt) |
756 (prog1 (marker-position elt) | 779 (prog1 (marker-position elt) |
757 (set-marker elt nil)) | 780 (set-marker elt nil)) |
758 elt)) | 781 elt)) |
759 (match-data)))) | 782 (match-data)))) |
760 stack)) | 783 stack)) |
761 (if replaced (setq replace-count (1+ replace-count))))) | 784 (if replaced (setq replace-count (1+ replace-count))))) |
762 (setq lastrepl (point))) | 785 (setq lastrepl (point))) |
786 (replace-dehighlight)) | |
763 (or unread-command-events | 787 (or unread-command-events |
764 (message "Replaced %d occurrence%s" | 788 (message "Replaced %d occurrence%s" |
765 replace-count | 789 replace-count |
766 (if (= replace-count 1) "" "s"))) | 790 (if (= replace-count 1) "" "s"))) |
767 (and keep-going stack))) | 791 (and keep-going stack))) |
768 | 792 |
769 ; FSF 19.30 original: | 793 (defvar query-replace-highlight nil |
770 ; (defun match-string (num &optional string) | 794 "*Non-nil means to highlight words during query replacement.") |
771 ; "Return string of text matched by last search. | 795 |
772 ; NUM specifies which parenthesized expression in the last regexp. | 796 (defvar replace-overlay nil) |
773 ; Value is nil if NUMth pair didn't match, or there were less than NUM pairs. | 797 |
774 ; Zero means the entire text matched by the whole regexp or whole string. | 798 (defun replace-dehighlight () |
775 ; STRING should be given if the last search was by `string-match' on STRING." | 799 (and replace-overlay |
776 ; (if (match-beginning num) | 800 (progn |
777 ; (if string | 801 (delete-overlay replace-overlay) |
778 ; (substring string (match-beginning num) (match-end num)) | 802 (setq replace-overlay nil)))) |
779 ; (buffer-substring (match-beginning num) (match-end num))))) | 803 |
780 | 804 (defun replace-highlight (start end) |
781 ;; #### - this could stand to be in C... | 805 (and query-replace-highlight |
782 (defmacro match-string (n &optional string) | 806 (progn |
783 "Returns the Nth subexpression matched by the last regular expression | 807 (or replace-overlay |
784 search. The second argument, STRING, must be specified if the last | 808 (progn |
785 regular expression search was done with `string-match'." | 809 (setq replace-overlay (make-overlay start end)) |
786 ;; #### - note that match-beginning is byte coded, so it's more efficient | 810 (overlay-put replace-overlay 'face |
787 ;; to just call it twice than it is to let-bind its return value... --Stig | 811 (if (internal-find-face 'query-replace) |
788 `(and (match-beginning ,n) | 812 'query-replace 'region)))) |
789 ,(if string | 813 (move-overlay replace-overlay start end (current-buffer))))) |
790 `(substring ,string (match-beginning ,n) (match-end ,n)) | 814 |
791 `(buffer-substring (match-beginning ,n) (match-end ,n))))) | 815 (defun match-string (num &optional string) |
816 "Return string of text matched by last search. | |
817 NUM specifies which parenthesized expression in the last regexp. | |
818 Value is nil if NUMth pair didn't match, or there were less than NUM pairs. | |
819 Zero means the entire text matched by the whole regexp or whole string. | |
820 STRING should be given if the last search was by `string-match' on STRING." | |
821 (if (match-beginning num) | |
822 (if string | |
823 (substring string (match-beginning num) (match-end num)) | |
824 (buffer-substring (match-beginning num) (match-end num))))) | |
792 | 825 |
793 (defmacro save-match-data (&rest body) | 826 (defmacro save-match-data (&rest body) |
794 "Execute BODY forms, restoring the global value of the match data." | 827 "Execute BODY forms, restoring the global value of the match data." |
795 (let ((original (make-symbol "match-data"))) | 828 (let ((original (make-symbol "match-data"))) |
796 (list 'let (list (list original '(match-data))) | 829 (list 'let (list (list original '(match-data))) |