A minimal email TUI where you read with Markdown and write in Neovim. neomd.ssp.sh/docs
email markdown neovim tui
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

add version to debug output

sspaeti 24dabf4b 4835e926

+9 -2
+1
cmd/neomd/main.go
··· 79 79 os.Exit(1) 80 80 } 81 81 82 + ui.Version = version 82 83 model := ui.New(cfg, imapClients, sc) 83 84 84 85 p := tea.NewProgram(
+4 -2
docs/keybindings.md
··· 68 68 | `Mm` | move to Someday | 69 69 70 70 71 - ### Multi-select 71 + ### Multi-select & Undo 72 72 73 73 | Key | Action | 74 74 |-----|--------| ··· 111 111 | `shift+R` | reply-all — reply to sender + all CC recipients (from reader) | 112 112 | `f` | forward email (from reader or inbox) | 113 113 | `c` | compose new email | 114 - | `ctrl+b (compose)` | toggle Cc+Bcc fields (both hidden by default) | 114 + | `ctrl+b (compose/pre-send)` | toggle Cc+Bcc fields (both hidden by default) | 115 115 | `ctrl+f (compose/pre-send)` | cycle From address through all accounts + [[senders]] aliases | 116 116 | `a (pre-send)` | attach file via yazi file picker (or $NEOMD_FILE_PICKER) | 117 117 | `D (pre-send)` | remove last attachment | 118 118 | `d (pre-send)` | save to Drafts folder (IMAP APPEND with \Draft flag) | 119 + | `s (pre-send)` | spell check — open in nvim with spell on, jump to first error | 119 120 | `p (pre-send)` | preview email in $BROWSER (images rendered, same as recipient sees) | 120 121 | `e (pre-send)` | re-open editor to edit body | 121 122 | `enter (pre-send)` | confirm and send | ··· 145 146 | `:empty-trash / :et` | permanently delete ALL emails in Trash (y/n) | 146 147 | `:create-folders / :cf` | create missing IMAP folders from config (safe, idempotent) | 147 148 | `:go-spam / :spam` | open Spam folder (not in tab rotation) | 149 + | `:debug / :dbg` | diagnostic report — IMAP ping, config, folders, state (saved to /tmp/neomd/debug.log) | 148 150 | `:quit / :q` | quit neomd | 149 151 150 152
+4
internal/ui/model.go
··· 95 95 } 96 96 ) 97 97 98 + // Version is set by main.go at startup (from build-time ldflags). 99 + var Version = "dev" 100 + 98 101 // neomdTempDir returns /tmp/neomd/, creating it if needed. 99 102 // Using a dedicated subdirectory keeps temp files discoverable (e.g. recovering 100 103 // a draft after a crash) and avoids cluttering /tmp/. ··· 135 138 return func() tea.Msg { 136 139 var b strings.Builder 137 140 b.WriteString("# neomd debug report\n\n") 141 + b.WriteString(fmt.Sprintf("Version: %s\n", Version)) 138 142 b.WriteString(fmt.Sprintf("Time: %s\n", time.Now().Format(time.RFC3339))) 139 143 b.WriteString(fmt.Sprintf("Config: %s\n\n", config.DefaultPath())) 140 144