How to Use Email within Emacs

Emacs is more than just a simple text editor. It can be used to check emails too.

Emacs Email 00 Featured Image

Web email interfaces, such as Gmail, are often inefficient and insecure. All of them require you to always be connected to the Internet and do not support features such as mass tagging and filtering. However, if you’re already using Emacs to edit text, you can also use it to manage your email.

Tip: Download our Emacs keyboard shortcuts cheatsheet to increase your productivity.

Modern Email Clients and Emacs

While there are offline email clients such as Thunderbird and Evolution, these programs are often large, don’t have everything you might need, or don’t combine well with other applications.

Emacs Email 02 Evolution E Mail

For example, Evolution can accept email and your calendar but doesn’t deal with document processing, newsgroups, and to-do lists. This creates a disjointed user experience that can potentially lead to more issues in the future.

On the other hand, Emacs operates in the notion of interoperability. Within Emacs, everything can be accessed and manipulated through the same design language. The keybindings to do basic actions are the same. Further, the packages also strictly create and output text that can be used as an input in other packages.

Emacs Email 03 Interoperability

For example, if you are using gnus to read your newsgroups and Org Mode to manage your notes, you can direct a newsgroup article to an Org buffer to annotate it or save it as an inspiration.

Emacs Email 04 Emacs Gnus

Further, if you are using EMMS to manage your music, it outputs the title of the current song as text. You can link this to a blog post to highlight what you are listening to while writing.

Emacs Email 05 Emacs Emms

Emacs as an Email Client

Emacs allows you to integrate and save your email in an Org buffer to either annotate it or save it as a to-do item in a calendar.

You can also do the opposite: write an article in an Org buffer and send it, within Emacs, as an email to someone.

This is possible with the help of two programs: Offlineimap and notmuch.

  • Offlineimap is a helper program that fetches your email from a remote server and saves it on your disk. The server could either be a self-hosted one or an email service like Gmail or Protonmail.
  • Notmuch, on the other hand, is an extremely simple application that tags and displays mail. It maintains a database of all the mail that you have received and tags them according to what you have set, then displays these emails in Emacs based on those tags.

Installing Offlineimap and notmuch

To install these two applications in Debian and Ubuntu:

sudo apt install offlineimap notmuch

In Arch Linux:

sudo pacman -Syu offlineimap notmuch

In Fedora:

sudo dnf install offlineimap notmuch
Emacs Email 06 Installing Debian

After that, install the accompanying notmuch package in Emacs. It is currently available in the MELPA repository. You may need to enable it first in your Emacs configuration.

To do that, add the following lines of lisp to your init.el file:

(require 'package)
(add-to-list 'package-archives
             '("melpa" . "https://melpa.org/packages/"))
(package-initialize)

To install the notmuch package, press Alt + X and type package-install. Emacs will ask for the name of the package that you want to install. Type “notmuch.”

Once installed, this package will serve as the front end of the notmuch tagging program.

Emacs Email 07 Notmuch Melpa

Setting up Offlineimap

With that done, you can configure Offlineimap. This is a simple process that primarily involves a single file: “.offlineimaprc.”

By default, this configuration file is read from your home directory. To create it, run the following command:

touch /home/$USER/.offlineimaprc

Once done, open this file using your favorite text editor.

Emacs Email 08 Offlineimaprc

The configuration for Offlineimap is written in an INI format. For example, an .offlineimaprc for a single IMAP account could look something like this:

[general]
accounts = imapaccount
 
[Account imapaccount]
localrepository = thismachine
remoterepository = thatimap
 
[Repository thismachine]
type = Maildir
localfolders = /home/$USER/mail/youremail@domain.com
 
[Repository thatimap]
type = IMAP
remotehost = imap.domain.com
remoteuser = youremail@domain.com
remotepass = your_password_goes_here
ssl = yes
sslcacertfile = /your/ca/cert/path/here
  • The general category tells Offlineimap that you are setting a single account for this installation.
  • The Account category specifies the sources where that particular account gets its email, as well as any scripts that you want to run when Offlineimap fetches mail.
  • The Repository category will tell Offlineimap the configuration for the account you are trying to set up. The settings here will largely depend on whether or not you are using Gmail.

Email Repositories

Offlineimap works by saving the structure of a remote email directory in your local computer. This allows the program to imitate a remote IMAP server and allow email clients such as notmuch to read mail without the need to go online.

Emacs Email 09 Offlineimap

The Repository category differs whether you are setting up a local or a remote mailbox. To create a local mailbox, you only need to set its type as “Maildir.” This will tell Offlineimap that this repository will be pointing to a location in the local machine.

[Repository thismachine]
type = Maildir
localfolders = /home/$USER/mail/youremail@domain.com
Emacs Email 10 Local E Mail Directory

In contrast, setting up a remote repository can be a bit involved. However, once you understand what each value in the configuration file means, the remote setup should be very simple.

Let’s look at the Repository block example again:

[Repository thatimap]
type = IMAP
remotehost = imap.domain.com
remoteuser = youremail@domain.com
remotepass = your_password_goes_here
ssl = yes
sslcacertfile = /your/ca/cert/path/here
  • The type setting indicates the kind of server that you want Offlineimap to connect to. In this, there are only two options: Gmail for Google Mail and IMAP for non-Google accounts.
  • The remotehost setting sets the address of the IMAP server that Offlineimap connects to.
  • The remoteuser and remotepass is where you need to provide your user credentials.
  • Setting ssl to “yes” will tell Offlineimap that you want to establish an encrypted connection to the IMAP server.
  • The sslcacertfile option, then, specifies your local SSL certificate. Offlineimap will use this to verify its connection with the IMAP server.

Connecting to Gmail

As described above, Offlineimap also provides a special type for connecting to Gmail accounts, as Google requires additional information when connecting to its mail service.

Emacs Email 11 Gmail E Mail

To connect to Gmail using Offlineimap, you only need to change the type of your local and remote repositories. You need to set the local repository to “GmailMaildir” and the remote to “Gmail.”

For example, an .offlineimaprc file that connects to a Gmail service could look something like this:

[general]
accounts = gmailaccount
 
[Account gmailaccount]
localrepository = localgmail
remoterepository = remotegmail
 
[Repository localgmail]
type = GmailMaildir
localfolders = /home/$USER/mail/youremail@gmail.com
 
[Repository remotegmail]
type = Gmail
maxconnections=1
remotehost = imap.gmail.com
remoteuser = youremail@gmail.com
remotepass = your_password_goes_here
ssl = yes
sslcacertfile = /your/ca/cert/path/here

Establishing an SSL Connection

The next thing to do is configure Offlineimap to connect through SSL. To do this, you need to indicate the path to your system-wide SSL certificates.

The location of the SSL certificates will depend on the system you are running. However, in Debian and Ubuntu, it is located at the following path:

ls /etc/ssl/certs/ca-certificates.crt
Emacs Email 12 Fixed Ca Certs

You can now run offlineimap in the terminal to get all of the mail from your remote IMAP server.

Setting up notmuch

From there, proceed to the notmuch setup. Following its name, there is not much to configure with it.

Once you have your IMAP directory, you can run notmuch in the command line. This will start a configuration script that will ask about your specific email setup.

Emacs Email 13 Notmuch Start

With that, notmuch will create a configuration file in your home directory. You can check it by running the following command:

less /home/$USER/.notmuch-config
Emacs Email 14 Notmuch Config

Set a number of options that will tell notmuch where to find new mail. You can also set any tags you do not want indexed when notmuch is searching through its database.

For example, you can set it such that notmuch will not search any mail that was tagged as junk:

[search]
exclude_tags = junk

Email Tagging with notmuch

As you may have noticed, you did not set any email tags within the notmuch configuration file, as notmuch tags email directly from the command line.

This allows you to be flexible with how you want to use notmuch. For example, you can include a notmuch tagging command in a script that is periodically run as a cronjob.

Emacs Email 15 Notmuch Cron

To get started, however, you need to first initialize notmuch’s database by running the following command:

notmuch new

This will read your configuration file and create a database based on sensible defaults. From there, you can now use notmuch’s tagging commands to tag both your incoming and existing email.

Notmuch’s Tagging Syntax

The tagging syntax in notmuch is highly intuitive, and the general form looks something like this:

notmuch tag [+|-]label header:header-property (tag:current-tag)
  • The tag command tells notmuch that the following arguments will be used to create a tagging rule in your mailbox.
  • The label option specifies whether you are going to add a label (+) or remove a currently existing one (-). For example, all incoming mail is tagged with “unread” by default. You can, therefore, set this command to -unread to remove the unread tag.
  • The header option tells notmuch to only apply the label based on the email header that you have set. For example, you can use the “From:” header to filter mail based on who they are from.
  • The tag option is an optional argument that limits the application of a tagging rule to a specific tag. For example, you can set it so that notmuch will only apply a label if that particular email has an unread tag.
Emacs Email 16 Notmuch Tag

Viewing Your Email in Emacs

You can view your emails within Emacs. Do this by pressing Alt + X and typing notmuch. This will load the front-end package for notmuch in Emacs.

Emacs Email 17 Notmuch Hello

The landing screen will display a few standard tags by default. However, you can view your custom tags by clicking the “[show]” button beside “All Tags.” You can also access your tags by pressing S and typing “is:tag_name” in the command buffer.

Emacs Email 18 Notmuch Tag Screen

The standard Emacs movement and editing keys also work within notmuch. Further, there are a bunch of added features to better filter your email.

For example, trigger a “tree-style” view by pressing Shift + Z while viewing a specific tag. This is useful when you are subscribed to a mailing list since it displays the emails in easy-to-follow threads.

Emacs Email 19 Notmuch Tree View

Setting up Emacs to Send Email

You now have a working email directory that you can read within Emacs. However, you still need to set up a means to send mail. Luckily, this is surprisingly easy to do within Emacs.

To enable email support, you can add the following lines of lisp to your init.el file:

(setq mail-user-agent 'message-user-agent)
(setq message-send-mail-function 'smtpmail-send-it
      smtpmail-stream-type 'starttls
      smtpmail-smtp-server "mail.domain.com"
      smtpmail-smtp-service 587)
  • The mail-user-agent sets your user-agent variable to use Emacs’ message-user-agent. This will identify your outgoing emails to be coming from Emacs, which allows you to communicate with other mail servers.
  • The message-send-mail-function tells Emacs to use the built-in smtpmail package to properly send your emails.
  • In there, the smtpmail-stream-type indicates the kind of connection that you want Emacs to use when connecting to a remote mail server. Most mail servers currently use either SSL/TLS or STARTTLS.
  • The smtpmail-smtp-server sets the address of the SMTP server you want to connect to.
  • The smtpmail-smtp-service sets the port that Emacs is will use to send SMTP packets. If using SSL/TLS, write 465 as your SMTP port. If using STARTTLS, write 587.

Setting up Email Authentication Using .authinfo

You need to allow Emacs to send email through your mail account. Do this by appending your email credentials in .authinfo.

The .authinfo file is a hidden file that stores user credentials when logging in to remote services. For the most part, this doesn’t come by default in your Linux installation. However, you can create this file by running the following command:

touch /home/$USER/.authinfo

One important thing to note is that this file will contain sensitive information, such as your username and password. Therefore, you need to secure its access permissions so that only you can read and write to it. To do that, run the following command:

chmod 600 /home/$USER/.authinfo

From there, edit the .authinfo file to contain your mail account credentials. The general syntax of the .authinfo file looks something like this:

machine mail.domain.com login username@domain.com port 587 password mypasswordis123
  • The machine variable tells Emacs that you are connecting to a different machine or server.
  • The domain name indicates that this is the address of the machine you want to connect to.
  • The login field is where you will set your email address.
  • The port option sets the specific port you want Emacs to connect to. This should be similar to the port number you set in your init.el file.
  • The password variable contains the password of your email account.
Emacs Email 20 Authinfo

Reload Emacs to apply your new settings.

Sending Your First Email in Emacs

With that, it is extremely easy to send an email from Emacs. Do this either by pressing Ctrl + X, M or by pressing M while in the notmuch buffer.

These keybindings will execute the composemail command, which will create a message buffer with an empty heading where you can type your email.

Emacs Email 21 Compose E Mail

Once done, press Ctrl + C, Ctrl + C to send your first email from Emacs.

Congratulations! You successfully set up Emacs as an email client. Further, you also now have a basic understanding of how IMAP and SMTP servers work as well as the basics of setting up an email tagging system.

If all this talk made you interested in what else you can do with Emacs, check ut these five useful packages for this extensible text editor.

Frequently Asked Questions

1. Is it possible to automatically tag emails after I run offlineimap?

Do this by creating a notmuch post-sync hook in Offlineimap. Insert a variable under the Account category called “postsynchook”:

...
 
[Account imapaccount]
localrepository = thismachine
remoterepository = thatimap
 
postsynchook = /path/to/your/script.sh
...

This variable should contain a file path to an executable script that can contain your notmuch commands to set your tags.

For example, this is a simple post-sync script that removes the unread tag from the incoming mailing list emails and tags them appropriately:

#!/bin/sh
 
notmuch new
 
notmuch tag -inbox -unread +mailing-list from:mailing-list or to:mailing-list@domain.com tag:inbox
notmuch tag -inbox -unread +mailinglist-cmd from:mailing-list-cmd@domain.com tag:inbox

2. I wrote an email but decided I don’t want to send it. How can I discard an email in Emacs?

You can discard an email in Emacs by pressing Ctrl + C, Ctrl + D while in the message buffer. This will tag your email as a discarded draft and Emacs delete it after a period of time.

3. Is it possible to modify email tags inside notmuch in Emacs?

Yes! Do this by pressing Shift + = while inside the notmuch buffer. This opens a small command buffer where you can indicate the tags you want to add or remove from a particular email.

Subscribe to our newsletter!

Our latest tutorials delivered straight to your inbox