]> code.delx.au - gnu-emacs/blobdiff - lisp/misearch.el
Revert changes, which were committed with 2013-01-29T16:03:40Z!michael.albinus@gmx...
[gnu-emacs] / lisp / misearch.el
index 6a30d7242bd557fb6cca877f8d33c2ebc78acedc..0c4cd4ea323c386886c97c9401c257c1e741b3d9 100644 (file)
@@ -1,6 +1,6 @@
 ;;; misearch.el --- isearch extensions for multi-buffer search
 
-;; Copyright (C) 2007, 2008  Free Software Foundation, Inc.
+;; Copyright (C) 2007-2013 Free Software Foundation, Inc.
 
 ;; Author: Juri Linkov <juri@jurta.org>
 ;; Keywords: matching
@@ -66,14 +66,19 @@ at a failing search, the search goes
 to the next buffer in the series and continues searching for the
 next occurrence.
 
+This function should return the next buffer (it doesn't need to switch
+to it), or nil if it can't find the next buffer (when it reaches the
+end of the search space).
+
 The first argument of this function is the current buffer where the
 search is currently searching.  It defines the base buffer relative to
 which this function should find the next buffer.  When the isearch
-direction is backward (when `isearch-forward' is nil), this function
-should return the previous buffer to search.  If the second argument of
-this function WRAP is non-nil, then it should return the first buffer
-in the series; and for the backward search, it should return the last
-buffer in the series.")
+direction is backward (when option `isearch-forward' is nil), this function
+should return the previous buffer to search.
+
+If the second argument of this function WRAP is non-nil, then it
+should return the first buffer in the series; and for the backward
+search, it should return the last buffer in the series.")
 
 ;;;###autoload
 (defvar multi-isearch-next-buffer-current-function nil
@@ -125,19 +130,13 @@ Intended to be added to `isearch-mode-hook'."
   (lambda (string bound noerror)
     (let ((search-fun
           ;; Use standard functions to search within one buffer
-          (cond
-           (isearch-word
-            (if isearch-forward 'word-search-forward 'word-search-backward))
-           (isearch-regexp
-            (if isearch-forward 're-search-forward 're-search-backward))
-           (t
-            (if isearch-forward 'search-forward 'search-backward))))
+          (isearch-search-fun-default))
          found buffer)
       (or
        ;; 1. First try searching in the initial buffer
        (let ((res (funcall search-fun string bound noerror)))
         ;; Reset wrapping for all-buffers pause after successful search
-        (if (and res (eq multi-isearch-pause t))
+        (if (and res (not bound) (eq multi-isearch-pause t))
             (setq multi-isearch-current-buffer nil))
         res)
        ;; 2. If the above search fails, start visiting next/prev buffers
@@ -153,7 +152,7 @@ Intended to be added to `isearch-mode-hook'."
                   (while (not found)
                     ;; Find the next buffer to search
                     (setq buffer (funcall multi-isearch-next-buffer-current-function
-                                          buffer))
+                                          (or buffer (current-buffer)) nil))
                     (with-current-buffer buffer
                       (goto-char (if isearch-forward (point-min) (point-max)))
                       (setq isearch-barrier (point) isearch-opoint (point))
@@ -167,8 +166,9 @@ Intended to be added to `isearch-mode-hook'."
                   ;; Return point of the new search result
                   found)
               ;; Return nil when multi-isearch-next-buffer-current-function fails
-              (error nil))
-          (signal 'search-failed (list string "Repeat for next buffer"))))))))
+              ;; (`with-current-buffer' raises an error for nil returned from it).
+              (error (signal 'search-failed (list string "end of multi"))))
+          (signal 'search-failed (list string "repeat for next buffer"))))))))
 
 (defun multi-isearch-wrap ()
   "Wrap the multiple buffers search when search is failed.
@@ -195,7 +195,7 @@ search status stack."
   `(lambda (cmd)
      (multi-isearch-pop-state cmd ,(current-buffer))))
 
-(defun multi-isearch-pop-state (cmd buffer)
+(defun multi-isearch-pop-state (_cmd buffer)
   "Restore the multiple buffers search state.
 Switch to the buffer restored from the search status stack."
   (unless (equal buffer (current-buffer))
@@ -207,35 +207,82 @@ Switch to the buffer restored from the search status stack."
 (defvar multi-isearch-buffer-list nil)
 
 (defun multi-isearch-next-buffer-from-list (&optional buffer wrap)
-  "Return the next buffer in the series of ChangeLog file buffers.
-This function is used for multiple buffers isearch.
-A sequence of buffers is formed by ChangeLog files with decreasing
-numeric file name suffixes in the directory of the initial ChangeLog
-file were isearch was started."
+  "Return the next buffer in the series of buffers.
+This function is used for multiple buffers Isearch.  A sequence of
+buffers is defined by the variable `multi-isearch-buffer-list'
+set in `multi-isearch-buffers' or `multi-isearch-buffers-regexp'."
   (let ((buffers (if isearch-forward
                     multi-isearch-buffer-list
                   (reverse multi-isearch-buffer-list))))
     (if wrap
        (car buffers)
-      (cadr (member (or buffer (current-buffer)) buffers)))))
+      (cadr (member buffer buffers)))))
+
+(defvar ido-ignore-item-temp-list)  ; from ido.el
+
+(defun multi-isearch-read-buffers ()
+  "Return a list of buffers specified interactively, one by one."
+  ;; Most code from `multi-occur'.
+  (let* ((bufs (list (read-buffer "First buffer to search: "
+                                 (current-buffer) t)))
+        (buf nil)
+        (ido-ignore-item-temp-list bufs))
+    (while (not (string-equal
+                (setq buf (read-buffer
+                           (if (eq read-buffer-function 'ido-read-buffer)
+                               "Next buffer to search (C-j to end): "
+                             "Next buffer to search (RET to end): ")
+                           nil t))
+                ""))
+      (add-to-list 'bufs buf)
+      (setq ido-ignore-item-temp-list bufs))
+    (nreverse bufs)))
+
+(defun multi-isearch-read-matching-buffers ()
+  "Return a list of buffers whose names match specified regexp."
+  ;; Most code from `multi-occur-in-matching-buffers'
+  ;; and `kill-matching-buffers'.
+  (let ((bufregexp
+        (read-regexp "Search in buffers whose names match regexp")))
+    (when bufregexp
+      (delq nil (mapcar (lambda (buf)
+                         (when (string-match bufregexp (buffer-name buf))
+                           buf))
+                       (buffer-list))))))
 
 ;;;###autoload
 (defun multi-isearch-buffers (buffers)
-  "Start multi-buffer Isearch on a list of BUFFERS."
+  "Start multi-buffer Isearch on a list of BUFFERS.
+This list can contain live buffers or their names.
+Interactively read buffer names to search, one by one, ended with RET.
+With a prefix argument, ask for a regexp, and search in buffers
+whose names match the specified regexp."
+  (interactive
+   (list (if current-prefix-arg
+            (multi-isearch-read-matching-buffers)
+          (multi-isearch-read-buffers))))
   (let ((multi-isearch-next-buffer-function
         'multi-isearch-next-buffer-from-list)
-       (multi-isearch-buffer-list buffers))
-    (switch-to-buffer (car buffers))
+       (multi-isearch-buffer-list (mapcar #'get-buffer buffers)))
+    (switch-to-buffer (car multi-isearch-buffer-list))
     (goto-char (if isearch-forward (point-min) (point-max)))
     (isearch-forward)))
 
 ;;;###autoload
 (defun multi-isearch-buffers-regexp (buffers)
-  "Start multi-buffer regexp Isearch on a list of BUFFERS."
+  "Start multi-buffer regexp Isearch on a list of BUFFERS.
+This list can contain live buffers or their names.
+Interactively read buffer names to search, one by one, ended with RET.
+With a prefix argument, ask for a regexp, and search in buffers
+whose names match the specified regexp."
+  (interactive
+   (list (if current-prefix-arg
+            (multi-isearch-read-matching-buffers)
+          (multi-isearch-read-buffers))))
   (let ((multi-isearch-next-buffer-function
         'multi-isearch-next-buffer-from-list)
-       (multi-isearch-buffer-list buffers))
-    (switch-to-buffer (car buffers))
+       (multi-isearch-buffer-list (mapcar #'get-buffer buffers)))
+    (switch-to-buffer (car multi-isearch-buffer-list))
     (goto-char (if isearch-forward (point-min) (point-max)))
     (isearch-forward-regexp)))
 
@@ -245,11 +292,12 @@ file were isearch was started."
 (defvar multi-isearch-file-list nil)
 
 (defun multi-isearch-next-file-buffer-from-list (&optional buffer wrap)
-  "Return the next buffer in the series of ChangeLog file buffers.
-This function is used for multiple buffers isearch.
-A sequence of buffers is formed by ChangeLog files with decreasing
-numeric file name suffixes in the directory of the initial ChangeLog
-file were isearch was started."
+  "Return the next buffer in the series of file buffers.
+This function is used for multiple file buffers Isearch.  A sequence
+of files is defined by the variable `multi-isearch-file-list' set in
+`multi-isearch-files' or `multi-isearch-files-regexp'.
+Every next/previous file in the defined sequence is visited by
+`find-file-noselect' that returns the corresponding file buffer."
   (let ((files (if isearch-forward
                   multi-isearch-file-list
                 (reverse multi-isearch-file-list))))
@@ -258,28 +306,72 @@ file were isearch was started."
         (car files)
        (cadr (member (buffer-file-name buffer) files))))))
 
+(defun multi-isearch-read-files ()
+  "Return a list of files specified interactively, one by one."
+  ;; Most code from `multi-occur'.
+  (let* ((files (list (read-file-name "First file to search: "
+                                     default-directory
+                                     buffer-file-name)))
+        (file nil))
+    (while (not (string-equal
+                (setq file (read-file-name
+                            "Next file to search (RET to end): "
+                            default-directory
+                            default-directory))
+                default-directory))
+      (add-to-list 'files file))
+    (nreverse files)))
+
+(defun multi-isearch-read-matching-files ()
+  "Return a list of files whose names match specified wildcard."
+  ;; Most wildcard code from `find-file-noselect'.
+  (let ((filename (read-regexp "Search in files whose names match wildcard")))
+    (when (and filename
+              (not (string-match "\\`/:" filename))
+              (string-match "[[*?]" filename))
+      (condition-case nil
+         (file-expand-wildcards filename t)
+       (error (list filename))))))
+
 ;;;###autoload
 (defun multi-isearch-files (files)
-  "Start multi-buffer Isearch on a list of FILES."
+  "Start multi-buffer Isearch on a list of FILES.
+Relative file names in this list are expanded to absolute
+file names using the current buffer's value of `default-directory'.
+Interactively read file names to search, one by one, ended with RET.
+With a prefix argument, ask for a wildcard, and search in file buffers
+whose file names match the specified wildcard."
+  (interactive
+   (list (if current-prefix-arg
+            (multi-isearch-read-matching-files)
+          (multi-isearch-read-files))))
   (let ((multi-isearch-next-buffer-function
         'multi-isearch-next-file-buffer-from-list)
-       (multi-isearch-file-list files))
-    (find-file (car files))
+       (multi-isearch-file-list (mapcar #'expand-file-name files)))
+    (find-file (car multi-isearch-file-list))
     (goto-char (if isearch-forward (point-min) (point-max)))
     (isearch-forward)))
 
 ;;;###autoload
 (defun multi-isearch-files-regexp (files)
-  "Start multi-buffer regexp Isearch on a list of FILES."
+  "Start multi-buffer regexp Isearch on a list of FILES.
+Relative file names in this list are expanded to absolute
+file names using the current buffer's value of `default-directory'.
+Interactively read file names to search, one by one, ended with RET.
+With a prefix argument, ask for a wildcard, and search in file buffers
+whose file names match the specified wildcard."
+  (interactive
+   (list (if current-prefix-arg
+            (multi-isearch-read-matching-files)
+          (multi-isearch-read-files))))
   (let ((multi-isearch-next-buffer-function
         'multi-isearch-next-file-buffer-from-list)
-       (multi-isearch-file-list files))
-    (find-file (car files))
+       (multi-isearch-file-list (mapcar #'expand-file-name files)))
+    (find-file (car multi-isearch-file-list))
     (goto-char (if isearch-forward (point-min) (point-max)))
     (isearch-forward-regexp)))
 
 \f
 (provide 'multi-isearch)
-
-;; arch-tag: a6d38ffa-4d14-4e39-8ac6-46af9d6a6773
+(provide 'misearch)
 ;;; misearch.el ends here