Emacs - Notmuch

Table of Contents

Introduction

Notmuch is a mail system1. It can efficiently manage a fairly large number of emails. Particularly, it supports fast email searching and filtering based on tags, which is extremely similar to Gmail's tags whereby various virtual folders can be flexibly realized.

This post is composed just to summarize the basic installation and configuration of notmuch-based mail system.

Installation

pacman -S notmuch

Configuration

~/.notmuch-config

The basic configuration can be performed by either

  • an interactive guidance which can be provoked by
notmuch setup
  • or a manually composed ~/.notmuch-config as follows
[database]
# Mail storage in maildir format
path=/MAIL/REPO

[user]
name=NAME
primary_email=EMAILADDRESS

[new]
tags=unread;inbox;
ignore=

[search]
exclude_tags=deleted;spam;

[maildir]
synchronize_flags=true

[crypto]
gpg_path=gpg

~/.emacs.d/init.el

Add following content to the configuration of Emacs.

(require 'notmuch)
(setq user-full-name "NAME"
      user-mail-address "EMAILADDRESS")

(setq mail-user-agent 'message-user-agent
      message-kill-buffer-on-exit t
      mm-text-html-renderer 'w3m)

(setq notmuch-search-oldest-first nil
      notmuch-show-all-multipart/alternative-parts nil
      mail-interactive t
      notmuch-always-prompt-for-sender nil
      notmuch-show-indent-messages-width 3)

(setq mail-specify-envelope-from t
      message-sendmail-envelope-from 'header
      mail-envelope-from 'header)

(setq message-directory "."
      notmuch-fcc-dirs ".")

(setq message-send-mail-function 'smtpmail-send-it
      smtpmail-smtp-server "SMTPSERVER"
      smtpmail-stream-type 'ssl
      smtpmail-smtp-service PORT)

(setq notmuch-saved-searches '((:name "inbox"
                                      :query "tag:inbox"
                                      :count-query "tag:inbox and tag:unread"
                                      :sort-order newest-first)

Hooks

Additionally, notmuch supports hooks which are essentially scripts in /MAIL/REPO/.notmuch/hooks whereby users can specify and customize the behaviors of notmuch. Currently, following scripts and hooks are available.

pre-new
Hook/script provoked before command notmuch new, which is usually used to fetch mails.
#!/bin/sh
/usr/bin/offlineimap -c /PATH/TO/OFFLINEIMAPRC -a ACCOUNT

or

#!/bin/sh
/usr/bin/getmail --new --getmaildir=/PATH/TO/GETMAILRC --rcfile=GETMAILRC
post-new
Hook/script provoked after command notmuch new, which is usually used to tag the newly imported mails.
#!/bin/sh
notmuch tag -inbox +ML -- to:MAILLIST@EXAMPLE.COM
notmuch tag -inbox +SOMEONE -- from:SOMEONE@EXAMPLE.COM
/usr/bin/notmuch search --output=files tag:deleted OR tag:spam | xargs -r rm
post-insert
Hook/script called after command notmuch insert, which is provoked after mails are delivered, imported into database and labelled with initial tags.
#!/bin/sh
notmuch tag -inbox -unread +sent -- from:MYEMAILADDRESS
/usr/bin/notmuch search --output=files tag:deleted OR tag:spam | xargs -r rm

Automatics

  • Add new intended task by crontab -e with following content
*/5 * * * * /usr/bin/notmuch new

where the first line is for periodical fetching mail every 3 minutes and the second line to remove the mails deleted (tagged by deleted) at every boot.

  • Enable and start the service cronie.
systemctl enable cronie.service
systemctl start cronie.service

CJK Support

By default, notmuch cannot separate Chinese correctly, Japanese, or Korean words due to the non-space separator. A workaround is to set a environment variable as follows.

export XAPIAN_CJK_NGRAM=1

Key binding

Key Function and description
n/p Next/previous message, notmuch-tree-next-matching-message
M-n/p Next/previous thread, notmuch-tree-next-thread
w Save attachments, notmuch-show-save-attachments
m Write a new mail, notmuch-mua-new-mail
r Reply a mail, notmuch-show-reply-sender
R Reply all, notmuch-show-reply
f Forward a mail, notmuch-show-forward-message
C-c C-a Attach a file, mml-attach-file
= Refresh current buffer, notmuch-refresh-this-buffer
M-= Refresh all buffer, notmuch-refresh-all-buffers
z Display threads matching query in tree view, notmuch-tree
Z Tree view for the current query, notmuch-tree-from-search-current-query
+ Change (add by default) tags for the current thread or region, notmuch-search-add-tag
- Change (remove by default) tags for the current thread or region, notmuch-search-remove-tag

Footnotes: