Skip to content

Commit c8dc977

Browse files
committed
Merge branch 'dev'
2 parents 0bd357d + 2cd0c55 commit c8dc977

3 files changed

Lines changed: 66 additions & 62 deletions

File tree

README.md

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# neomd
22

3-
A minimal terminal email client for people who write in Markdown and live in Neovim.
3+
A keyboard-first TUI email: write in Neovim, render as Markdown, screen senders first, organize emails once.
44

5-
*Neomd is my way of implementing an email TUI based on my experience with Neomutt, focusing on [Neovim](https://www.ssp.sh/brain/neovim) (input) and reading/writing in [Markdown](https://www.ssp.sh/brain/markdown) and navigating with [Vim Motions](https://www.ssp.sh/brain/vim-language-and-motions) with the GTD workflow and [HEY-Screener](https://www.hey.com/features/the-screener/).*
5+
_Neomd is my way of implementing an email TUI based on my experience with Neomutt, focusing on [Neovim](https://www.ssp.sh/brain/neovim) (input) and reading/writing in [Markdown](https://www.ssp.sh/brain/markdown) and navigating with [Vim Motions](https://www.ssp.sh/brain/vim-language-and-motions) with the GTD workflow and [HEY-Screener](https://www.hey.com/features/the-screener/)._
66

77
## The philosophy behind Neomd: What's unique?
88

@@ -16,7 +16,6 @@ Also, we intentionally don't add more folders to the archive or file emails too,
1616

1717
But we have two additional **Feed** and **Papertrail**, two dedicated folders from HEY where you can read newsletters (just hit F) on them automatically in their separate tab, or move all your receipts into the Papertrail. Once you mark them as feed or papertrail, they will moved there automatically going forward. So you decide whether to read emails or news by jumping to different tabs.
1818

19-
2019
### Email Processing Workflow
2120

2221
Here's how neomd combines HEY-Screener + GTD + Feed/Papertrail to process your email:
@@ -66,24 +65,25 @@ flowchart TD
6665
classDef folderStyle fill:#54546d,stroke:#7fb4ca,stroke-width:2px,color:#dcd7ba
6766
class ToScreen,Inbox,ScreenedOut,Feed,PaperTrail,Archive,Waiting,Someday,Scheduled,Trash folderStyle
6867
```
69-
*all colored boxes represent neomd folders*
68+
69+
_all colored boxes represent neomd folders_
7070

7171
**Key principles:**
72+
7273
- **Screener first**: Unknown senders never clutter your Inbox, but get automatically wait in ToScreen for classification [more](https://neomd.ssp.sh/docs/screener/)
7374
- **One-time decision**: Once you classify a sender (`I/O/F/P`), all future emails from them are automatically routed [more](https://neomd.ssp.sh/docs/screener/#how-classification-works)
74-
- **GTD processing**: Emails in Inbox are processed once. Inbox acting as want/need to do *Next*, otherwise move to Waiting, Someday, or Scheduled
75-
- **Minimal filing**: Only Archive when done; no complex folder hierarchies. Use search to find old emails
76-
- **Separate contexts**: Feed for newsletters (read when you want), PaperTrail for receipts (search when needed)
75+
- **GTD processing**: Emails in Inbox are processed once. Inbox acting as want/need to do _Next_, otherwise move to Waiting, Someday, or Scheduled
76+
- **Minimal filing**: Only Archive when done; no complex folder hierarchies. Use search to find old emails
77+
- **Separate contexts**: Feed for newsletters (read when you want), PaperTrail for receipts (search when needed)
7778
- See full features list below.
7879

79-
8080
## Screenshots
8181

8282
### Overview: List-View
8383

8484
Feed view with all Newsletters - also workflow with differnt tabs and unread counter only for certain tabs (not all):
8585
![neomd](docs/static/images/neomd-hero.png)
86-
*Features seen: Reading newsletter directly in your email client (feed) - see spy pixel, if you have replied (dot) and thread mode if replied*
86+
_Features seen: Reading newsletter directly in your email client (feed) - see spy pixel, if you have replied (dot) and thread mode if replied_
8787

8888
### Reading Panel
8989

@@ -92,10 +92,12 @@ Reading an email with Markdown 💙:
9292
![neomd](docs/static/images/reading-email.png)
9393

9494
### Sent emails
95+
9596
This is the markdown sent:
9697

9798
```markdown
9899
# [neomd: to: [email protected]]
100+
99101
# [neomd: subject: this is an email from neomd!]
100102

101103
This email is from Neomd. Great I can add links such as [this](https://ssp.sh) with plain Markdown.
@@ -112,8 +114,7 @@ how does that look in an email?
112114
Best regards
113115
```
114116

115-
*Compose emails in your editor, read them rendered with [glamour](https://github.com/charmbracelet/glamour), and manage your inbox with a [HEY-style screener](https://www.hey.com/features/the-screener/) — all from the terminal.*
116-
117+
_Compose emails in your editor, read them rendered with [glamour](https://github.com/charmbracelet/glamour), and manage your inbox with a [HEY-style screener](https://www.hey.com/features/the-screener/) — all from the terminal._
117118

118119
Which looks like this:
119120

@@ -122,12 +123,11 @@ Which looks like this:
122123
Or in Gmail:
123124
![neomd](docs/static/images/gmail.png)
124125

125-
126126
### Video
127127

128-
YouTube rundown of most features:
129-
[![neomd demo](https://img.youtube.com/vi/lpmHqIrCC-w/maxresdefault.jpg)](https://youtu.be/8aKkldYLWV8)
130-
*(shorter but limited showcase [part 1 video](https://youtu.be/lpmHqIrCC-w))*
128+
YouTube rundown of most features:
129+
[![neomd demo](https://img.youtube.com/vi/lpmHqIrCC-w/maxresdefault.jpg)](https://youtu.be/8aKkldYLWV8)
130+
_(shorter but limited showcase [part 1 video](https://youtu.be/lpmHqIrCC-w))_
131131

132132
## Features
133133

@@ -142,7 +142,6 @@ These features are the one that makes neomd different to other email clients out
142142
- **GitHub/Obsidian-style callouts** — compose emails with callout syntax `> [!note]`, `> [!tip]`, `> [!warning]` for styled alert boxes in HTML emails; rendered with colored left borders, subtle backgrounds, and emoji icons [](https://neomd.ssp.sh/docs/sending/#callouts-admonition)
143143
- **Listmonk newsletter integration** — compose an email to a virtual address (e.g. `[email protected]`) and neomd creates a scheduled campaign in [Listmonk](https://listmonk.app) via API instead of sending via SMTP; configure multiple trigger addresses to target different subscriber lists; pre-send screen shows campaign details [](https://neomd.ssp.sh/docs/integrations/listmonk/)
144144

145-
146145
### Inbox & Screener
147146

148147
Keep your inbox clean without effort.
@@ -154,7 +153,6 @@ Keep your inbox clean without effort.
154153
- **Desktop notifications for VIP senders** — opt-in `[notifications]` block fires `notify-send` only for senders/domains you list in `notify.txt`; independent of screener categories; first run silently records a baseline so you don't get flooded [](https://neomd.ssp.sh/docs/notifications/)
155154
- **Folder tabs** — Inbox, ToScreen, Feed, PaperTrail, Archive, Waiting, Someday, Scheduled, Sent, Trash, ScreenedOut [](https://neomd.ssp.sh/docs/keybindings/#folders)
156155

157-
158156
### Composing & Sending
159157

160158
- **Pre-send review** — after closing the editor, review To/Subject/body before sending; attach files, save to Drafts, or re-open the editor — no accidental sends [](https://neomd.ssp.sh/docs/sending/#pre-send-review)
@@ -203,6 +201,7 @@ Keep your inbox clean without effort.
203201
204202
> [!NOTE]
205203
> **Optional Neovim & file picker helpers:**
204+
>
206205
> - `yazi` enables the built-in file picker used by pre-send `a`
207206
> - custom Neovim integration in [`custom.lua`](https://github.com/sspaeti/dotfiles/blob/master/nvim/.config/nvim/lua/sspaeti/custom.lua) enables inline `<leader>a` attachment insertion inside `neomd-*.md` buffers
208207
> - a tiny [yazi `init.lua`](https://github.com/sspaeti/dotfiles/blob/master/yazi/.config/yazi/init.lua) snippet (`ps.sub("cd", ...)` guard on `rt.args.chooser_file`) is recommended — it clears any stale yazi selection on every `cd`, so a stray `<Space>` (yazi's toggle-selection key) in the picker can't cause `--chooser-file` to write the wrong path. Only fires in chooser mode; standalone yazi usage is unaffected.
@@ -223,18 +222,18 @@ make build
223222
```
224223

225224
Or if on Arch Linux (AUR), you can use my [neomd-bin](https://aur.archlinux.org/packages/neomd-bin) via:
225+
226226
```sh
227227
yay -S neomd-bin
228228
```
229229

230-
231230
On first run, neomd:
231+
232232
1. Creates `~/.config/neomd/config.toml` with placeholders — fill in your IMAP/SMTP credentials
233-
- Important: Make sure that the Capitalization and naming of folder in `config.toml` is accroding to webmail IMAP, e.g. [Gmails](docs/content/docs/configuration/gmail.md) uses `sent = "[Gmail]/Sent Mail"` and not `sent` etc.
233+
- Important: Make sure that the Capitalization and naming of folder in `config.toml` is accroding to webmail IMAP, e.g. [Gmails](docs/content/docs/configuration/gmail.md) uses `sent = "[Gmail]/Sent Mail"` and not `sent` etc.
234234
2. Creates `~/.config/neomd/lists/` for screener allowlists (or uses your custom paths from config)
235235
3. Creates any missing IMAP folders (ToScreen, Feed, PaperTrail, etc.) automatically
236236

237-
238237
Neomd also runs on Android (more for fun) — see [docs/content/docs/configuration/android.md](docs/content/docs/android.md).
239238

240239
## Configuration
@@ -268,6 +267,7 @@ Use an app-specific password (Gmail, Fastmail, Hostpoint, etc.) rather than your
268267
For the full configuration reference including multiple accounts, OAuth2 authentication, `[[senders]]` aliases, folder customization, signatures, and UI options, see [docs/content/docs/configuration](docs/content/docs/configuration/_index.md).
269268

270269
**Provider-specific guides:**
270+
271271
- Gmail: [docs/content/docs/configuration/gmail.md](docs/content/docs/configuration/gmail.md) — folder name mapping and OAuth2 setup
272272
- Proton Mail Bridge: [docs/content/docs/configuration/proton-bridge.md](docs/content/docs/configuration/proton-bridge.md) — non-standard port configuration
273273

@@ -301,6 +301,7 @@ You choose who can land in your Inbox. Bye-bye spam. This is the beauty of [HEY-
301301
### Screener Workflow
302302

303303
Find full Screener Workflow at [docs/content/docs/screener.md](docs/content/docs/screener.md), classification tables, and bulk re-classification instructions.
304+
304305
### Keybindings
305306

306307
Press `?` inside neomd to open the interactive help overlay. Start typing to filter shortcuts.
@@ -313,7 +314,7 @@ Compose in Markdown, send as `multipart/alternative` (plain text + HTML). Attach
313314

314315
Discarding unsent mail now asks for confirmation in compose/pre-send, and `:recover` reopens the latest backup if you want to resume after an abort.
315316

316-
- See [docs/content/docs/sending.md](docs/content/docs/sending.md) for details on MIME structure, attachments, pre-send review, and drafts.
317+
- See [docs/content/docs/sending.md](docs/content/docs/sending.md) for details on MIME structure, attachments, pre-send review, and drafts.
317318
- See [docs/content/docs/reading.md](docs/content/docs/reading.md) for the reader: images, inline links, attachments, and navigation.
318319

319320
### Dev: Makefile Commands
@@ -341,9 +342,10 @@ make help print this list
341342
- [goldmark](https://github.com/yuin/goldmark) — Markdown → HTML for sending
342343
- [BurntSushi/toml](https://github.com/BurntSushi/toml) — config parsing
343344

344-
345345
## FAQ
346+
346347
You have more questions, check out the [docs](https://neomd.ssp.sh/) with more information, or check [Frequently Asked Questions](https://neomd.ssp.sh/docs/faq/).
348+
347349
## Changelog
348350

349351
See [CHANGELOG.md](CHANGELOG.md) for what's new.
@@ -378,11 +380,11 @@ neomd's responsiveness depends entirely on your IMAP server. Every folder switch
378380

379381
Interestingly, Gmail benchmarks fast on a **fresh single connection** (`scripts/imap-benchmark.sh` shows ~70ms total, same as Hostpoint). But on a **sustained session** with sequential commands — which is how neomd actually uses IMAP — Gmail adds ~180ms latency per command. This is likely Gmail's internal label-to-folder translation and session management overhead. The result: every action in neomd feels much slower on Gmail, while Hostpoint stays instant.
380382

381-
382383
> [!NOTE]
383384
> **Gmail is not recommended.** If you're on Gmail, consider a dedicated email provider (Hostpoint, Fastmail, HEY, Migadu, etc.) for the best neomd experience. Or use Gmail just for fun :). See [docs/content/docs/configuration/gmail.md](docs/content/docs/configuration/gmail.md) for Gmail-specific folder configuration.
384385
385386
**Test your own provider:**
387+
386388
```bash
387389
# With password
388390
IMAP_HOST=imap.example.com [email protected] IMAP_PASS=secret ./scripts/imap-benchmark.sh
@@ -414,6 +416,7 @@ This TUI is mostly [vibe-coded](https://www.ssp.sh/brain/vibe-coding) in the sen
414416
I used my experience with Neomutt, TUIs, and the GTD workflow for handling emails with HEY Screener, and added some (hopefully) _taste_ using my favorite tools and aesthetics. Find the full history at [Twitter](https://xcancel.com/sspaeti/status/2036539855182627169#m) - inspired by seeing [Email.md](https://www.emailmd.dev/) on HackerNews.
415417

416418
If you [rather read the prompt](https://www.ssp.sh/brain/id-rather-read-the-prompt), check out my [initial prompt](https://github.com/ssp-data/neomd/blob/main/docs/initial-prompt/prompt.md) and its generated [plan](https://github.com/ssp-data/neomd/blob/main/docs/initial-prompt/prompt-plan.md) - which I have iterated and added features by the 100s since then.
419+
417420
## Roadmap
418421

419422
See at my second brain at [Roadmap](https://www.ssp.sh/brain/neomd#roadmap).

docs/content/_index.md

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,32 +69,30 @@ toc: false
6969
<br>
7070

7171
![neomd demo](/images/neomd-hero.png)
72-
*Reading newsletter directly in your email client (feed) - see spy pixel, if you have replied (dot) and thread mode if replied)*
72+
_Reading newsletter directly in your email client (feed) - see spy pixel, if you have replied (dot) and thread mode if replied)_
7373

7474
<br>
7575

7676
<div class="hx-mt-12 hx-mb-8">
7777
<h2 class="hx-text-4xl hx-font-bold hx-tracking-tight hx-text-gray-900 dark:hx-text-gray-50">Video Demo - YouTube rundown of most features:</h2>
7878
</div>
7979

80-
8180
[![neomd demo](https://img.youtube.com/vi/lpmHqIrCC-w/maxresdefault.jpg)](https://youtu.be/8aKkldYLWV8)
8281

83-
8482
<br>
8583
<div class="hx-mt-12 hx-mb-8">
8684
<h2 class="hx-text-4xl hx-font-bold hx-tracking-tight hx-text-gray-900 dark:hx-text-gray-50">Documentation:</h2>
8785
</div>
8886

8987
{{< cards cols="3" >}}
90-
{{< card link="docs" title="Overview & Philosophy" subtitle="Full feature list, installation (binary, AUR, source), philosophy, benchmarks, and inspiration" >}}
91-
{{< card link="docs/configuration" title="Configuration Reference" subtitle="Full config with multiple accounts, OAuth2, signatures, and UI options" >}}
92-
{{< card link="docs/keybindings" title="Keybindings" subtitle="Complete keyboard shortcuts reference (auto-generated from source)" >}}
93-
{{< card link="docs/screener" title="Screener Workflow" subtitle="How to classify emails, bulk operations, and screener lists" >}}
94-
{{< card link="docs/reading" title="Reading Emails" subtitle="Navigation, images, links, attachments, threading" >}}
95-
{{< card link="docs/sending" title="Sending Emails" subtitle="Compose, attachments, CC/BCC, drafts, HTML signatures" >}}
96-
{{< card link="docs/integrations/" title="Integrations" subtitle="Integrations with Newsletter such as Listmonk" >}}
97-
{{< card link="docs/faq" title="FAQ" subtitle="Frequently asked questions" >}}
88+
{{< card link="docs" title="Overview & Philosophy" subtitle="Full feature list, installation (binary, AUR, source), philosophy, benchmarks, and inspiration" >}}
89+
{{< card link="docs/configuration" title="Configuration Reference" subtitle="Full config with multiple accounts, OAuth2, signatures, and UI options" >}}
90+
{{< card link="docs/keybindings" title="Keybindings" subtitle="Complete keyboard shortcuts reference (auto-generated from source)" >}}
91+
{{< card link="docs/screener" title="Screener Workflow" subtitle="How to classify emails, bulk operations, and screener lists" >}}
92+
{{< card link="docs/reading" title="Reading Emails" subtitle="Navigation, images, links, attachments, threading" >}}
93+
{{< card link="docs/sending" title="Sending Emails" subtitle="Compose, attachments, CC/BCC, drafts, HTML signatures" >}}
94+
{{< card link="docs/integrations/" title="Integrations" subtitle="Integrations with Newsletter such as Listmonk" >}}
95+
{{< card link="docs/faq" title="FAQ" subtitle="Frequently asked questions" >}}
9896
{{< /cards >}}
9997

10098
<br>

0 commit comments

Comments
 (0)