(or emacs irrelevant)

Save Ivy file completions to Dired


I think ivy-occur (C-c C-o) is one of the coolest features in ivy. It allows you to save your current search into a new buffer. This has many uses:

  • get a full overview of all candidates
  • many useful modal bindings (q, j, k, f) and mouse support
  • ability to manipulate candidates as text
  • save the search for later, with the option to refresh the search with g
  • go over candidates as a TODO list, using C-d to remove elements

Everything above works for any ivy-read session. But the most powerful features come into play when ivy-occur gets customized for a specific collection.

ivy-occur for grep-like functions

(ivy-set-occur 'swiper 'swiper-occur)

Thanks to this default customization, the resulting *ivy-occur swiper* buffer is in ivy-occur-grep-mode which inherits from grep-mode. Additionally, you can use ivy-wgrep-change-to-wgrep-mode C-x C-q to edit the result in-place - pressing C-x C-s will save the changes.

Similar customizations are available for counsel-git-grep, counsel-ag, counsel-rg, and counsel-grep.

ivy-occur for ivy-switch-buffer

(ivy-set-occur 'ivy-switch-buffer 'ivy-switch-buffer-occur)

This makes C-c C-o open your candidates in the powerful ibuffer, which adds additional info to your buffer list and allows you to manipulate buffers easily.

For instance, to delete all matching buffers you can do C-c C-o tD.

The source code is short enough to be included here:

(defun ivy-switch-buffer-occur ()
  "Occur function for `ivy-switch-buffer' using `ibuffer'."
  (ibuffer nil (buffer-name) (list (cons 'name ivy--old-re))))

The interface is quite simple: ivy-occur is responsible for generating a new buffer, and the occur function e.g. ivy-switch-buffer-occur is to fill that buffer with useful info, based on the current search parameters like ivy-text and ivy--old-re.

ivy-occur for counsel-find-file-like functions

This is a brand new feature that works for counsel-find-file, counsel-git, and counsel-fzf (which itself is quite new, thanks to @jojojames for contributing it).

Since these functions are used to complete file names, we obviously want ivy-occur to open a Dired buffer.

Example 1

To delete all *.elc files in the current folder do:

  • C-x C-f elc$ C-c C-o tDy.

Example 2

To copy all Org files in a Git project to some directory do:

  • M-x counsel-git org$ C-c C-o tC.

Example 3

To get a list of videos to watch do:

  • M-x counsel-fzf mp4$ C-c C-o.

I can further e.g. mark 3 files with m and use r to send these 3 files to vlc as a list. See this post for my dired setup that makes r work this way.

You can remove some files afterwards with the usual D or dx. And to redisplay the buffer use g.


I hope you like the new feature. I had a really good few hours figuring out how it should work exactly. Please consider joining my 72 patrons to give me the opportunity to work on Free Software a lot more. Happy hacking!