The thought to migrate to Nix and home-manager was based on the complexity of setting up the previous email configuration. Let's see if Nix makes things better.

mu

For some reason, I decided to start in the middle. Let's try to replace maildir-utils (as it's called in the Ubuntu repositories) with mu (as it's called ni nixpkgs). There is a home-manager option that is directly on point:

programs.mu.enable = true;
❯ home-manager switch
...
❯ which mu
/home/shaun/.nix-profile/bin/mu

Ok, now we uninstall maildir-utils:

❯ sudo apt remove maildir-utils                                                       21:35:00
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following packages were automatically installed and are no longer required:
  guile-2.2-libs libgc1 libxapian30
Use 'sudo apt autoremove' to remove them.
The following packages will be REMOVED:
  maildir-utils mu4e
0 upgraded, 0 newly installed, 2 to remove and 5 not upgraded.
After this operation, 1,867 kB disk space will be freed.
Do you want to continue? [Y/n]
(Reading database ... 309390 files and directories currently installed.)
Removing mu4e (1.4.13-1) ...
Removing maildir-utils (1.4.13-1) ...
Processing triggers for man-db (2.9.3-2) ...
Processing triggers for install-info (6.7.0.dfsg.2-5) ...
install-info: warning: no info dir entry in `/usr/share/info/automake-history.info.gz'
Processing triggers for libc-bin (2.32-0ubuntu3) ...

This removed mu4e, but it's still loaded in Emacs, so let's try loading the inbox and trying to refresh the inbox. Uh-oh:

error in process filter: mu4e-error: [mu4e] Please set `mu4e-mu-binary' to the full path to the mu binary.

That should be easy enough to fix. It also looks like home-manager installed these at ~/.nix-profile/share/emacs/site-lisp/mu4e/, so we'll update ~/.emacs.d/site-lisp/init-mail.el:

(use-package mu4e
  :ensure nil
  :load-path "~/.nix-profile/share/emacs/site-lisp/mu4e/" ;; this line for mu4e
  :bind (("<f12>" . 'mu4e))
  :config
  (add-to-list 'mu4e-bookmarks
               '(:name "Inbox"
                       :key ?i
                       :query "maildir:/Inbox and not flag:trashed"))
  :custom
  (mu4e-get-mail-command "mbsync -qq fastmail")
  (mu4e-mu-binary "/home/shaun/.nix-profile/bin/mu") ;; this line for mu location
  (mu4e-headers-date-format "%d-%m-%Y %H:%M")
  (mu4e-change-filenames-when-moving t)
  (mu4e-drafts-folder "/Drafts")
  (mu4e-refile-folder "/Archive")
  (mu4e-sent-folder "/Sent")
  (mu4e-trash-folder "/Trash")
  (mu4e-update-interval 300)
  (mu4e-headers-fields '((:human-date . 20)
                         (:flags . 6)
                         (:from . 22)
                         (:maildir . 8)
                         (:subject))))

So far so good.

mbsync

Of course programs.mbsync exists too. Let's give it a try:

programs.mbsync.enable = true;

And then we'll add a section for fastmail under accounts.email:

accounts.fastmail = {
  address = "?????@fastmail.com";
  imap = {
    host = "imap.fastmail.com";
    port = 993;
  };
  maildir.path = "fastmail";
  mbsync = {
    enable = true;
    create = "maildir";
  };
  passwordCommand = "pass email/fastmail";
  realName = "Shaun Lee";
  userName = "?????@fastmail.com";
};

Let's try it:

❯ mbsync -a
Notice: Master/Slave are deprecated; use Far/Near instead.
C: 1/1  B: 6/6  F: +1/1 *1/1 #0/0  N: +0/0 *30/30 #0/0

Well that was a pleasant surprise.

msmtp

Same drill:

programs.msmtp.enable = true;

I should have set a bunch of smtp settings before:

accounts.email = {
  maildirBasePath = "/scratch/Maildir";
  accounts.fastmail = {
    address = "?????";
    aliases = ["shaun@curlyfri.es" "?????@fastmail.com"];
    imap = {
      host = "imap.fastmail.com";
      port = 993;
    };
    maildir.path = "fastmail";
    mbsync = {
      enable = true;
      create = "maildir";
    };
    msmtp = {
      enable = true;
      tls.fingerprint = "AF:01:8E:7F:FF:36:61:06:C6:F9:D4:38:D1:4E:08:98:78:C8:27:C5:E5:C0:A3:97:49:37:F2:76:90:B1:27:59";
    };
    smtp = {
      host = "smtp.fastmail.com";
      port = 465;
      tls = {
        enable = true;
      };
    };
    passwordCommand = "pass email/fastmail";
    realName = "Shaun Lee";
    userName = "?????@fastmail.com";
  };
  accounts.gmail = {
    address = "shaun.lee@gmail.com";
    flavor = "gmail.com";
    maildir.path = "gmail";
    lieer.enable = true;
    notmuch.enable = true;
    realName = "Shaun Lee";
    passwordCommand = "pass email/shaunlee-gmail";
    msmtp.enable = true;
    smtp = {
      host = "smtp.gmail.com";
      tls = {
        enable = true;
      };
    };
    userName = "shaun.lee@gmail.com";
    primary = true;
  };
};

And now I can send email from both mu4e and notmuch.