A scheme for an event-driven NeoMutt
At the heart of NeoMutt is the data. It starts with:
N) holds an Account List (
A) holds a Mailbox List (
M) holds an Email List (
E) is made up of an Envelope, Body and other Mime parts (not shown)
Some of these data objects are created by the core code in NeoMutt, but the majority will be created by the backends (Maildir, IMAP, Notmuch, etc).
Note: These objects are just raw data, only the data saved on your email server. They don’t contain any GUI information (that’s contained in the Views).
The GUI is composed of a set of nested Windows. Some are visible, such as the Sidebar and Pager, others are transparent containers used for alignment, etc.
Scene: User reads an email in the pager
Below, the tree and the diagram show the how the Windows are arranged.
Root Window (R) ├─▶ Help Line ├─▶ All Dialogs Container (D) │ └─▶ Index-Pager Dialog (I) │ ├─▶ Sidebar │ └─▶ Container (4) │ ├─▶ Index Container (5) │ │ ├─▶ Index │ │ └─▶ Index Bar (Status) │ └─▶ Pager Container (6) │ ├─▶ Pager │ └─▶ Pager Bar └─▶ Command Line / Message Window
Each Window has a set of simple rules that determine its size and position.
Index-Pager Dialog: Transparent, Maximise horizontal, Maximise vertical
Use all the available space given to it by its parent
Sidebar: Visible, Fixed horizontal, Maximise vertical
Any remaining horizontal space will be used by Container (4)
Index: Visible, Maximise horizontal, Fixed vertical
These rules allow the ‘reflow’ function to simply allocate screen space to the Windows.
The Email Index is simply the list of Emails in a certain Mailbox. But:
These questions are all answered by the Views. For each data object there’s a view object containing the user’s visual customisations and interactions with the data.
The diagram shows the Index (
I) which owns a MailboxView (
The MailboxView has a pointer to the data Mailbox (
M) and also a child view, an
EV), which points to some Emails (
Note: There may be multiple Views, but there is only one Data object.
When composing an Email, if the user wants to attach an Email, then the sequence looks like this: Index1 -> Compose -> Index2. Index1 and Index2 may both refer to the Mailbox, but they will have separate Views. Changing the sort order in Index2 won’t affect Index1.
To keep the Data and Views separate, NeoMutt uses an Observer Pattern system of notifications. Like the Data and the Windows, the Notifications are also nested.
The diagram shows four Subjects: the NeoMutt, Account, Mailbox and Email.
Each has a Notification object (
N) and a set of Observers (
When a subject changes, all the observers will be notified.
Note: Subjects are nested and Notifications will be propagated up the tree
Current list of Subjects:
The Sidebar uses data from three sources: Account, Mailbox and MailboxView, but that’s not all that affects the display. Config variables, colours and some commands can have an effect and the dimensions of the Window, too.
The config code doesn’t know about the Sidebar, the Sidebar must register its interest in the config, colours, commands, etc. This helps to reduce dependencies, whilst keeping things flexible.