iobelix
iobelix

Reputation: 1225

emacs: interactively search open buffers

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.

Upvotes: 28

Views: 7292

Answers (7)

phils
phils

Reputation: 73246

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 a buffer name pattern each time is annoying).

(defun my-multi-occur-in-matching-buffers (regexp &optional allbufs)
  "Show lines matching REGEXP in all file-visiting buffers.

Given a prefix argument, search in ALL buffers."
  (interactive (occur-read-primary-args))
  (multi-occur-in-matching-buffers "." regexp allbufs))

(global-set-key (kbd "M-s /") 'my-multi-occur-in-matching-buffers)

To invert the behaviour of the prefix argument so that the default behaviour is to search all buffers, change the call to:

(multi-occur-in-matching-buffers "." regexp (not allbufs))

(and, of course, update the docstring accordingly.)

Upvotes: 36

Drew
Drew

Reputation: 30701

In Icicles, C-c ' is command icicle-occur, which can search multiple buffers.

C-u C-c ' searches a set of buffers that you choose. You can choose by dynamically filtering the buffer names with your minibuffer input, then hit C-! to search all of those buffers whose names match. Similarly, C-99 C-c ' searches only the buffers that are visiting files.

Like occur and grep, icicle-occur searches line by line. More generally, instead of using lines as the search contexts you can use any buffer portions at all. C-c ` (backquote instead of quote) is command icicle-search. With a non-negative prefix arg it searches a set of buffers that you choose.

The first thing you do is give it a regexp that defines the search contexts. E.g., if you give it .* then it acts like icicle-occur: each search context is a line. If you give it a regexp that matches only function definitions then those are the search contexts, and so on.

http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview

Upvotes: 1

offby1
offby1

Reputation: 6983

I've fixed the TODO:

;; I know that string is in my Emacs somewhere!
(require 'cl)
(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)

Upvotes: 17

scottfrazer
scottfrazer

Reputation: 17327

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.

Upvotes: 8

Trey Jackson
Trey Jackson

Reputation: 74430

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.

Upvotes: 1

Bozhidar Batsov
Bozhidar Batsov

Reputation: 56595

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!

Upvotes: 11

Paul Ellis
Paul Ellis

Reputation: 106

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).

Upvotes: 1

Related Questions