< B / >

Setting Up Email in Doom Emacs with mu4e on NixOS with Home Manager

On some days I feel like I’ve dug my own grave.

My day started out in a pretty innocent way. I’m currently reading The Great CEO Within, and came across a section on Getting Things Done especially tailored towards Email.
Having an Email Client + workflow I can halfway be productive with is something that’s been on my mind for quite some time.
So I gave it another try—and immediately remembered why I’ve stopped the last few times.

What this boils down to for me is that:

  1. Email itself is tech-wise insanely complex and hard to work with
  2. It comes from a very different world. In this world, it has inherent and fatal flaws

and incentives around it make basically any startup with a decent personal offering pivot to business customers pretty fast. (or just get bought)

§ What I Want

What I want is:

  1. That it “just works”
  2. Decent speed
  3. Customizable keybindings
  4. Generally affordable (<= 5$/month)
  5. Tight integration into my other workflows

§ What the World looks like

I think you can put Email Clients in three buckets:

A. free GUI apps (e.g. Thunderbird)
B. paid apps (e.g. Superhuman)
C. free Terminal clients, and their Emacs/NeoVim counterparts (e.g. mu, notmuch)

For 1. (“just works”-ness):

  • free GUI apps work, but those are:
    • barely customizable (failing 3.)
    • and tend to be slow (failing 2.)
  • paid apps work
  • free terminal clients just don’t

For 2. and 3., there’s:

  • TUI/Emacs stuff, but that fails 1.
  • paid apps work
  • free apps don’t

The paid apps fail 4., and tight integration (5.) is hard to achieve basically anywhere except for Emacs or my shell.

This left me with either paying a lot for “just works”-ness and speed, or finally spending the time to understand Email, setting up something in my shell, and using it from Emacs.
That taken together makes it a pretty daunting task.

But this time, it didn’t stop me.

§ Understanding Email

To work with Email, you need three things:

  1. A program to sync your email from a server to a local folder
  2. A program to read/view/search your email from that folder
  3. A program to reply to emails from that folder/send new emails

The programs we’re going to use in this guide are mbsync (1.), mu (2.) and msmtp(3.).

First, we’re gonna get your system to a state you can start from, then get it to work on the command line, and only then set it up in Doom Emacs.

§ 1. Getting the system to a state you can start from

From here on, this post assumes that you’ve got:

  1. Nix installed
  2. Home Manager installed

(Since you came here you probably know it, but) The Home Manager Email Options are weird, at least at first.

The way they work is that you define an email account:

accounts.email.accounts = {
posteo = {
address = "[email protected]";
realName = "Beat Hagenlocher";
userName = "[email protected]";
passwordCommand = "cat ~/.posteopassword";
};
};

How to access the server for sending and pulling Email:

accounts.email.accounts = {
posteo = {
# ...
smtp = {
host = "posteo.de";
port = 465;
tls.enable = true;
};
imap = {
host = "posteo.de";
port = 993;
tls.enable = true;
};
};
};

As well as the configuration options per account for the tools you might use (mbsync, mu, and msmtp for us):

accounts.email.accounts = {
posteo = {
# ...
mbsync = {
enable = true;
create = "both";
remove = "both";
expunge = "both";
};
mu.enable = true;
msmtp.enable = true;
};
};

Taken together:

accounts.email.accounts = {
posteo = {
address = "[email protected]";
realName = "Beat Hagenlocher";
userName = "[email protected]";
passwordCommand = "cat ~/.posteopassword";
smtp = {
host = "posteo.de";
port = 465;
tls.enable = true;
};
imap = {
host = "posteo.de";
port = 993;
tls.enable = true;
};
mbsync = {
enable = true;
create = "both";
remove = "both";
expunge = "both";
};
mu.enable = true;
msmtp.enable = true;
};
};

Now, we only need to enable mbsync, mu and msmtp:

programs.mbsync.enable = true;
programs.msmtp.enable = true;
programs.mu.enable = true;
accounts.email.accounts = {
# ...
};

Taken together:

programs.mbsync.enable = true;
programs.msmtp.enable = true;
programs.mu.enable = true;
accounts.email.accounts = {
posteo = {
primary = true;
address = "[email protected]";
realName = "Beat Hagenlocher";
userName = "[email protected]";
passwordCommand = "cat ~/.posteopassword";
signature = {
text = ''
Liebe Grüße
Beat Hagenlocher
'';
showSignature = "append";
};
smtp = {
host = "posteo.de";
port = 465;
tls.enable = true;
};
imap = {
host = "posteo.de";
port = 993;
tls.enable = true;
};
mbsync = {
enable = true;
create = "both";
remove = "both";
expunge = "both";
patterns = [
"*"
"!Drafts"
"!Deleted Messages"
];
};
msmtp = {
enable = true;
};
};
};

Now a simple

Terminal window
home-manager switch --flake ~/nix-home/

and you should be good to go.

And since Nix sprinkles everything it touches with magic “works on every machine” sauce, this (minus correct configuration for your Email provider) should work on your machine, too.

Happy mailing :)

Actually, not yet.

There’s still the whole Doom Emacs part to be resolved.

This is what my config for that looks like:
https://github.com/haglobah/doom/blob/c4004efa3c1f9cac71252dead8f2b2765142e290/config/email.el#L5

(The workflow-relevant part being the bookmarks and this horrendous kmacro-fuckery)

If you squint a bit, you can see the Getting Things Done influence there.

But that’s for another time.

Now, finally: Happy Mailing!


In case that’s helpful, this is what my full config looks like: https://github.com/haglobah/nix-home/blob/main/home.nix#L187