Skip to content

Writing mail

A compose runs in three stages: header fields, your $EDITOR for the body, then a review screen. Each stage names its keys in the status line.

Start a compose

Key Does
N new message
R reply to the sender
Shift+R reply to all (you dropped from the recipients)
Shift+L reply to the mailing list
F forward

Shift+L replies to the mailing list a message came from: Mail-Followup-To wins when the author set one, otherwise the List-Post mailto address is used. A List-Post: NO list refuses with a status message, and a list without any List-Post header falls back to reply-all with a warning naming the recipient count rather than guessing an address.

Or start from a named template:

:template <name>

Templates called new and reply apply themselves automatically (see templates).

The fields

Key Does
Tab / Shift+Tab move between fields
Left / Right cycle the From identity

Start typing in To, Cc or Bcc and matches from your own mail appear beneath the field:

Key Does
Tab complete
Ctrl+N / Ctrl+P select a match
Esc dismiss

The body

Ctrl+E opens your $EDITOR on the body alone. It runs embedded beneath the fields; Ctrl+E toggles back to the fields while it runs. Quit the editor (:q in vim) to land on review. Quitting the first edit with nothing written abandons the compose.

Hand the whole terminal to the editor instead:

[ui]
composer = "suspend"

Review

Nothing sends until you confirm here.

Key Does
Y send
E edit the body
H edit the header fields
A attach a file (path prompt, ~ expands)
D remove the attachment
S / X toggle signing / encryption
K toggle a read-receipt request
N toggle a DSN request
++at++ schedule the send
Q close, keeping a draft if you choose

Signing and encryption go through your gpg-agent; if a certificate is missing or the agent refuses, nothing sends and review names the problem (see security).

K asks the recipient's client to confirm the message was read (a standard Disposition-Notification-To header, RFC 8098). It is off by default, and honouring it is the recipient's choice.

N asks the sending server to report on delivery itself: a delivery status notification (DSN, RFC 3461), so a bounce or a delay comes back as a machine-readable receipt. It reaches the wire only when the server advertises the DSN extension, and its default follows [compose] request_dsn.

Both show as their own rows in the review settings list: a Receipt: row below the security line, and a DSN: row below that, each reading requested or not requested as you flip it.

Send

Y queues the message to a durable outbox and the daemon sends it over SMTP (or Microsoft Graph). If the daemon or network is down, it stays queued and goes on the next pass. Bcc recipients travel in the envelope, never in the headers. Every outgoing message carries an X-Mailer header naming Antiphon and its version. The Date header is stamped in the machine's local timezone (the offset desktop clients show), not UTC.

A message the server refuses outright moves to outbox/dead in the store and stops retrying; read, fix and requeue it by hand.

Drafts

Press Q on review (or answer Y to the draft prompt) to save the compose whole. Reopen it:

:resume <path>

Drafts also spool to the account's drafts folder on the server.

git send-email

antiphon sendmail speaks the sendmail contract, so git can send through your queue:

[sendemail]
    sendmailcmd = antiphon sendmail

Exit 0 means the daemon took durable delivery. See patches for the full workflow.