tags:

views:

125

answers:

6

Is there a way to search all the open buffers for a particular pattern?

C-s interactively searches current buffer. Similarly, is there something that searches all the open buffers?

I know I can use "occur", but "Occur" brings a new buffer and changes/messes with the buffer organization.

+1  A: 

Although this is not exactly what you're asking for, I search multiple files using grep (M-X grep) and grep-find (M-X grep-find).

Paul Ellis
+5  A: 

ibuffer might help you. Have a look at this article. I imagine that this might be most interesting for you:

'O' - ibuffer-do-occur - Do an occur on the selected buffers. This does a regex search on all the selected buffers and displays the result in an occur window. It is unbelievably useful when browsing through code. It becomes truly awesome when you combine it with the ‘filter’ powers of ibuffer (coming up ahead). Eg: Do C-x C-b, mark all files using (say) Perl major-mode, do occur to find out all places where a certain function is mentioned in these files. Navigate to the point at will through the Occur window.

'M-s a C-s' - ibuffer-do-isearch - Do an incremental search in the marked buffers. This is so awesome that you have to try it right this instant. Select two or more buffers, hit the hotkey, search for something that occurs in all these buffers. These two features alone are enough to make me a lifelong fan of IBuffer. Go do it now!

Bozhidar Batsov
You don't need ibuffer for that -- the "standard" buffer menu acts the same way: mark some buffers and do M-s a C-s (or M-x Buffer-menu-isearch-buffers). It would be nice if this functionality were generalized so that one didn't have to mark buffers. It should be easy to implement -- there exists a multi-isearch-buffers function, one just needs to supply a list of open buffers as its argument.
Leo Alekseyev
offby1's idea was the closest to my workflow. thx
Data
Zachary Young
+1  A: 

This sort of does what you want, in that when you've come to the end of matches for the string/regexp you're searching for, the next search command will start in a new buffer.

(setq isearch-wrap-function 'isearch-bury-buffer-instead-of-wrap)
(defun isearch-bury-buffer-instead-of-wrap ()
  "bury current buffer, try to search in next buffer"
  (bury-buffer))

It doesn't switch to a different buffer when the search fails, and when you "back up" the search results by pressing <backspace>, you won't pop back into the previous buffers searched.

Trey Jackson
+1  A: 

I've fixed the TODO:

;; I know that string is in my Emacs somewhere!

(defcustom search-all-buffers-ignored-files (list (rx-to-string '(and bos (or ".bash_history" "TAGS") eos)))
  "Files to ignore when searching buffers via \\[search-all-buffers]."
  :type 'editable-list)

(require 'grep)
(defun search-all-buffers (regexp prefix)
  "Searches file-visiting buffers for occurence of REGEXP.  With
prefix > 1 (i.e., if you type C-u \\[search-all-buffers]),
searches all buffers."
  (interactive (list (grep-read-regexp)
                     current-prefix-arg))
  (message "Regexp is %s; prefix is %s" regexp prefix)
  (multi-occur
   (if (member prefix '(4 (4)))
       (buffer-list)
     (remove-if
      (lambda (b) (some (lambda (rx) (string-match rx  (file-name-nondirectory (buffer-file-name b)))) search-all-buffers-ignored-files))
      (remove-if-not 'buffer-file-name (buffer-list))))

   regexp))

(global-set-key [f7] 'search-all-buffers)
offby1
Thx using it now
Data
+1  A: 

Taking a clue from Leo's comment to Bozhidar:

(defun my-isearch-buffers ()
  "isearch multiple buffers."
  (interactive)
  (multi-isearch-buffers
   (delq nil (mapcar (lambda (buf)
                       (set-buffer buf)
                       (and (not (equal major-mode 'dired-mode))
                            (not (string-match "^[ *]" (buffer-name buf)))
                            buf))
                     (buffer-list)))))

You might have to tweak the conditions inside the and to filter whatever other kinds of buffers you want to ignore.

scottfrazer
+2  A: 

The built-in multi-occur-in-matching-buffers hasn't been mentioned. I use a modified version of this (because I invariably want to search all buffers, and specifying the ".*" buffer name pattern each time is annoying)

(defun my-multi-occur-in-matching-buffers (regexp &optional allbufs)
  "Show all lines matching REGEXP in all buffers."
  (interactive (occur-read-primary-args))
  (multi-occur-in-matching-buffers ".*" regexp))
(global-set-key (kbd "M-s /") 'my-multi-occur-in-matching-buffers)
phils