diff --git a/CLAUDE.md b/CLAUDE.md index c53c74a..e82a9ee 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,7 +4,9 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co ## Project Overview -**Skim** is a TUI email client built with Rust and Ratatui. It connects to IMAP servers (including Gmail) and displays inbox messages with a split-pane interface: email list on top, message preview on the bottom. +**tui_mail** is a TUI email client built with Rust and Ratatui. It connects to IMAP servers (including Gmail) and displays inbox messages with a split-pane interface: email list on top, message preview on the bottom. + +**User documentation:** see [`USAGE.md`](USAGE.md) for setup instructions, keyboard shortcuts, and configuration reference. ## Build and Run Commands diff --git a/USAGE.md b/USAGE.md new file mode 100644 index 0000000..c64a9bc --- /dev/null +++ b/USAGE.md @@ -0,0 +1,198 @@ +# tuimail — User Guide + +tuimail is a terminal email client. It shows your inbox in a split-pane view: +the email list on top, the message preview on the bottom. + +--- + +## Setup + +Copy the example config and fill in your credentials: + +```bash +cp config.toml.example config.toml +``` + +Edit `config.toml`: + +```toml +[imap] +host = "imap.gmail.com" # your provider's IMAP server +port = 993 +username = "you@example.com" +password = "your-password" +use_tls = true + +[smtp] +host = "smtp.gmail.com" # your provider's SMTP server +port = 465 +username = "you@example.com" +password = "your-password" +tls_mode = "smtps" # none | starttls | smtps +from = "Your Name " +``` + +**Common provider settings** + +| Provider | IMAP host | IMAP port | use_tls | SMTP host | SMTP port | tls_mode | +|----------|-----------|-----------|---------|-----------|-----------|----------| +| Gmail | imap.gmail.com | 993 | true | smtp.gmail.com | 465 | smtps | +| Outlook/Hotmail | outlook.office365.com | 993 | true | smtp.office365.com | 587 | starttls | +| ProtonMail (Bridge) | 127.0.0.1 | 1143 | false | 127.0.0.1 | 1025 | none | +| Local test server | localhost | 143 | false | localhost | 25 | none | + +> **Gmail note:** You must use an [App Password](https://myaccount.google.com/apppasswords), +> not your regular password. Enable 2-Step Verification first, then generate an +> App Password for "Mail". + +Then run: + +```bash +cargo run --release +``` + +--- + +## Interface + +``` +┌─────────────────────────────────────────────────────┐ +│ ▶ Inbox (42 messages) │ ← active pane (cyan) +│ 2025-01-15 10:32 Alice Hello│ +│>> 2025-01-14 09:11 Bob Re: …│ ← selected row +│ 2025-01-13 17:44 Carol Mtg │ +├─────────────────────────────────────────────────────┤ +│ Message │ ← inactive pane +│ │ +│ Hi there, │ +│ Just checking in… │ +│ │ +├─────────────────────────────────────────────────────┤ +│ c compose | r reply | / search | q quit | … │ ← status bar +└─────────────────────────────────────────────────────┘ +``` + +The active pane is highlighted in cyan with a `▶` prefix. `Tab` switches focus +between the two panes. + +--- + +## Keyboard Reference + +### Navigation + +| Key | Action | +|-----|--------| +| `↑` / `k` | Move up in inbox or scroll message up | +| `↓` / `j` | Move down in inbox or scroll message down | +| `Tab` | Switch focus between inbox list and message preview | +| `q` / `Esc` | Quit (or clear search results) | + +Scrolling past the last loaded message automatically fetches the next batch of +50 older emails. + +### Email Actions + +| Key | Action | +|-----|--------| +| `r` | **Reply** to the selected email | +| `d` | **Delete** the selected email (moves to Trash) | +| `u` / `F5` | **Refresh** the inbox manually | + +### Search + +| Key | Action | +|-----|--------| +| `/` | Open the search bar | +| *(type query)* | Filter by subject or sender | +| `Enter` | Run the search | +| `Esc` | Clear search results and return to inbox | + +Search runs an IMAP `SEARCH OR SUBJECT … FROM …` query on the server so it +works across your entire mailbox, not just the loaded batch. + +### Compose + +| Key | Action | +|-----|--------| +| `c` | Open compose window | +| `r` | Open compose pre-filled for replying to the selected email | +| `Tab` | Cycle focus: To → Subject → Body → To | +| `Enter` | Move to next field (To / Subject); insert newline in Body | +| `Ctrl+S` | Send the email | +| `Esc` | Cancel and discard the draft | + +--- + +## Composing and Replying + +Press **`c`** to compose a new email. The compose window opens full-screen: + +``` +┌─ ▶ Compose ──────────────────────┐ +│ To: alice@example.com │ +│ Subject: Hello │ +├─ Body ───────────────────────────┤ +│ Hi Alice, │ +│ │ +│ _ │ ← cursor +└──────────────────────────────────┘ + Ctrl+S send | Esc cancel | Tab switch field +``` + +Press **`r`** to reply. The compose window opens with: + +- **To** pre-filled with the sender's address +- **Subject** set to `Re: ` +- **Cursor** placed in the Body field, ready to type +- The original message shown below a separator (dimmed) — included in the + sent email automatically + +``` +┌─ ▶ Compose ──────────────────────┐ +│ To: bob@example.com │ +│ Subject: Re: Weekend plans │ +├─ Body ───────────────────────────┤ +│ _ │ ← type your reply here +│ ─────────────────────────────── │ +│ On 2025-01-14 09:11, Bob wrote: │ +│ > Are you free Saturday? │ +└──────────────────────────────────┘ +``` + +> If the message body hasn't finished loading when you press `r`, the quote +> is omitted. Press `Esc`, wait a moment for the preview to appear, then +> press `r` again. + +--- + +## Auto-refresh + +The inbox refreshes automatically every 30 seconds in the background. A +`[loading…]` indicator appears in the inbox title while a refresh is in +progress. Your current selection is preserved across refreshes. + +--- + +## Configuration Reference + +### `[imap]` + +| Key | Type | Description | +|-----|------|-------------| +| `host` | string | IMAP server hostname | +| `port` | integer | IMAP port (usually 993 with TLS, 143 without) | +| `username` | string | Login username (usually your full email address) | +| `password` | string | Password or app-specific password | +| `use_tls` | bool | `true` for IMAPS (port 993), `false` for plain/STARTTLS | + +### `[smtp]` + +| Key | Type | Description | +|-----|------|-------------| +| `host` | string | SMTP server hostname | +| `port` | integer | SMTP port | +| `username` | string | Login username | +| `password` | string | Password or app-specific password | +| `tls_mode` | string | `none`, `starttls`, or `smtps` | +| `from` | string | Sender address shown to recipients, e.g. `Name ` |