Emacs Ivy interface for Mairix email message searching
Fix checkdoc errors.
Fix byte-compilation errors and some other miscellaneous things.


browse  log 



You can also use your local clone with git send-email.

#counsel-mairix - fast, real-time email searching in the minibuffer

builds.sr.ht status

counsel-mairix is an Ivy interface for rapidly going through Mairix search results. Mairix is a very fast mail searching program. Combining it with an ivy completion interface, you can search your emails interactively in the minibuffer, results update as you type. Additionally, if you're looking at an email, you can quickly insert search terms based on the email.

By default, Mairix works by saving the search results into a separate file, like a unix Mbox file, and then you point your email program to that file to display the result. This can be quite inconvenient, since you have to reopen the search mailbox every time your search query changes. Using Ivy, we can now interactively refine our search and view the results in real time.

Currently this is very much a work in progress. counsel-mairix depends on the Emacs Interface for Mairix which is bundled with Emacs. It should work out of the box by invoking M-x counsel-mairix if you have configured it properly (see Installation below).

Patches are welcome! Please note that this package is intended to be a part of GNU ELPA, thus for patches over >15 lines your FSF paperwork ought to be in order. Please mail patches to my public inbox at ~ane/public-inbox@lists.sr.ht.


Mairix running on (mostly) the September 2020 archive of emacs-devel@gnu.org in Mbox format.



A prerequisite on the system is obviously that Mairix is installed and configured properly. See (mairix-el) Configuring mairix.

Since this is still alpha quality software, it is not available in any package repository. Thus clone it somewhere in your system and add it to your load path:

(add-to-list 'load-path "<path-to-this-repo>")

You can do this using use-package:

(use-package counsel-mairix
  :load-path <path>)

If you have the Emacs Interface for Mairix configured properly then this should work without any additional configuration. Otherwise, you need to configure it. For example, if you use Mairix with Mbox format results, configure it like this:

(setq mairix-file-path "~/mail")        ;; The folder where the search file is stored
(setq mairix-search-file "search.mbox") ;; Name of the search file itself


The table below lists a summary of the functions in counsel-mairix. Please refer to their documentation in Emacs for more information.

Function Description
counsel-mairix Run mairix queries interactively
counsel-mairix-save-search Save your searches from your previous counsel-mairix searches
counsel-mairix-search-from Start a counsel-mairix search using the From: header
counsel-mairix-search-thread Start a counsel-mairix search using the Message-Id: header

#General keybindings

Binding Description
C-c C-t Toggle threading
C-c C-s i Insert saved mairix search
C-c C-s s Save current search

#Bindings when viewing an email

If you're viewing an email in one of the major modes Mairix supports, you can hit these bindings to add them to your search string:

Binding Description
C-c C-f f Yank the From value as in your search
C-c C-f s Yank the Subject value into your search
C-c C-f t Yank the To value into your search
C-c C-f i Yank the Message-Id into your search

Remember that the default binding M-j (ivy-yank-word) to yank things your cursor is on to insert it into the minibuffer.

With a negative prefix argument (M-- or C-u -), insert a negated search of the form f:~foo@bar.com which would search messages not matching that address. This also applies for avy searches below.

#avy bindings

If avy is installed, the following avy search refinements are available.

Binding Description
C-c C-a t Avy pick one To address and insert it into the search
C-c C-a c Avy pick one CC address and insert it into the search
C-c C-a s Avy pick one word from Subject and insert into the search
C-c C-a b Avy pick one word from the body and insert into the search
C-c C-a a Avy pick any word from the message and insert into the search

With the prefix argument, it will insert the respective mairix search pattern (f: for From) before the picked item. If the pattern is already inserted, the pattern is refined, i.e. if the search string is t:foo@bar.com, picking a new address xyz@zy.com will turn it into t:foo@bar.com,xyz@zy.com, unless the prefix argument is given, in which case a new pattern is inserted, turning it into t:foo@bar.com t:xyz@zy.com. This does not apply for yanking anything.

avy demo

Here, I'm interested in emacs-devel discussions about key bindings, so I start by creating a subject search term using s:. I yank the words key and bindings using avy, note that the second yank inserts a comma to create a search of the form s:key,binding which matches when both key and bindings are mentioned. Then I'm also interested in what Stefan Monnier and Eli Zaretskii have to say about it, so I insert f: and yank one of the Cc targets using C-a C-c c and then add an OR search using / and then insert the To target using C-c C-f t. Finally, I'm just interested in what Stefan and Eli have to say about it, so I toggle threads OFF using C-c C-t.


counsel-mairix defines the following customization variables:

#Custom variable: counsel-mairix-mail-frontend

Override the mail program used to create the Ivy search buffer.

This setting can override which mail program you are normally using for Mairix searches defined in mairix-mail-program. This can be useful if you want traditional Mairix searches to use some mail program (e.g. Gnus) but prefer another program to display the Ivy buffer.

It defaults to the value of mairix-mail-program.

(setq counsel-mairix-mail-frontend 'rmail)

This would force counsel-mairix to use Rmail for displaying the search buffer.

#Custom variable: counsel-mairix-include-threads

Whether to prompt for including threads in the Mairix search. Mairix.el defaults to querying every time, but I found this behaviour annoying.

Set it to

  • 'prompt to ask every time (the default)
  • t to always include threads
  • nil to never include threads.

#TODO stuff (if you feel like contributing)

Gnus and VM aren't supported as display frontends.

These could go into the ticket tracker.

Copyright © Antoine Kalmbach. Licensed under the GNU GPL version 3.