Introducing mdstat

September 25, 2022

MailDir Stat (mdstat) is a small program I wrote some time ago to play with zig: it lists MailDirs, and optionally only those that contain unread emails. Nothing incredibly new, just a small itch to scratch.

It came from a small frustration with (neo)mutt where I sometimes like to have a tree of mailboxes in the sidebar ; but I only want to see the unread ones. I synchronize various IMAP accounts locally with mbsync, so finding maildirs is easily done with a bit of shell scripting.

For instance, this is how I listed all maildirs until recently:

fd . /home/oz/mail/cyprio --type d | \
  rg 'cur/$' | \
  sed 's,^/home/oz/mail/cyprio/\(.*\)/cur,=\"\1\",' | \
  tr '\n' ' '

This works well enough to tell neomutt to check all the maildirs of my account, and you can get more creative to ignore some directories, etc. With mdstat, this is just:

mdstat ~/mail/cyprio

Personally, I find that it’s an improvement ; but also maybe, a senseless micro-optimization, you know just for fun.

Sidebar and unreads

My mail account(s) often have nested folders, and will until the day I’m forced to properly use notmuch or something, and use labels like the rest of the world. I don’t know.

Still. As I use the sidebar plugin, I’ve realized that the “sidebar parser” isn’t (wasn’t?) clever enough to display a tree unless explicitly asked to. Let me try to explain.

Let’s say that I have new emails under ="news/progamming". To display a nice 2-levels tree with both the news, and programming labels correctly nested, the sidebar config expects to receive both entries like so: ="news/" ="news/programming" (order doesn’t actually matter).

If you just list ="news/programming", you’ll get:


If you list both entries, you get:


No flying folder without context, nicely indented, which makes my brain work better. 😌

It’s possible to do that with more shell scripting, but it quickly gets dirty when you try to deal with deeper trees, avoiding duplicates, and well it also gets slower because it’s a shell script.

This is my excuse for writing a program that builds maildir trees. In that example, mdstat ... -u will list both news and news/programming when there’s unread mail in the bottom folder ; even if news is not a proper maildir (which is a feature).

If you’re curious, the code is on with other more or less personal projects. Of course it’s way faster than forking 4+ shell commands.

About zig

I’m not sure that I’ll write much more zig code in the future.

It’s not that I don’t enjoy it, quite the contrary! The language seems simple, and fairly easy to pick up if you’ve ever dealt with C, Go, or Rust. It firmly sits somewhere between C and Go in my mind ; which is a space that I don’t often need to work into… but who knows?