;;; Code:
-(defconst case-replace t "\
+(defvar case-replace t "\
*Non-nil means query-replace should preserve case in replacements.")
(defvar query-replace-history nil)
What you probably want is a loop like this:
(while (search-forward FROM-STRING nil t)
(replace-match TO-STRING nil t))
-which will run faster and will not set the mark or print anything."
+which will run faster and will not set the mark or print anything.
+\(You may need a more complex loop if FROM-STRING can match the null string
+and TO-STRING is also null.)"
(interactive (query-replace-read-args "Replace string" nil))
(perform-replace from-string to-string nil nil delimited))
(setq occur-mode-map (make-sparse-keymap))
(define-key occur-mode-map [mouse-2] 'occur-mode-mouse-goto)
(define-key occur-mode-map "\C-c\C-c" 'occur-mode-goto-occurrence)
- (define-key occur-mode-map "\C-m" 'occur-mode-goto-occurrence))
+ (define-key occur-mode-map "\C-m" 'occur-mode-goto-occurrence)
+ (define-key occur-mode-map "g" 'revert-buffer))
(defvar occur-buffer nil)
(defvar occur-nlines nil)
(defvar occur-pos-list nil)
+(defvar occur-command-arguments nil
+ "Arguments that were given to `occur' when it made this buffer.")
(defun occur-mode ()
"Major mode for output from \\[occur].
(use-local-map occur-mode-map)
(setq major-mode 'occur-mode)
(setq mode-name "Occur")
+ (make-local-variable 'revert-buffer-function)
+ (setq revert-buffer-function 'occur-revert-function)
(make-local-variable 'occur-buffer)
(make-local-variable 'occur-nlines)
(make-local-variable 'occur-pos-list)
+ (make-local-variable 'occur-command-arguments)
(run-hooks 'occur-mode-hook))
+;; Handle revert-buffer for *Occur* buffers.
+(defun occur-revert-function (ignore1 ignore2)
+ (let ((args occur-command-arguments ))
+ (save-excursion
+ (set-buffer occur-buffer)
+ (apply 'occur args))))
+
(defun occur-mode-mouse-goto (event)
"In Occur mode, go to the occurrence whose line you click on."
(interactive "e")
(defalias 'list-matching-lines 'occur)
+(defvar list-matching-lines-face 'bold
+ "*Face used by M-x list-matching-lines to show the text that matches.
+If the value is nil, don't highlight the matching portions specially.")
+
(defun occur (regexp &optional nlines)
"Show all lines in the current buffer containing a match for REGEXP.
The lines are shown in a buffer named `*Occur*'.
It serves as a menu to find any of the occurrences in this buffer.
-\\[describe-mode] in that buffer will explain how."
+\\[describe-mode] in that buffer will explain how.
+
+If REGEXP contains upper case characters (excluding those preceded by
+\\), the matching is case-sensitive."
(interactive
(list (let* ((default (car regexp-history))
(input
(dir default-directory)
(linenum 1)
(prevpos (point-min))
+ (case-fold-search (and case-fold-search
+ (isearch-no-upper-case-p regexp t)))
(final-context-start (make-marker)))
;;; (save-excursion
;;; (beginning-of-line)
(occur-mode)
(setq occur-buffer buffer)
(setq occur-nlines nlines)
- (setq occur-pos-list ()))
+ (setq occur-pos-list ())
+ (setq occur-command-arguments
+ (list regexp nlines)))
(if (eq buffer standard-output)
(goto-char (point-max)))
(save-excursion
(forward-line (1+ nlines))
(forward-line 1))
(point)))
+ ;; Record where the actual match
+ (match-offset
+ (save-excursion
+ (goto-char (match-beginning 0))
+ (beginning-of-line)
+ ;; +6 to skip over line number
+ (+ 6 (- (match-beginning 0) (point)))))
+ (match-len (- (match-end 0) (match-beginning 0)))
(tag (format "%5d" linenum))
(empty (make-string (length tag) ?\ ))
tem)
(insert-buffer-substring buffer start end)
(set-marker final-context-start
(- (point) (- end (match-end 0))))
- (backward-char (- end start))
+ (goto-char (- (point) (- end start)))
(setq tem nlines)
(while (> tem 0)
(insert empty ?:)
(forward-line 1)
(setq tem (1- tem)))
- (let ((this-linenum linenum))
+ (let ((this-linenum linenum)
+ line-start)
(while (< (point) final-context-start)
(if (null tag)
(setq tag (format "%5d" this-linenum)))
(insert tag ?:)
- (put-text-property (save-excursion
- (beginning-of-line)
- (point))
+ (setq line-start
+ (save-excursion
+ (beginning-of-line)
+ (point)))
+ (put-text-property line-start
(save-excursion
(end-of-line)
(point))
'mouse-face 'highlight)
+ (if list-matching-lines-face
+ (put-text-property
+ (+ line-start match-offset)
+ (+ line-start match-offset match-len)
+ 'face list-matching-lines-face))
(forward-line 1)
(setq tag nil)
(setq this-linenum (1+ this-linenum)))
;; Put positions in increasing order to go with buffer.
(setq occur-pos-list (nreverse occur-pos-list))
(goto-char (point-min))
- (if (= (length occur-pos-list) 1)
- (insert "1 line")
- (insert (format "%d lines" (length occur-pos-list))))
- (if (interactive-p)
- (message "%d matching lines." (length occur-pos-list)))))))))
+ (let ((message-string
+ (if (= (length occur-pos-list) 1)
+ "1 line"
+ (format "%d lines" (length occur-pos-list)))))
+ (insert message-string)
+ (if (interactive-p)
+ (message "%s matched" message-string)))))))))
\f
;; It would be nice to use \\[...], but there is no reasonable way
;; to make that display both SPC and Y.
(replace-match \"foobar\" nil nil))
which will run faster and probably do exactly what you want."
(or map (setq map query-replace-map))
+ (and query-flag minibuffer-auto-raise
+ (raise-frame (window-frame (minibuffer-window))))
(let ((nocasify (not (and case-fold-search case-replace
(string-equal from-string
(downcase from-string)))))
t))
;; Save the data associated with the real match.
- (setq real-match-data (match-data))
+ ;; For speed, use only integers and reuse the list used last time.
+ (setq real-match-data (match-data t real-match-data))
;; Before we make the replacement, decide whether the search string
;; can match again just after this match.
(sit-for 1)))
((eq def 'act)
(or replaced
- (replace-match next-replacement nocasify literal))
+ (progn
+ (replace-match next-replacement nocasify literal)
+ (setq replace-count (1+ replace-count))))
(setq done t replaced t))
((eq def 'act-and-exit)
(or replaced
- (replace-match next-replacement nocasify literal))
+ (progn
+ (replace-match next-replacement nocasify literal)
+ (setq replace-count (1+ replace-count))))
(setq keep-going nil)
(setq done t replaced t))
((eq def 'act-and-show)
(if (not replaced)
(progn
(replace-match next-replacement nocasify literal)
+ (setq replace-count (1+ replace-count))
(setq replaced t))))
((eq def 'automatic)
(or replaced
- (replace-match next-replacement nocasify literal))
+ (progn
+ (replace-match next-replacement nocasify literal)
+ (setq replace-count (1+ replace-count))))
(setq done t query-flag nil replaced t))
((eq def 'skip)
(setq done t))
;; since lots of markers slow down editing.
(setq stack
(cons (cons (point)
- (or replaced
- (mapcar (lambda (elt)
- (and elt
- (prog1 (marker-position elt)
- (set-marker elt nil))))
- (match-data))))
- stack))
- (if replaced (setq replace-count (1+ replace-count)))))
+ (or replaced (match-data t)))
+ stack))))
(setq lastrepl (point)))
(replace-dehighlight))
(or unread-command-events