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 benchmark

sspaeti a2c377d6 03dc0ccf

+117
+8
Makefile
··· 45 45 demo-reset: 46 46 ./scripts/reset-demo.sh $(HOME)/.config/neomd-demo 47 47 48 + ## benchmark: benchmark IMAP latency for Hostpoint and Gmail 49 + benchmark: 50 + @echo "=== Hostpoint ===" 51 + @IMAP_HOST=imap.mail.hostpoint.ch IMAP_USER=simu@sspaeti.com IMAP_PASS=$$IMAP_PASS_SIMU ./scripts/imap-benchmark.sh 52 + @echo "" 53 + @echo "=== Gmail ===" 54 + @IMAP_HOST=imap.gmail.com IMAP_USER=neomd.demo@gmail.com IMAP_PASS=$$IMAP_APPPASS_GMAIL_NEOMD ./scripts/imap-benchmark.sh 55 + 48 56 ## test: run all tests 49 57 test: 50 58 go test ./...
+109
scripts/imap-benchmark.sh
··· 1 + #!/bin/bash 2 + # Benchmark IMAP server latency (LOGIN + SELECT INBOX + UID SEARCH ALL). 3 + # Usage: IMAP_HOST=imap.example.com IMAP_USER=me@example.com IMAP_PASS=secret ./scripts/imap-benchmark.sh 4 + # 5 + # Or with env vars from your shell: 6 + # IMAP_HOST=imap.mail.hostpoint.ch IMAP_USER=simu@sspaeti.com IMAP_PASS=$IMAP_PASS_SIMU ./scripts/imap-benchmark.sh 7 + # IMAP_HOST=imap.gmail.com IMAP_USER=demo@gmail.com IMAP_PASS=$GMAIL_APP_PASS ./scripts/imap-benchmark.sh 8 + 9 + set -e 10 + 11 + HOST="${IMAP_HOST:?Set IMAP_HOST (e.g. imap.gmail.com)}" 12 + USER="${IMAP_USER:?Set IMAP_USER (e.g. me@example.com)}" 13 + PASS="${IMAP_PASS:?Set IMAP_PASS (app password)}" 14 + PORT="${IMAP_PORT:-993}" 15 + 16 + python3 -c " 17 + import time, ssl, socket 18 + 19 + host, user, pw = '$HOST', '$USER', '$PASS' 20 + port = $PORT 21 + 22 + print(f'Benchmarking {host}:{port} as {user}...') 23 + print() 24 + 25 + ctx = ssl.create_default_context() 26 + 27 + # TLS connect 28 + start = time.time() 29 + s = ctx.wrap_socket(socket.socket(), server_hostname=host) 30 + s.settimeout(10) 31 + s.connect((host, port)) 32 + greeting = s.recv(4096) 33 + tls_ms = (time.time() - start) * 1000 34 + 35 + # LOGIN 36 + start = time.time() 37 + s.send(f'a1 LOGIN {user} {pw}\r\n'.encode()) 38 + resp = b'' 39 + while b'a1 ' not in resp: 40 + resp += s.recv(4096) 41 + login_ms = (time.time() - start) * 1000 42 + 43 + # SELECT INBOX 44 + start = time.time() 45 + s.send(b'a2 SELECT INBOX\r\n') 46 + resp = b'' 47 + while b'a2 ' not in resp: 48 + resp += s.recv(4096) 49 + select_ms = (time.time() - start) * 1000 50 + 51 + # UID SEARCH ALL 52 + start = time.time() 53 + s.send(b'a3 UID SEARCH ALL\r\n') 54 + resp = b'' 55 + while b'a3 ' not in resp: 56 + resp += s.recv(4096) 57 + search_ms = (time.time() - start) * 1000 58 + 59 + # Parse UIDs from SEARCH response and FETCH last 10 headers 60 + uids = [] 61 + for line in resp.decode(errors='replace').split('\r\n'): 62 + if '* SEARCH' in line: 63 + uids = [u for u in line.split()[2:] if u.isdigit()] 64 + break 65 + 66 + fetch_ms = 0 67 + if uids: 68 + last_uids = uids[-min(10, len(uids)):] 69 + uid_range = ','.join(last_uids) 70 + start = time.time() 71 + s.send(f'a4 UID FETCH {uid_range} (UID FLAGS ENVELOPE RFC822.SIZE BODYSTRUCTURE)\r\n'.encode()) 72 + resp = b'' 73 + while b'a4 OK' not in resp: 74 + resp += s.recv(8192) 75 + fetch_ms = (time.time() - start) * 1000 76 + 77 + # MOVE one email (to itself = NOOP, just measures command latency) 78 + move_ms = 0 79 + if uids: 80 + start = time.time() 81 + s.send(b'a5 NOOP\r\n') 82 + resp = b'' 83 + while b'a5 ' not in resp: 84 + resp += s.recv(4096) 85 + move_ms = (time.time() - start) * 1000 86 + 87 + s.send(b'a9 LOGOUT\r\n') 88 + s.close() 89 + 90 + total = login_ms + select_ms + search_ms + fetch_ms 91 + print(f' TLS connect: {tls_ms:6.0f}ms') 92 + print(f' LOGIN: {login_ms:6.0f}ms') 93 + print(f' SELECT INBOX: {select_ms:6.0f}ms') 94 + print(f' UID SEARCH: {search_ms:6.0f}ms') 95 + n = min(10, len(uids)) 96 + print(f' FETCH ({n:>2} hdr):{fetch_ms:6.0f}ms') 97 + print(f' NOOP: {move_ms:6.0f}ms') 98 + print(f' ─────────────────────') 99 + print(f' Total: {total:6.0f}ms') 100 + print() 101 + if total < 100: 102 + print(' Result: Excellent — neomd will feel instant') 103 + elif total < 300: 104 + print(' Result: Good — neomd will feel responsive') 105 + elif total < 1000: 106 + print(' Result: Slow — noticeable delay on folder switches') 107 + else: 108 + print(' Result: Very slow — neomd is not recommended with this provider') 109 + "