Notmuch logo

Notmuch is a great mail indexing tool that can also be used in conjunction with existing Mail User Agents (MUA) instead of replacing them. The advantage of such mixed solutions is that users can benefit from notmuch features (such as full-text search and thread reconstruction) without having to change MUA.

A popular geek MUA is the Mutt e-mail client; integrating notmuch with Mutt is not seamless, but fairly straightforward. There are two principal possibilities, either using a patched mutt that handles internally notmuch, or use a sets of scripts/handler within mutt to achieve something close.

  1. Using Notmuch with the good old mutt
  2. Using Notmuch with neomutt
    1. Install:
    2. Configuration:
    3. Using:
    4. Mail tagging on sending
    5. Mail filtering/tagging

Using Notmuch with the good old mutt

There's a page about the notmuch-mutt scripts that are distributed along with notmuch, in its contrib directory.

Using Notmuch with neomutt

Note: This discussion was updated by a non-mutt user from talking about mutt-kz to neomutt. Caveat lector!

Install:

See the neomutt install page. If building from source see build instructions. Note in particular the --notmuch configuration option.

Configuration:

N.B. From here is unmodified previous discussion about mutt-kz, which hopefully also applies to neomutt.

Here is my .muttrc I use with mutt-kz, explanations as comments:

    # notmuch
    set nm_default_uri="notmuch:///PATH/TO/MY/Maildir" # path to the maildir
    set virtual_spoolfile=yes                          # enable virtual folders
    set sendmail="/PATH/TO/bin/nm_sendmail"            # enables parsing of outgoing mail
    virtual-mailboxes \
        "INBOX"     "notmuch://?query=tag:INBOX and NOT tag:archive"\
        "Unread"    "notmuch://?query=tag:unread"\
        "Starred"   "notmuch://?query=tag:*"\
        "Sent"      "notmuch://?query=tag:sent"        # sets up queries for virtual folders
    # notmuch bindings
    macro index \\\\ "<vfolder-from-query>"              # looks up a hand made query
    macro index A "<modify-labels>+archive -unread -inbox<enter>"        # tag as Archived
    macro index I "<modify-labels>-inbox -unread<enter>"                 # removed from inbox
    macro index S "<modify-labels-then-hide>-inbox -unread +junk<enter>" # tag as Junk mail
    macro index + "<modify-labels>+*<enter><sync-mailbox>"               # tag as starred
    macro index - "<modify-labels>-*<enter><sync-mailbox>"               # tag as unstarred
    # sidebar
    set sidebar_width   = 20
    set sidebar_visible = yes               # set to "no" to disable sidebar view at startup
    color sidebar_new yellow default
    # sidebar bindings
    bind index <left> sidebar-prev          # got to previous folder in sidebar
    bind index <right> sidebar-next         # got to next folder in sidebar
    bind index <space> sidebar-open         # open selected folder from sidebar
    # sidebar toggle
    macro index ,@) "<enter-command> set sidebar_visible=no; macro index ~ ,@( 'Toggle sidebar'<Enter>"
    macro index ,@( "<enter-command> set sidebar_visible=yes; macro index ~ ,@) 'Toggle sidebar'<Enter>"
    macro index ~ ,@( 'Toggle sidebar'      # toggle the sidebar

There is no major difference with the standard mutt. Just a new concept (and URL) the virtual folder, that is addressed as notmuch://, a few new settings and commands.

Using:

when you open mutt you get the INBOX opened. There you can crawl through your mails, and tag them as appropriate, either manually using the " ` " command, or using the bindings defined in configuration (such as A/I/S/+/-).

Mail tagging on sending

You may have noticed in neomutts's configuration that I set the sendmail variable of mutt to a nm_sendmail script. This is for tagging outgoing mail each time I send a mail. Here is the content of the script (which may be used directly in mutt's variable, I did not try).

Source of nm_sendmail:

    #!/bin/bash
    tee >(notmuch insert --folder=Sent +sent) | sendmail $*

Mail filtering/tagging

For mail tagging on arrival, I prefer to use a simple procmail delivery along with notmuch insert.

Of course, you could use formail or maildrop, instead of procmail, but it is flexible enough for my needs, and here is an example of configuration that can be useful:

    PATH=/bin:/usr/bin:/usr/local/bin

    # ensure each mail is unique
    :0 Wh: msgid.lock
    | formail -D 8192 msgid.cache

    # update addressbook with current mail
    :0 Wh
    | /usr/local/bin/notmuch_abook update

    NOINBOX="-inbox"
    TAGS=""

    # manage dynamic tagging, using the ' + ' token in mail addresses
    # e.g.: user+TAG@fqdn.tld will generate the tag TAG
    :0:notmuch.lock
    * ^TO\/user\+[a-z0-9]+@fqdn\.tld
    * MATCH ?? ^user\+\/[a-z0-9]+
    {
    TAGS="+${MATCH}"
    }

    # match all mails from mailing-lists, don't let them go to inbox, but tag them with ml
    :0:notmuch.lock
    * ^List-[Ii][dD]:.*
    {
    TAGS="${TAGS} +ml -inbox"
    }

    # tag all mails coming from mutt-kz mailing list
    :0:notmuch.lock
    * .*mutt-kz\.lists\.fedoraproject\.org.*
    | notmuch insert $TAGS +mutt +notmuch

    # tag all mails coming from notmuch mailing list
    :0:notmuch.lock
    * .*notmuch\.notmuchmail\.org.*
    | notmuch insert $TAGS +notmuch

    # Mark all spams as junk mail
    :0:notmuch.lock
    * ^X-Spam-Status: Yes
    | notmuch insert +junk

    :0:notmuch.lock
    * ^Subject: .*SPAM.*
    | notmuch insert +junk

    ### All unmatched mails
    :0:notmuch.lock
    * .*
    | notmuch insert $TAGS

there's a line that updates the addressbook with addresses of current mail, and you'll be able to read more about it on the vimtips page.