Skip to content

Latest commit

 

History

History
364 lines (238 loc) · 14.5 KB

Emacs-Mail-01.org

File metadata and controls

364 lines (238 loc) · 14.5 KB

Streamline Your E-mail Management with mu4e

mu4e is an excellent e-mail client

https://www.djcbsoftware.nl/code/mu/mu4e.html

  • Emacs interface for the mu mail indexer
  • Highly efficient for keyboard users
  • Syncs your e-mail in the background using an external program
  • Powerful search interface
  • Can manage multiple e-mail accounts

Today we’ll cover syncing your e-mail and how you can read and manage it all with mu4e.

Future episodes will cover topics like multiple e-mail accounts, composing e-mail, Org Mode integration, and more.

IMPORTANT NOTE: I’m using Ubuntu 20 for this demonstration, it has an older mu4e version (1.2.0). Some things may be different in the newest version, I will discuss difference where appropriate.

Syncing your mail

Configuring mbsync

Today we’ll sync a Gmail account since they’re pretty common. In another episode we’ll show a more traditional IMAP account too.

We’ll use a program called isync (in practice it’s mbsync!) to sync our mail. You can also use a program called offlineimap, it’s a bit slower but it works on Windows too. We’ll cover it in another video.

Install it:

sudo apt install isync

Set up an initial configuration at ~/.mbsyncrc:

IMAPAccount gmail
Host imap.gmail.com
User systemcrafters.test@gmail.com
PassCmd "cat ~/.oh-no-insecure-password"
SSLType IMAPS
CertificateFile /etc/ssl/certs/ca-certificates.crt

IMAPStore gmail-remote
Account gmail

MaildirStore gmail-local
Subfolders Verbatim
Path ~/Mail/
Inbox ~/Mail/Inbox

Channel gmail
Master :gmail-remote:
Slave :gmail-local:
Patterns * ![Gmail]* "[Gmail]/Sent Mail" "[Gmail]/Starred" "[Gmail]/All Mail" "[Gmail]/Trash"
Create Both
SyncState *

NOTE: Be careful of how you manage whitespace between lines in this file, the spaces define groupings!

Settings you may need to change:

  • PassCmd - We’re getting the contents of a plain text file here, you might want to use gpg!
  • Pass - If you want to use plaintext password (not recommended!), doesn’t need quotation marks
  • CertificateFile - This location can vary based on your Linux distribution!
  • Patterns - Defines which folders will be synced
    NOTE: Non-English users might need to pay extra attention to the Patterns line since Gmail renames the IMAP folders based on the selected user interface language one uses in the Gmail web interface. In Dutch e.g. the folder [Gmail]/Starred would need to be changed to [Gmail]/Met ster. Changing the Patterns line to * and running the command mbsync --list gmail might give some insight into which folders are available. Unfortunately the mapping does not appear to be one to one, e.g. the label Sent is shown as Verzonden in Dutch while mbsync reports [Gmail]/Verzonden berichten as the name of the IMAP folder. Furthermore similar changes need to be made to the mu4e configuration below.

For the security conscious:

  • Use GPG to decrypt an encrypted password file: gpg --quiet --for-your-eyes-only --no-tty --decrypt ~/.passwords/gmail.gpg
  • Use the Password Store program to simplify this: pass Mail/MyGmail

Enable IMAP for your Gmail account

IMAP e-mail access is not enabled on your Gmail account by default! Follow these steps to enable it:

https://support.google.com/mail/answer/7126229?hl=en

Make sure to configure these settings!

  • “Auto-expunge off”
  • “Move the message to the trash”

Enable access for mbsync

This can go one of two ways:

You have two-factor authentication turned on:

If you have two-factor authentication turned on, you will need to create an App Password to access your account. More details can be found at this link:

https://support.google.com/accounts/answer/185833

No two-factor authentication: enable “Less secure apps” for your Google account

If you don’t have two-factor authentication turned on, Google will still automatically block “less secure” apps like isync from accessing your mail over IMAP. Give access to mbsync by going to the following page:

https://myaccount.google.com/lesssecureapps

Start the initial sync

You might receive a scary e-mail from Google the first time you run this, just open it and confirm that it was you who tried to use the account!

mbsync -a

NOTE: mbsync won’t create the base maildir for you, you’ll have to create it: mkdir ~/Mail

Setting up mu to index the mailbox

Install it on Ubuntu via the mu4e package (it’s actually the dependency maildir-utils but we need mu4e anyway):

sudo apt install mu4e

Run the initial index, providing your e-mail address so it knows how to identify you:

mu index --maildir=~/Mail --my-address=systemcrafters.test@gmail.com

NOTE: You will need to use --my-address for every e-mail address you use in a multiple account setup.

Indexing could take a while depending on how much e-mail you have, but it’s quite fast in general.

NOTE: Starting with version 1.3.8, mu index doesn’t accept these arguments anymore. You need to run:

mu init --maildir=~/Mail --my-address=systemcrafters.test@gmail.com

And then:

mu index

You only need to run mu init again if you wish to change your maildir or your addresses.

Setting up mu4e

Before we do this though, turn off evil-collection for mu4e.

NOTE: I’m only doing this to show the normal Emacs bindings, don’t do this if you want to use Evil bindings!

(delete 'mu4e evil-collection-mode-list)
(delete 'mu4e-conversation evil-collection-mode-list)

Add the initial mu4e configuration:

(use-package mu4e
  :ensure nil
  ;; :load-path "/usr/share/emacs/site-lisp/mu4e/"
  ;; :defer 20 ; Wait until 20 seconds after startup
  :config

  ;; This is set to 't' to avoid mail syncing issues when using mbsync
  (setq mu4e-change-filenames-when-moving t)

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

  (setq mu4e-drafts-folder "/[Gmail]/Drafts")
  (setq mu4e-sent-folder   "/[Gmail]/Sent Mail")
  (setq mu4e-refile-folder "/[Gmail]/All Mail")
  (setq mu4e-trash-folder  "/[Gmail]/Trash")

  (setq mu4e-maildir-shortcuts
      '(("/Inbox"             . ?i)
        ("/[Gmail]/Sent Mail" . ?s)
        ("/[Gmail]/Trash"     . ?t)
        ("/[Gmail]/Drafts"    . ?d)
        ("/[Gmail]/All Mail"  . ?a))))

NOTE: In the stream, I had trouble getting mail to sync in other folders. The problem was that I had configured the folder names wrong with mu4e! I was using /[Gmail].Trash where it should have been /[Gmail]/Trash. Simple explanation for an annoying problem!

IMPORTANT NOTE: As of mu4e 1.3.7, mu4e-maildir-shortcuts now has a new format! Here is the equivalent:

(setq mu4e-maildir-shortcuts
    '((:maildir "/Inbox"    :key ?i)
      (:maildir "/[Gmail]/Sent Mail" :key ?s)
      (:maildir "/[Gmail]/Trash"     :key ?t)
      (:maildir "/[Gmail]/Drafts"    :key ?d)
      (:maildir "/[Gmail]/All Mail"  :key ?a))))

More Gmail configuration tips: https://www.djcbsoftware.nl/code/mu/mu4e/Gmail-configuration.html

Managing your e-mail

Reading mail

Run mu4e, see the landing page.

When reading mail, you start out in the Headers buffer. When you select an email with RET, the View buffer is displayed in a window below the Headers buffer window.

Headers Mode

Key Bindings:

KeyEvilCommandDescription
Movement
C-njnext-lineMoves to the next header line
C-pkprevious-lineMoves to the previous header line
[[[[mu4e-headers-prev-unreadMoves to previous unread message
]]]]mu4e-headers-next-unreadMoves to next unread message
jJmu4e~headers-jump-to-maildirJump to another mail directory
Toggles
Pztmu4e-headers-toggle-threadingToggles threaded message display
Wzrmu4e-headers-toggle-include-relatedToggles related message display
Marking
ddmu4e-headers-mark-for-trashMarks message for deletion
mmmu4e-headers-mark-for-moveMarks message for move to folder
++mu4e-headers-mark-for-flagMarks message for flagging
--mu4e-headers-mark-for-unflagMarks message for unflagging
%%mu4e-headers-mark-patternMarks based on a regex pattern
uumu4e-headers-mark-for-unmarkRemoves mark for message
UUmu4e-mark-unmark-allUnmarks all marks in the view
xxmu4e-mark-execute-allExecutes all marks in the view
Searching
ssmu4e-headers-searchSearch all e-mails
SSmu4e-headers-search-editEdit current search (useful!)
//mu4e-headers-search-narrowNarrow down the current results
bbmu4e-headers-search-bookmarkSelect a bookmark to search with
BBmu4e-headers-search-bookmark-editEdit bookmark before search
ggrmu4e-rerun-searchRerun the current search
Composing
CC, ccmu4e-compose-newCompose a new e-mail
RR, crmu4e-compose-replyCompose a reply to selected email
FF, cfmu4e-compose-forwardCompose a forward for selected email
EE, cemu4e-compose-editEdit selected draft message
Other Actions
qqmu4e~headers-quit-bufferQuit the headers view

Controlling the number of messages visible:

  • mu4e-headers-results-limit: The number of messages to display in mail listings (default 500)
  • mu4e-headers-full-search: If t, shows all messages, ignoring limit

You can toggle mu4e-headers-full-search with M-x mu4e-headers-toggle-full-search!

View Mode

Many of the same keybindings work! Marking keys work on the currently viewed message.

KeyEvilCommandDescription
Movement
C-njnext-lineMoves to the next line in message
C-pkprevious-lineMoves to the previous line in message
nC-jmu4e-view-headers-nextMoves to next email in header list
pC-kmu4e-view-headers-prevMoves to previous email in header list
[[[[mu4e-headers-prev-unreadMoves to previous unread message
]]]]mu4e-headers-next-unreadMoves to next unread message

Syncing e-mail

Run M-x mu4e-update-mail-and-index to sync and index your e-mail at any time (bind it to a key!)

To auto-sync your mail at an interval, add this to mu4e config:

;; Run mu4e in the background to sync mail periodically
(mu4e t)

When doing this, it’s also good to :defer your mu4e config so that it doesn’t run immediately at startup:

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

  ... the rest ...

Search queries

  • something - General text search for “something”
  • from:stallman - Emails from a particular sender
  • date:today..now - Date range
  • flag:attach - Emails with an attachment
  • =”maildir:/Inbox”= - Search in a specific mail directory

You can also use logic statements like and , not:

=”maildir:/Inbox” and from:eli and docs=

Documentation: https://www.djcbsoftware.nl/code/mu/mu4e/Queries.html

Bookmarking queries

You can create your own bookmarked queries!

Run these from anywhere in Emacs with M-x mu4e-headers-search-bookmark

In mu4e 1.2.0:

(setq mu4e-bookmarks
  '(("flag:unread AND NOT flag:trashed" "Unread messages"      ?i)
    ("date:today..now"                  "Today's messages"     ?t)
    ("from:stallman"                    "The Boss"             ?s)
    ("date:7d..now"                     "Last 7 days"          ?w)
    ("mime:image/*"                     "Messages with images" ?p)))

As of mu4e 1.3.7:

(setq mu4e-bookmarks
  '((:name "Unread messages" :query "flag:unread AND NOT flag:trashed" :key ?i)
    (:name "Today's messages" :query "date:today..now" :key ?t)
    (:name "The Boss" :query "from:stallman" :key ?s)
    (:name "Last 7 days" :query "date:7d..now" :hide-unread t :key ?w)
    (:name "Messages with images" :query "mime:image/*" :key ?p)))