]> code.delx.au - gnu-emacs/blobdiff - lisp/replace.el
Say "standard settings" instead of "factory settings".
[gnu-emacs] / lisp / replace.el
index 747adbe27e497656f0bb1f63733f15ea6021ffa1..30109b87ba72f4ffe4853b85a06d9c167b5ef5a8 100644 (file)
@@ -26,7 +26,7 @@
 
 ;;; Code:
 
-(defconst case-replace t "\
+(defvar case-replace t "\
 *Non-nil means query-replace should preserve case in replacements.")
 
 (defvar query-replace-history nil)
@@ -148,7 +148,9 @@ This function is usually the wrong thing to use in a Lisp program.
 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))
 
@@ -241,11 +243,14 @@ Applies to lines after point."
   (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].
@@ -258,11 +263,21 @@ Alternatively, click \\[occur-mode-mouse-goto] on an item to go to it.
   (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")
@@ -317,6 +332,10 @@ A positive number means to include that many lines both before and after.")
 
 (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.
 
@@ -329,7 +348,10 @@ Interactively it is the prefix arg.
 
 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
@@ -352,6 +374,8 @@ It serves as a menu to find any of the occurrences in this buffer.
        (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)
@@ -376,7 +400,9 @@ It serves as a menu to find any of the occurrences in this buffer.
            (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
@@ -399,6 +425,14 @@ It serves as a menu to find any of the occurrences in this buffer.
                                (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)
@@ -413,24 +447,32 @@ It serves as a menu to find any of the occurrences in this buffer.
                  (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)))
@@ -448,11 +490,13 @@ It serves as a menu to find any of the occurrences in this buffer.
            ;; 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.
@@ -511,6 +555,8 @@ just as `query-replace' does.  Instead, write a simple loop like this:
     (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)))))
@@ -562,7 +608,8 @@ which will run faster and probably do exactly what you want."
                      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.
@@ -624,21 +671,28 @@ which will run faster and probably do exactly what you want."
                         (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))
@@ -674,14 +728,8 @@ which will run faster and probably do exactly what you want."
              ;; 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