This page is an HTML mirror of the original gemini page.

My e-mail client vision (sketch)

In the previous post, I wrote about my gripes with mail software. In short: I want a command-line interface that sort of feels like the ``git of e-mail''. This is, roughly, my vision.

(Side note: @ploum made me aware of Himalaya, which comes quite close to this sort of vision, but it seems to lack offline capabilities, and the workflow is not quite there yet.)

In this post, I want to try and sketch a potential approach to this vision. This comprises (a) the way we use e-mail and (b) the workflow on the command line.

How to use e-mail: parsimony

We can't realize the full potential of even the best software if we use e-mail wrong. When we want to apply frugal computing to e-mail, we have to start with e-mail parsimony, to borrow a term from the area of data protection.

For instance, one-way broadcasting should entirely be done via RSS feeds, never via e-mail. Why should my inbox be flooded with bulk e-mail (probably mostly HTML mail at that) that I hardly ever read? I might at times be curious to know what's currently happening with some NGO I'm supporting. But then I can visit their web site or refresh their RSS feed.

So, the objective here is that whatever message reaches my inbox was written for me (and maybe others) *specifically*. This is what I will assume (at least as an ideal).

I will furthermore assume that my mail server has filters in place so that incoming mail is automatically sorted into folders, and I distinguish `primary' from `secondary' folders: messages in the former I deem important while messages in the latter are more likely to be noise.

With this in mind, let's come up with a nice workflow of how to interact with our hypothetical e-mail client.


First of all: the hypothetical client (for the sake of simplicity, let's assume its name is `mail') must have offline capability: the whole interaction with the network should be done with a dedicated command. This command need not output too much of interest for it is probably buried inside some script ( or whatever floats your boat) or cron job.

$ mail interact
On account foo: sending 3 messages... done.
On account foo: syncing messages... done.
On account bar: nothing to send.
On account bar: syncing messages... done.

Next I imagine the client manages the `working set' of e-mails:

$ mail status
New: 3 (+2 unimportant)
    13    foo/folder1    J. Bartlett       Re: presidency
    12    foo/inbox      T. Hoynes         Fwd: latest news
    11    bar/project    D. Floyd-Wa...    An offer you can't refuse
Pending: 2
    22    foo/inbox      <--Bee Maja       Hum hum hum
    21    bar/drafts     -->Dumbledore     Re: about your proposal

The idea here is that there is always a rather small set of messages that I'm likely to touch next, so it should be easy to review and reference them.

What I'm likely to touch is, roughly speaking, new messages (however excluding those in secondary folders, here referred to as `unimportant') as well as `pending messages' (those that I want to read later as well as draft messages).

And to make referencing the messages in the working set easy, they receive simple identifiers like 11, 21, etc. The identifiers should be stable: if, for instance, 11 leaves the working set, then the identifier 11 can be reused, but the meaning of 12 and 13 stays the same. This means that I can memorize some identifier (as in `I still have to work on 21`) for as long as the corresponding message is a member of the working set.

Let's say I want to read the new messages. I can do it one by one, but here I decide to read them all in one go:

$ mail open 11 12 13
Extracting 11 into ~/mail/11/...
Extracting 12 into ~/mail/12/...
Extracting 13 into ~/mail/13/...
Launching editor...

For each of these messages, a dedicated directory was populated with everything I might need: the raw message (in case I need to peek at all the headers) as well as its attachments.

Now my editor of choice will come up with the following contents:


message 11 <UUID>
  set-status p  # [n]ew, [p]ending, [r]ead
  #move-to <FOLDER>
  #detach all #attachment1,attachment2,...
  #reply #all
  #forward #plain

<plain-text summary of message 11>


message 12 <UUID>
  set-status p  # [n]ew, [p]ending, [r]ead
  #move-to <FOLDER>
  #detach all #attachment1,attachment2,...
  #reply #all
  #forward #plain

<plain-text summary of message 12>


message 13 <UUID>
  set-status p  # [n]ew, [p]ending, [r]ead
  #move-to <FOLDER>
  #detach all #attachment1,attachment2,...
  #reply #all
  #forward #plain

<plain-text summary of message 13>

Each message gets a section in this file (the delimiter is not really that interesting, but it is chosen in a way that it doesn't occur in any of the messages).

Each section starts with instructions that will be executed once I leave the editor. The command `set-status p', for instance, will change the message's status (currently new) to pending. If I don't like that, I can edit the line. Most of the instructions are commented out; I can uncomment them if I want them. (These comments are mainly there so new users don't need to memorize the instructions.)

After the instructions we have an empty line and then the plain-text summary of the message. By this I mean that I don't want to see any multipart stuff, but just whatever has the highest signal-to-noise ratio, and I don't want to decode quoted-printable (and the like) myself. Whenever I need more info, I can always switch to another terminal window (or use ctrl-z to send the editor into the background) and inspect the files in the message's directory. (NB: This should be promoted more! Terminal windows abound, and ctrl-z is not so bad, either.)

Let's assume I want to reply to 11 and 12 and forward 13. So I change `set-status p' to `set-status r' (for `read'), uncomment the respective instructions, save, and quit my editor. Worth noting: the reply and forward instructions name the sender identity (here the fictitious `') so the correct signature can be inserted.

Executing your instructions...
Created 23: Re: An offer you can't refuse
Created 24: Re: Fwd: latest news
Created 25: Fwd: Re: presidency

As per my instructions, `mail' creates new pending messages that are drafts for my replies/forwards. Now I can proceed to work on my responses:

$ mail open 23 24 25
Extracting 23 into ~/mail/23/...
Extracting 24 into ~/mail/24/...
Extracting 25 into ~/mail/25/...
Launching editor...

You get the drift (I hope). We might need a fourth state to indicate that the draft is ready and designated to be sent. As the final step of sending the message, its state would be changed to `read' and it would be moved to some other folder. Maybe this should also be controlled on a per-message basis via some instruction (with a ssensible default).

Discussion and remarks

More questions:

If you have ideas, I'd be delighted to read about them (on Antenna)!

Subscribe to my RSS feed.