comparison lisp/replace.el @ 388:aabb7f5b1c81 r21-2-9

Import from CVS: tag r21-2-9
author cvs
date Mon, 13 Aug 2007 11:09:42 +0200
parents a300bb07d72d
children 74fd4e045ea6
comparison
equal deleted inserted replaced
387:f892a9d0bb8d 388:aabb7f5b1c81
50 (defvar query-replace-history nil) 50 (defvar query-replace-history nil)
51 51
52 (defvar query-replace-interactive nil 52 (defvar query-replace-interactive nil
53 "Non-nil means `query-replace' uses the last search string. 53 "Non-nil means `query-replace' uses the last search string.
54 That becomes the \"string to replace\".") 54 That becomes the \"string to replace\".")
55
56 (defvar replace-search-function
57 (lambda (str limit)
58 (search-forward str limit t))
59 "Function used by perform-replace to search forward for a string. It will be
60 called with two arguments: the string to search for and a limit bounding the
61 search.")
62
63 (defvar replace-re-search-function
64 (lambda (regexp limit)
65 (re-search-forward regexp limit t))
66 "Function used by perform-replace to search forward for a regular
67 expression. It will be called with two arguments: the regexp to search for and
68 a limit bounding the search.")
55 69
56 (defun query-replace-read-args (string regexp-flag) 70 (defun query-replace-read-args (string regexp-flag)
57 (let (from to) 71 (let (from to)
58 (if query-replace-interactive 72 (if query-replace-interactive
59 (setq from (car (if regexp-flag regexp-search-ring search-ring))) 73 (setq from (car (if regexp-flag regexp-search-ring search-ring)))
207 A match split across lines preserves all the lines it lies in. 221 A match split across lines preserves all the lines it lies in.
208 Applies to all lines after point." 222 Applies to all lines after point."
209 (interactive (list (read-from-minibuffer 223 (interactive (list (read-from-minibuffer
210 "Keep lines (containing match for regexp): " 224 "Keep lines (containing match for regexp): "
211 nil nil nil 'regexp-history))) 225 nil nil nil 'regexp-history)))
212 (save-excursion 226 (with-interactive-search-caps-disable-folding regexp t
213 (or (bolp) (forward-line 1)) 227 (save-excursion
214 (let ((start (point))) 228 (or (bolp) (forward-line 1))
215 (while (not (eobp)) 229 (let ((start (point)))
216 ;; Start is first char not preserved by previous match. 230 (while (not (eobp))
217 (if (not (re-search-forward regexp nil 'move)) 231 ;; Start is first char not preserved by previous match.
218 (delete-region start (point-max)) 232 (if (not (re-search-forward regexp nil 'move))
219 (let ((end (save-excursion (goto-char (match-beginning 0)) 233 (delete-region start (point-max))
220 (beginning-of-line) 234 (let ((end (save-excursion (goto-char (match-beginning 0))
221 (point)))) 235 (beginning-of-line)
222 ;; Now end is first char preserved by the new match. 236 (point))))
223 (if (< start end) 237 ;; Now end is first char preserved by the new match.
224 (delete-region start end)))) 238 (if (< start end)
225 (setq start (save-excursion (forward-line 1) 239 (delete-region start end))))
226 (point))) 240 (setq start (save-excursion (forward-line 1)
227 ;; If the match was empty, avoid matching again at same place. 241 (point)))
228 (and (not (eobp)) (= (match-beginning 0) (match-end 0)) 242 ;; If the match was empty, avoid matching again at same place.
229 (forward-char 1)))))) 243 (and (not (eobp)) (= (match-beginning 0) (match-end 0))
244 (forward-char 1)))))))
230 245
231 (define-function 'flush-lines 'delete-matching-lines) 246 (define-function 'flush-lines 'delete-matching-lines)
232 (defun delete-matching-lines (regexp) 247 (defun delete-matching-lines (regexp)
233 "Delete lines containing matches for REGEXP. 248 "Delete lines containing matches for REGEXP.
234 If a match is split across lines, all the lines it lies in are deleted. 249 If a match is split across lines, all the lines it lies in are deleted.
235 Applies to lines after point." 250 Applies to lines after point."
236 (interactive (list (read-from-minibuffer 251 (interactive (list (read-from-minibuffer
237 "Flush lines (containing match for regexp): " 252 "Flush lines (containing match for regexp): "
238 nil nil nil 'regexp-history))) 253 nil nil nil 'regexp-history)))
239 (save-excursion 254 (with-interactive-search-caps-disable-folding regexp t
240 (while (and (not (eobp)) 255 (save-excursion
241 (re-search-forward regexp nil t)) 256 (while (and (not (eobp))
242 (delete-region (save-excursion (goto-char (match-beginning 0)) 257 (re-search-forward regexp nil t))
243 (beginning-of-line) 258 (delete-region (save-excursion (goto-char (match-beginning 0))
244 (point)) 259 (beginning-of-line)
245 (progn (forward-line 1) (point)))))) 260 (point))
261 (progn (forward-line 1) (point)))))))
246 262
247 (define-function 'how-many 'count-matches) 263 (define-function 'how-many 'count-matches)
248 (defun count-matches (regexp) 264 (defun count-matches (regexp)
249 "Print number of matches for REGEXP following point." 265 "Print number of matches for REGEXP following point."
250 (interactive (list (read-from-minibuffer 266 (interactive (list (read-from-minibuffer
251 "How many matches for (regexp): " 267 "How many matches for (regexp): "
252 nil nil nil 'regexp-history))) 268 nil nil nil 'regexp-history)))
253 (let ((count 0) opoint) 269 (with-interactive-search-caps-disable-folding regexp t
254 (save-excursion 270 (let ((count 0) opoint)
255 (while (and (not (eobp)) 271 (save-excursion
256 (progn (setq opoint (point)) 272 (while (and (not (eobp))
257 (re-search-forward regexp nil t))) 273 (progn (setq opoint (point))
258 (if (= opoint (point)) 274 (re-search-forward regexp nil t)))
259 (forward-char 1) 275 (if (= opoint (point))
260 (setq count (1+ count)))) 276 (forward-char 1)
261 (message "%d occurrences" count)))) 277 (setq count (1+ count))))
278 (message "%d occurrences" count)))))
262 279
263 280
264 (defvar occur-mode-map ()) 281 (defvar occur-mode-map ())
265 (if occur-mode-map 282 (if occur-mode-map
266 () 283 ()
443 (setq occur-buffer buffer) 460 (setq occur-buffer buffer)
444 (setq occur-nlines nlines) 461 (setq occur-nlines nlines)
445 (setq occur-pos-list ())) 462 (setq occur-pos-list ()))
446 (if (eq buffer standard-output) 463 (if (eq buffer standard-output)
447 (goto-char (point-max))) 464 (goto-char (point-max)))
448 (save-excursion 465 (with-interactive-search-caps-disable-folding regexp t
449 (if list-matching-lines-whole-buffer 466 (save-excursion
450 (beginning-of-buffer)) 467 (if list-matching-lines-whole-buffer
451 (message "Searching for %s ..." regexp) 468 (beginning-of-buffer))
452 ;; Find next match, but give up if prev match was at end of buffer. 469 (message "Searching for %s ..." regexp)
453 (while (and (not (= prevpos (point-max))) 470 ;; Find next match, but give up if prev match was at end of buffer.
454 (re-search-forward regexp nil t)) 471 (while (and (not (= prevpos (point-max)))
455 (goto-char (match-beginning 0)) 472 (re-search-forward regexp nil t))
456 (beginning-of-line) 473 (goto-char (match-beginning 0))
457 (save-match-data 474 (beginning-of-line)
458 (setq linenum (+ linenum (count-lines prevpos (point))))) 475 (save-match-data
459 (setq prevpos (point)) 476 (setq linenum (+ linenum (count-lines prevpos (point)))))
460 (goto-char (match-end 0)) 477 (setq prevpos (point))
461 (let* ((start (save-excursion 478 (goto-char (match-end 0))
462 (goto-char (match-beginning 0)) 479 (let* ((start (save-excursion
463 (forward-line (if (< nlines 0) nlines (- nlines))) 480 (goto-char (match-beginning 0))
481 (forward-line (if (< nlines 0) nlines (- nlines)))
482 (point)))
483 (end (save-excursion
484 (goto-char (match-end 0))
485 (if (> nlines 0)
486 (forward-line (1+ nlines))
487 (forward-line 1))
464 (point))) 488 (point)))
465 (end (save-excursion 489 (tag (format "%5d" linenum))
466 (goto-char (match-end 0)) 490 (empty (make-string (length tag) ?\ ))
467 (if (> nlines 0) 491 tem)
468 (forward-line (1+ nlines)) 492 (save-excursion
469 (forward-line 1)) 493 (setq tem (make-marker))
470 (point))) 494 (set-marker tem (point))
471 (tag (format "%5d" linenum)) 495 (set-buffer standard-output)
472 (empty (make-string (length tag) ?\ )) 496 (setq occur-pos-list (cons tem occur-pos-list))
473 tem) 497 (or first (zerop nlines)
474 (save-excursion 498 (insert "--------\n"))
475 (setq tem (make-marker)) 499 (setq first nil)
476 (set-marker tem (point)) 500 (insert-buffer-substring buffer start end)
477 (set-buffer standard-output) 501 (set-marker final-context-start
478 (setq occur-pos-list (cons tem occur-pos-list)) 502 (- (point) (- end (match-end 0))))
479 (or first (zerop nlines) 503 (backward-char (- end start))
480 (insert "--------\n")) 504 (setq tem (if (< nlines 0) (- nlines) nlines))
481 (setq first nil) 505 (while (> tem 0)
482 (insert-buffer-substring buffer start end)
483 (set-marker final-context-start
484 (- (point) (- end (match-end 0))))
485 (backward-char (- end start))
486 (setq tem (if (< nlines 0) (- nlines) nlines))
487 (while (> tem 0)
488 (insert empty ?:)
489 (forward-line 1)
490 (setq tem (1- tem)))
491 (let ((this-linenum linenum))
492 (while (< (point) final-context-start)
493 (if (null tag)
494 (setq tag (format "%5d" this-linenum)))
495 (insert tag ?:)
496 ;; FSFmacs -- we handle this using mode-motion-highlight-line, above.
497 ; (put-text-property (save-excursion
498 ; (beginning-of-line)
499 ; (point))
500 ; (save-excursion
501 ; (end-of-line)
502 ; (point))
503 ; 'mouse-face 'highlight)
504 (forward-line 1)
505 (setq tag nil)
506 (setq this-linenum (1+ this-linenum)))
507 (while (<= (point) final-context-start)
508 (insert empty ?:) 506 (insert empty ?:)
509 (forward-line 1) 507 (forward-line 1)
510 (setq this-linenum (1+ this-linenum)))) 508 (setq tem (1- tem)))
511 (while (< tem nlines) 509 (let ((this-linenum linenum))
512 (insert empty ?:) 510 (while (< (point) final-context-start)
513 (forward-line 1) 511 (if (null tag)
514 (setq tem (1+ tem))) 512 (setq tag (format "%5d" this-linenum)))
515 (goto-char (point-max))) 513 (insert tag ?:)
516 (forward-line 1))) 514 ;; FSFmacs --
517 (set-buffer standard-output) 515 ;; we handle this using mode-motion-highlight-line, above.
518 ;; Put positions in increasing order to go with buffer. 516 ;; (put-text-property (save-excursion
519 (setq occur-pos-list (nreverse occur-pos-list)) 517 ;; (beginning-of-line)
520 (goto-char (point-min)) 518 ;; (point))
521 (if (= (length occur-pos-list) 1) 519 ;; (save-excursion
522 (insert "1 line") 520 ;; (end-of-line)
523 (insert (format "%d lines" (length occur-pos-list)))) 521 ;; (point))
524 (if (interactive-p) 522 ;; 'mouse-face 'highlight)
525 (message "%d matching lines." (length occur-pos-list))))))) 523 (forward-line 1)
524 (setq tag nil)
525 (setq this-linenum (1+ this-linenum)))
526 (while (<= (point) final-context-start)
527 (insert empty ?:)
528 (forward-line 1)
529 (setq this-linenum (1+ this-linenum))))
530 (while (< tem nlines)
531 (insert empty ?:)
532 (forward-line 1)
533 (setq tem (1+ tem)))
534 (goto-char (point-max)))
535 (forward-line 1)))
536 (set-buffer standard-output)
537 ;; Put positions in increasing order to go with buffer.
538 (setq occur-pos-list (nreverse occur-pos-list))
539 (goto-char (point-min))
540 (if (= (length occur-pos-list) 1)
541 (insert "1 line")
542 (insert (format "%d lines" (length occur-pos-list))))
543 (if (interactive-p)
544 (message "%d matching lines." (length occur-pos-list))))))))
526 545
527 ;; It would be nice to use \\[...], but there is no reasonable way 546 ;; It would be nice to use \\[...], but there is no reasonable way
528 ;; to make that display both SPC and Y. 547 ;; to make that display both SPC and Y.
529 (defconst query-replace-help 548 (defconst query-replace-help
530 (purecopy 549 (purecopy
602 "Subroutine of `query-replace'. Its complexity handles interactive queries. 621 "Subroutine of `query-replace'. Its complexity handles interactive queries.
603 Don't use this in your own program unless you want to query and set the mark 622 Don't use this in your own program unless you want to query and set the mark
604 just as `query-replace' does. Instead, write a simple loop like this: 623 just as `query-replace' does. Instead, write a simple loop like this:
605 (while (re-search-forward \"foo[ \t]+bar\" nil t) 624 (while (re-search-forward \"foo[ \t]+bar\" nil t)
606 (replace-match \"foobar\" nil nil)) 625 (replace-match \"foobar\" nil nil))
607 which will run faster and probably do exactly what you want." 626 which will run faster and probably do exactly what you want.
627 When searching for a match, this function use `replace-search-function' and `replace-re-search-function'"
608 (or map (setq map query-replace-map)) 628 (or map (setq map query-replace-map))
609 (let* ((event (make-event)) 629 (let* ((event (make-event))
610 (nocasify (not (and case-fold-search case-replace 630 (nocasify (not (and case-fold-search case-replace
611 (string-equal from-string 631 (string-equal from-string
612 (downcase from-string))))) 632 (downcase from-string)))))
613 (literal (not regexp-flag)) 633 (literal (not regexp-flag))
614 (search-function (if regexp-flag 're-search-forward 'search-forward)) 634 (search-function (if regexp-flag
635 replace-re-search-function
636 replace-search-function))
615 (search-string from-string) 637 (search-string from-string)
616 (real-match-data nil) ; the match data for the current match 638 (real-match-data nil) ; the match data for the current match
617 (next-replacement nil) 639 (next-replacement nil)
618 (replacement-index 0) 640 (replacement-index 0)
619 (keep-going t) 641 (keep-going t)
644 (zmacs-deactivate-region)) 666 (zmacs-deactivate-region))
645 (if (stringp replacements) 667 (if (stringp replacements)
646 (setq next-replacement replacements) 668 (setq next-replacement replacements)
647 (or repeat-count (setq repeat-count 1))) 669 (or repeat-count (setq repeat-count 1)))
648 (if delimited-flag 670 (if delimited-flag
649 (setq search-function 're-search-forward 671 (setq search-function replace-re-search-function
650 search-string (concat "\\b" 672 search-string (concat "\\b"
651 (if regexp-flag from-string 673 (if regexp-flag from-string
652 (regexp-quote from-string)) 674 (regexp-quote from-string))
653 "\\b"))) 675 "\\b")))
654 (push-mark) 676 (push-mark)
656 (unwind-protect 678 (unwind-protect
657 ;; Loop finding occurrences that perhaps should be replaced. 679 ;; Loop finding occurrences that perhaps should be replaced.
658 (while (and keep-going 680 (while (and keep-going
659 (not (eobp)) 681 (not (eobp))
660 (let ((case-fold-search qr-case-fold-search)) 682 (let ((case-fold-search qr-case-fold-search))
661 (funcall search-function search-string limit t)) 683 (funcall search-function search-string limit))
662 ;; If the search string matches immediately after 684 ;; If the search string matches immediately after
663 ;; the previous match, but it did not match there 685 ;; the previous match, but it did not match there
664 ;; before the replacement was done, ignore the match. 686 ;; before the replacement was done, ignore the match.
665 (if (or (eq lastrepl (point)) 687 (if (or (eq lastrepl (point))
666 (and regexp-flag 688 (and regexp-flag
670 nil 692 nil
671 ;; Don't replace the null string 693 ;; Don't replace the null string
672 ;; right after end of previous replacement. 694 ;; right after end of previous replacement.
673 (forward-char 1) 695 (forward-char 1)
674 (let ((case-fold-search qr-case-fold-search)) 696 (let ((case-fold-search qr-case-fold-search))
675 (funcall search-function search-string limit t))) 697 (funcall search-function search-string limit)))
676 t)) 698 t))
677 699
678 ;; Save the data associated with the real match. 700 ;; Save the data associated with the real match.
679 (setq real-match-data (match-data)) 701 (setq real-match-data (match-data))
680 702