The path to GNUrvana

Mail Configuration

Mail in Emacs with mu4e

mu4e is the best mail interface I've ever used because it's fast and makes it really easy to power through a huge e-mail backlog. Love the ability to capture links to emails with org-mode too.

Useful mu4e manual pages:

(use-package mu4e
  :defer 20 ; Wait until 20 seconds after startup

  ;; Load org-mode integration
  (require 'org-mu4e)

  ;; Refresh mail using isync every 10 minutes
  (setq mu4e-update-interval (* 10 60))
  (setq mu4e-get-mail-command "mbsync -a")
  (setq mu4e-maildir "~/Mail")

  ;; Use Ivy for mu4e completions (maildir folders, etc)
  (setq mu4e-completing-read-function #'ivy-completing-read)

  ;; Make sure that moving a message (like to Trash) causes the
  ;; message to get a new file name.  This helps to avoid the
  ;; dreaded "UID is N beyond highest assigned" error.
  ;; See this link for more info: https://stackoverflow.com/a/43461973
  (setq mu4e-change-filenames-when-moving t)

  ;; Set up contexts for email accounts
  (setq mu4e-contexts
            :name "Fastmail"
            :match-func (lambda (msg) (when msg
                                        (string-prefix-p "/Fastmail" (mu4e-message-field msg :maildir))))
            :vars '(
                    (user-full-name . "David Wilson")
                    (user-mail-address . "david@daviwil.com")
                    (mu4e-sent-folder . "/Fastmail/Sent Items")
                    (mu4e-trash-folder . "/Fastmail/Trash")
                    (mu4e-drafts-folder . "/Fastmail/Drafts")
                    (mu4e-refile-folder . "/Fastmail/Archive")
                    (mu4e-sent-messages-behavior . sent)
            :name "Personal"
            :match-func (lambda (msg) (when msg
                                        (string-prefix-p "/Personal" (mu4e-message-field msg :maildir))))
            :vars '(
                    (mu4e-sent-folder . "/Personal/Sent")
                    (mu4e-trash-folder . "/Personal/Deleted")
                    (mu4e-refile-folder . "/Personal/Archive")
  (setq mu4e-context-policy 'pick-first)

  ;; Prevent mu4e from permanently deleting trashed items
  ;; This snippet was taken from the following article:
  ;; http://cachestocaches.com/2017/3/complete-guide-email-emacs-using-mu-and-/
  (defun remove-nth-element (nth list)
    (if (zerop nth) (cdr list)
      (let ((last (nthcdr (1- nth) list)))
        (setcdr last (cddr last))
  (setq mu4e-marks (remove-nth-element 5 mu4e-marks))
  (add-to-list 'mu4e-marks
                 :char ("d" . "▼")
                 :prompt "dtrash"
                 :dyn-target (lambda (target msg) (mu4e-get-trash-folder msg))
                 :action (lambda (docid msg target)
                           (mu4e~proc-move docid
                                           (mu4e~mark-check-target target) "-N"))))

  ;; Display options
  (setq mu4e-view-show-images t)
  (setq mu4e-view-show-addresses 't)

  ;; Composing mail
  (setq mu4e-compose-dont-reply-to-self t)

  ;; Use mu4e for sending e-mail
  (setq mail-user-agent 'mu4e-user-agent
        message-send-mail-function 'smtpmail-send-it
        smtpmail-smtp-server "smtp.fastmail.com"
        smtpmail-smtp-service 465
        smtpmail-stream-type  'ssl)

  ;; Signing messages (use mml-secure-sign-pgpmime)
  (setq mml-secure-openpgp-signers '("53C41E6E41AAFE55335ACA5E446A2ED4D940BF14"))

  ;; (See the documentation for `mu4e-sent-messages-behavior' if you have
  ;; additional non-Gmail addresses and want assign them different
  ;; behavior.)

  ;; setup some handy shortcuts
  ;; you can quickly switch to your Inbox -- press ``ji''
  ;; then, when you want archive some messages, move them to
  ;; the 'All Mail' folder by pressing ``ma''.
  (setq mu4e-maildir-shortcuts
        '(("/Fastmail/INBOX"       . ?i)
          ("/Fastmail/Lists/*"     . ?l)
          ("/Fastmail/Sent Mail"   . ?s)
          ("/Fastmail/Trash"       . ?t)))

  (add-to-list 'mu4e-bookmarks
                :name "All Inboxes"
                :query "maildir:/Fastmail/INBOX OR maildir:/Personal/Inbox"
                :key ?i))

  ;; don't keep message buffers around
  (setq message-kill-buffer-on-exit t)

  (setq dw/mu4e-inbox-query
        "(maildir:/Personal/Inbox OR maildir:/Fastmail/INBOX) AND flag:unread")

  (defun dw/go-to-inbox ()
    (mu4e-headers-search dw/mu4e-inbox-query))

    "m"  '(:ignore t :which-key "mail")
    "mm" 'mu4e
    "mc" 'mu4e-compose-new
    "mi" 'dw/go-to-inbox
    "ms" 'mu4e-update-mail-and-index)

  ;; Start mu4e in the background so that it syncs mail periodically
  (mu4e t))

Use mu4e-alert to show notifications when e-mail comes in:

(use-package mu4e-alert
  :after mu4e
  ;; Show unread emails from all inboxes
  (setq mu4e-alert-interesting-mail-query dw/mu4e-inbox-query)

  ;; Show notifications for mails already notified
  (setq mu4e-alert-notify-repeated-mails nil)


Provide the dw-mail package so that it can be require'd:

(provide 'dw-mail)

Mail Synchronization

Configuration docs: https://manpages.debian.org/unstable/isync/mbsync.1.en.html

IMAPAccount fastmail
Host imap.fastmail.com
Port 993
User daviwil@fastmail.fm
PassCmd "pass Mail/Fastmail/daviwil"
SSLVersions TLSv1.2
CertificateFile /etc/ssl/certs/ca-certificates.crt

# Define the remote from which mail will be synced
IMAPStore fastmail-remote
Account fastmail

# Define where mail will be stored
MaildirStore fastmail-local
Path ~/Mail/Fastmail/
Inbox ~/Mail/Fastmail/INBOX/
Trash ~/Mail/Fastmail/Trash/
SubFolders Verbatim

# Connect the remote and the local maildir
Channel fastmail
Master :fastmail-remote:
Slave :fastmail-local:
Patterns * !"Archive/*"
Expunge None
CopyArrivalDate yes
Sync All
Create Slave
SyncState *