The Problem: Raw IMAP is kind of a bummer.
I cant recall what prompted it but I wiped my neomutt setup sometime towards the end of last year and just got around to piecing it back together. Here are some issues I immediately noticed:
- If you have a few thousand emails, imap is terribly slow.
- If you find yourself moving from connection to connection neomutt eventually times out and doesn’t attempt to reconnect.
- I was not diligent in keeping up with gpg/pgp changes, or any changes really (in some cases i had the old directives with “# $new_directive”. sigh.
- A lot of settings were either redundant (literally the same declerations in different parts of a config file, or unnecessary.
The most glaring problem was imap slowness. My hack to get around this was to utilize the tagging functionality. I would tag emails by month and only display one month at a time in the index. It worked well enough but its 2019 I shouldnt need hacky methods to keep my MUA from exploding. My solution was mbsync. Why? I had lots of issues with offlineimap when I used it a year ago - mostly regarding mail delivery time. In any case mbsync was simple.
The Solution: Mbsync to the rescue.
Create Both Expunge Both # Save the synchronization state files in the relevant directory SyncState * IMAPAccount username Host imap.gmail.com User email@example.com Passcmd "pass mail/gmail/username" SSLType IMAPS Authmechs LOGIN CertificateFile /etc/ssl/certs/ca-certificates.crt IMAPStore username-remote Account username MaildirStore username-local Path ~/.mail/username/ Inbox ~/.mail/username/inbox/ Subfolders Verbatim Channel username-inbox Master :username-remote: Slave :username-local: Patterns "INBOX" Channel username-sent Master :username-remote:"[Gmail]/Sent Mail" Slave :username-local:sent Create Both Expunge Both SyncState * Channel username-spam Master :username-remote:"[Gmail]/Spam" Slave :username-local:spam Create Both Expunge Both SyncState * Channel username-trash Master :username-remote:"[Gmail]/Trash" Slave :username-local:trash Create Both Expunge Both SyncState * Group username Channel username-inbox Channel username-sent Channel username-spam Channel username-trash
Mbsync is fairly straight forward with one caveat, which I’ll get to.
- Give it your credentials and auth method. I’m using pass for the password, you can use gpg or what have you.
- Name your remote imap connection (username-remote). And account (how you’ll call Mbsync - in this case username).
- Maildirstore is your local store. Where your mail will be saved to. Give it a
name. username-local just seems intuitive. YMMV.
- Set the path.
- Define an inbox (mind the /).
- Suborders Verbatim tells it to respect the folder hierarchy. There are several options that you can read about in the doc. You probably want this one if you’re using Gmail.
- Define your channels. Mbsync uses channels. A channel is just the link
between two stores. Your local and remote.
- Define its name.
- Set the problematic name of the upstream store and the folder name according to imap. Set the problematic name of the downstream store and the folder name according to where you want to store it.
- Tell Mbsync if you want to create/delete either dir’s if they do/do not exist.
- Tell it how to sync.
- Group these channels to a particular account.
Dont forget the SSL cert portion. Unless you’re too cool for SSL.
There are are a few caveats. According to the documentation (or how I read it anyway) after the first inbox channel sync you should be able to add a Pattern “*” or “! [Gmail]folder” to either sync everything under the sun, or everything but [Gmail]folder. Which, actually you can do but it creates a DIR hierarchy like this:
~/.mail/username/inbox ~/.mail/username/[GMAIL]/sent ~/.mail/username/[GMAIL]/trash
This proved to be problematic for to neomutt retrieving the folders. I found it necessary to define them each individually which created the folders on the same level and made Neomutt a happy puppy.
How do I retrieve new mail you ask? Well here’s a trivial way. I’m not sure where I got this but if anyone knows shoot me an email so I can credit them:
#!/bin/bash ## Check mbsync email 3 times per minute based on a cronjob firing this script killall mbsync &>/dev/null mbsync -a -q sleep 20 killall mbsync &>/dev/null mbsync -a -q sleep 20 killall mbsync &>/dev/null mbsync -a -q
Here’s the cronjob
*/1 * * * * ~/bin/mbsync.sh
An Excuse to mess with .muttrc
That’s it for retrieval and syncing of email. Now we’ve just got to get into Neomutt. Since you’re in there, it might be a good time to take a look at your .muttrc to make sure you’re up to date with any changes or maybe tweak that setting you’ve been meaning to but you’ve been too busy.
# DIR set folder = "~/.mail/username/" set spoolfile = "~/.mail/username/inbox" set postponed = "=drafts" set trash = "=trash" set record = "=sent" set alias_file = "$my_path/"alias # mailboxes mailboxes "=inbox" "=sent" "=drafts" "=spam" "=trash"
- set spoolfile =”~/.mail/username/inbox”.
- All other mailbox folders are defined by what we named them in mbsync, prepended with an “=”.
- Identify each mailbox with “mailboxes = “=inbox” etc (for sidebar). full .muttrc on my github
Sending mail: Because people want to hear from you. Maybe.
MSMTP handles this pretty easily. I just rolled Neomutt into this because I use it for other things anyway.
defaults auth on tls on tls_trust_file /etc/ssl/certs/ca-certificates.crt logfile ~/.msmtp.log account username host smtp.gmail.com port 587 from firstname.lastname@example.org user username passwordeval "pass show mail/gmail/username" account default : username
I don’t think this really needs much explanation. Here’s the relevant .muttrc bits:
set sendmail = "msmtp -a username"
That’s really all there is to it. I’ve been running with this setup for about 5 days now and I’m very pleased. No more seemingly random timeouts. No more timeouts when moving offices and connecting to a different WAP. No more hacks to stop Neomutt from barfing on a couple thousand emails like its the 90’s.
As always, comment, questions, suggestions? Id love to hear them.