Emacs multi-occur Search All Occurrences and List Search Results

There are different ways to perform search in Emacs, each for different purposes and scenarios. The small range search usually interactive, which means the search goes interactively like most people get used to, search one match and go next, one by one.

This usually the case for small file, search for a few occurrences. But search can also be large scale, with dozens of matches, across several buffers and files, list all occurrences for later inspection. You can also call it batched search. Both are useful for us. In command line, we usually use tool like grep to do the job. Sometimes we want to do the same thing in Emacs. And Emacs provides a lot of choices for us.

multi-occur to search selected buffers

Suppose you have a large file opened in Emacs. Even though for most people, small text file is common situation in their daily editing life, but there are cases that people have to deal with large text file and Emacs can handle it without problem, actually many average text editors were not designed for processing large text file, using them in this situation will be painful.

In Emacs I can put all my blog posts or articles in one text file and navigate through them or locate the things I want to edit easily. I can load a big list of item into Emacs and find or edit things I needed easily. Because Emacs provided with us ample of handy search facilities.

To find and edit things efficiently in those kind of situations, multi-occur is a must have command.

Execute M-x multi-occur, it will prompt you to select buffers that will be searched, press enter to select the first in candidates, press enter to select the next and so on, after selection press Ctrl-J to end the selection.

Then you can input the regular expression to conduct the search. For example the title starts with double brackets [[ and ends with ]], to list all title in the buffer you can input the regular expression

 
^\[\[
 

The search results is displayed in a new buffer, you can click the item or press Ctrl-M to jump to the line in the buffer.

occur to search current buffer

Sometimes you only interest in the current buffer you are working on, you can execute M-x occur and input or paste the query string to save some types.

Using multi-occur-in-matching-buffers to search regular expression matched buffers

This feature has some usages, such as to search all buffers with file name suffix as java. Another usage is you only remember the name string but forget which file contains it, you simply search all the buffers. The regular expression to match all buffers is ".", you execute M-x multi-occur-in-matching-buffers and input "." and then input query.

The *Occur* buffer

By default, the search results are displayed in a new buffer with name "*Occur*". That means every search will flood the result to the same buffer and overwrite the existing *Occur* buffer.

If you don't want to overwrite, which means each search result is displayed in a different buffer, you need to make sure the buffer name is different. This is done by function occur-rename-buffer. Add this line to your config file

 
(add-hook 'occur-hook (lambda () (occur-rename-buffer t)))
 

The buffer name will consists of three parts with the following pattern

 
*Occur: orginal-buffer-name*<number>
 

The occur-rename-buffer will fill the current buffer name as original-buffer-name and the rename-buffer with the third parameter not nil will generate a string such as "<2>" to make it unique. Examples:

 
*Occur: replace.el*<1>
*Occur: replace.el*<2>
*Occur: replace.el*<3>
*Occur: replace.el*<4>
 

You get create a new occur result buffer every time you perform an occur search.

I have a better idea, the buffer name should determined by original buffer name and the query input. For example, if I search "revert" in replace.el buffer, there should be only one occur buffer display the result with buffer name like

 
*Occur: replace.el*<revert>
 

I can switch to this buffer either by fuzzy matching the orginal buffer name and query or I can just execute occur with the same query without open multiple occur buffers contain exactly the same search result.