Combining isearch with loccur ("interactive occur")

Tagged:  

(Maybe the following already exists - if so, please let me know in the comments.)

I'm in the process of switching from moc to EMMS, and so far I'm pretty happy with it. However, there's one feature in moc which I'm missing, and that is a special type of interactive search: While you type a search string in moc, you do not just jump to the first matching title, but the list of titles is reduced to those matching the current search. In Emacs-speak, you might name this an "interactive occur".

While I couldn't exactly find this kind of search, I stumbled upon loccur; while the the normal occur-mode opens a new buffer with the matching lines, loccur-mode works directly in the buffer you're currently working with. So, the only task remaining is to hook loccur into isearch. This is what I came up with:

(require 'loccur)
(defadvice isearch-update (after DE-call-loccur ())
  (let ((loccur-mode nil))
    (loccur-mode (regexp-quote isearch-string))))

(ad-activate 'isearch-update)
(add-hook 'isearch-mode-end-hook 
          (lambda ()
              (loccur-mode nil)))

I had to use 'defadvice' since there's no hook in isearch-update I could use instead.

Now, you only have to put loccur.el into your load-path and evaluate the above code snippet. When you now call up isearch, all lines which do not currently match your search string will be hidden. To deactivate this feature, just do

(ad-deactivate 'isearch-update)
Icicles, a great search pkg with tons of documentation, has C-c ' bound to icicle-occur, which displays a *completion* window that shows all the matching lines in the buffer as you type, interactively. You also have all the icicles search features, such as multiple regex matching (match on one regex, press Shift-space, and you can type another regex that is matched only in the lines that matched the previous one - like performing two greps in a row). With a large monitor where you normally have 2 buffer windows split vertically side-by-side, like I do, icicles work great - it uses the second window to show the completion buffer as you type and you can use C-NEXT (Page-Down) to move down the completions list, with it adjusting the edit buffer window to show the current line. If you decide to change the regex/string you're matching on after you've been moving up/down the completions list, press C-l (lowercase L) to clear the current completion and get back to the regex/string, and then continue typing. Its much harder to describe than to do. http://www.emacswiki.org/emacs/Icicles_-_Search_Commands%2c_Overview
Thanks for the pointer. I tried Icicles about two years ago. Its features are impressive, but in the end I decided that it was just "too much" for me.
I like this! I've gone ahead and added an isearch-update-post-hook so you can use that directly in bzr emacs now and in the next release of emacs later.
(autoload 'loccur-mode "loccur")
(add-hook 'isearch-update-post-hook
           (lambda ()
             (let ((loccur-mode nil))
               (loccur-mode (regexp-quote isearch-string)))))

(add-hook 'isearch-mode-end-hook
          (lambda ()
              (loccur-mode nil)))