migrate from msmtp (external) to emacs's own smtpmail
[~bandali/configs] / .emacs.d / lisp / bandali-gnus.el
CommitLineData
4c05c418
AB
1;;; bandali-gnus.el --- bandali's Gnus setup -*- lexical-binding: t; -*-
2
ccb32b49 3;; Copyright (C) 2018-2021 Amin Bandali
4c05c418
AB
4
5;; Author: Amin Bandali <bandali@gnu.org>
6;; Keywords: mail, news
7
8;; This program is free software; you can redistribute it and/or modify
9;; it under the terms of the GNU General Public License as published by
10;; the Free Software Foundation, either version 3 of the License, or
11;; (at your option) any later version.
12
13;; This program is distributed in the hope that it will be useful,
14;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16;; GNU General Public License for more details.
17
18;; You should have received a copy of the GNU General Public License
19;; along with this program. If not, see <https://www.gnu.org/licenses/>.
20
21;;; Commentary:
22
23;; My trusty super awesome Gnus setup.
24
25;;; Code:
26
2087ae39
AB
27(defvar b/maildir (expand-file-name "~/mail/"))
28(with-eval-after-load 'recentf
29 (add-to-list 'recentf-exclude b/maildir))
30
31(defvar b/gnus-init-file (b/etc "gnus"))
32
33(eval-when-compile
34 (progn
35 (defvar nndraft-directory)
36 (defvar gnus-read-newsrc-file)
37 (defvar gnus-save-newsrc-file)
38 (defvar gnus-gcc-mark-as-read)
39 (defvar nnmail-split-abbrev-alist)))
40
41(declare-function article-make-date-line "gnus-art" (date type))
42
c84be134
AB
43(csetq
44 mail-user-agent 'gnus-user-agent
45 read-mail-command 'gnus
46
47 gnus-select-method '(nnnil "")
48 gnus-secondary-select-methods
49 '((nnimap "shemshak"
50 (nnimap-stream plain)
51 (nnimap-address "127.0.0.1")
52 (nnimap-server-port 143)
53 (nnimap-authenticator plain)
54 (nnimap-user "bandali@shemshak.local"))
55 (nnimap "gnu"
56 (nnimap-stream plain)
57 (nnimap-address "127.0.0.1")
58 (nnimap-server-port 143)
59 (nnimap-authenticator plain)
60 (nnimap-user "bandali@gnu.local")
61 (nnimap-inbox "INBOX")
62 (nnimap-split-methods 'nnimap-split-fancy)
63 (nnimap-split-fancy (|
64 ;; (: gnus-registry-split-fancy-with-parent)
65 ;; (: gnus-group-split-fancy "INBOX" t "INBOX")
66 ;; keep debbugs emails in INBOX
67 (list ".*<\\(.*\\)\\.debbugs\\.gnu\\.org>.*" "INBOX")
5df34463
AB
68 ;; list moderation emails
69 (from ".+-\\(owner\\|bounces\\)@\\(non\\)?gnu\\.org" "listmod")
c84be134
AB
70 ;; gnu
71 (list ".*<\\(.*\\)\\.\\(non\\)?gnu\\.org>.*" "l.\\1")
72 ;; gnus
73 (list ".*<\\(.*\\)\\.gnus\\.org>.*" "l.\\1")
74 ;; libreplanet
75 (list ".*<\\(.*\\)\\.libreplanet\\.org>.*" "l.\\1")
76 ;; iana (e.g. tz-announce)
77 (list ".*<\\(.*\\)\\.iana\\.org>.*" "l.\\1")
adba94a7
AB
78 ;; haskell
79 (list ".*<\\(.*\\)\\.haskell\\.org>.*" "l.\\1")
c84be134
AB
80 ;; *.lists.sr.ht, omitting one dot if present
81 ;; add more \\.?\\([^.]*\\) if needed
82 (list ".*<~\\(.*\\)/\\([^.]*\\)\\.?\\([^.]*\\)\\.lists\\.sr\\.ht>.*" "l.~\\1.\\2\\3")
83 ;; webmasters
84 (from "webmasters\\(-comment\\)?@gnu\\.org" "webmasters")
85 ;; other
9867e4bb 86 ("subject" "nagios-fsf:.*" "nagios-fsf")
c84be134
AB
87 (list ".*atreus.freelists.org" "l.atreus")
88 (list ".*deepspec.lists.cs.princeton.edu" "l.deepspec")
89 ;; (list ".*haskell-art.we.lurk.org" "l.haskell.art") ;d
c84be134
AB
90 ;; (list ".*notmuch.notmuchmail.org" "l.notmuch") ;u
91 (list ".*dev.lists.parabola.nu" "l.parabola-dev")
92 ;; ----------------------------------
93 ;; legend: (u)nsubscribed | (d)ead
94 ;; ----------------------------------
95 ;; spam
96 ("X-Spam_action" "reject" "Junk")
97 ;; otherwise, leave mail in INBOX
98 "INBOX")))
99 (nnimap "uwaterloo"
100 (nnimap-stream plain)
101 (nnimap-address "127.0.0.1")
102 (nnimap-server-port 143)
103 (nnimap-authenticator plain)
104 (nnimap-user "abandali@uwaterloo.local")
105 (nnimap-inbox "INBOX")
106 (nnimap-split-methods 'nnimap-split-fancy)
107 (nnimap-split-fancy (|
108 ;; (: gnus-registry-split-fancy-with-parent)
109 ;; se212-f19
110 ("subject" "SE\\s-?212" "course.se212-f19")
111 (from "SE\\s-?212" "course.se212-f19")
112 ;; catch-all
113 "INBOX")))
114 (nnimap "csc"
115 (nnimap-stream plain)
116 (nnimap-address "127.0.0.1")
117 (nnimap-server-port 143)
118 (nnimap-authenticator plain)
119 (nnimap-user "abandali@csclub.uwaterloo.local")
120 (nnimap-inbox "INBOX")
121 (nnimap-split-methods 'nnimap-split-fancy)
122 (nnimap-split-fancy (|
123 ;; cron reports and other messages from root
124 (from "root@\\(.*\\.\\)?csclub\\.uwaterloo\\.ca" "INBOX")
125 ;; spam
126 ("X-Spam-Flag" "YES" "Junk")
127 ;; catch-all
128 "INBOX")))
129 (nnimap "sfl"
1fff6361
AB
130 (nnimap-stream plain)
131 (nnimap-address "127.0.0.1")
132 (nnimap-server-port 143)
133 (nnimap-authenticator plain)
134 (nnimap-user "amin.bandali@savoirfairelinux.local")))
c84be134
AB
135 gnus-message-archive-group "nnimap+gnu:INBOX"
136 gnus-parameters
9867e4bb 137 '(("l\\.deepspec"
c84be134
AB
138 (to-address . "deepspec@lists.cs.princeton.edu")
139 (to-list . "deepspec@lists.cs.princeton.edu")
140 (list-identifier . "\\[deepspec\\]"))
c84be134
AB
141 ("l\\.fencepost-users"
142 (to-address . "fencepost-users@gnu.org")
143 (to-list . "fencepost-users@gnu.org")
144 (list-identifier . "\\[Fencepost-users\\]"))
c84be134
AB
145 ("l\\.haskell-cafe"
146 (to-address . "haskell-cafe@haskell.org")
147 (to-list . "haskell-cafe@haskell.org")
148 (list-identifier . "\\[Haskell-cafe\\]"))
c84be134
AB
149 ("gnu.*"
150 (gcc-self . t))
9867e4bb
AB
151 ;; ("l\\."
152 ;; (subscribed . t))
c84be134
AB
153 ("nnimap\\+uwaterloo:.*"
154 (gcc-self . t)))
155 ;; nnimap-record-commands t
41fb7da0 156 ;; gnus-large-newsgroup 50
c84be134
AB
157 gnus-home-directory (b/var "gnus/")
158 gnus-directory (concat gnus-home-directory "news/")
159 message-directory (concat gnus-home-directory "mail/")
160 nndraft-directory (concat gnus-home-directory "drafts/")
161 gnus-save-newsrc-file nil
162 gnus-read-newsrc-file nil
adba94a7 163 gnus-search-use-parsed-queries t
c84be134
AB
164 gnus-interactive-exit nil
165 gnus-gcc-mark-as-read t)
166
167(with-eval-after-load 'gnus
2087ae39
AB
168 (when (version< emacs-version "27")
169 (with-eval-after-load 'nnmail
170 (add-to-list
171 'nnmail-split-abbrev-alist
172 '(list . "list-id\\|list-post\\|x-mailing-list\\|x-beenthere\\|x-loop")
173 t)))
174
6b09fc8a
AB
175 ;; (require 'gnus-registry)
176 ;; (setq gnus-registry-max-entries 2500)
177 ;; (setq gnus-registry-ignored-groups
178 ;; (append gnus-registry-ignored-groups
179 ;; '(("^nnimap:gnu\\.l" t)
180 ;; ("webmasters$" t))))
2087ae39
AB
181 ;; (gnus-registry-initialize)
182
183 (with-eval-after-load 'recentf
c84be134
AB
184 (add-to-list 'recentf-exclude gnus-home-directory))
185
186 ;; hooks
187 (add-hook 'gnus-group-mode-hook #'gnus-topic-mode)
188 (add-hook 'gnus-group-mode-hook #'gnus-agent-mode))
189;; global key bindings
adba94a7
AB
190(global-set-key (kbd "C-c m") #'gnus-plugged)
191(global-set-key (kbd "C-c M") #'gnus-unplugged)
2087ae39 192
c84be134
AB
193(with-eval-after-load 'gnus-art
194 (csetq
2087ae39
AB
195 gnus-buttonized-mime-types '("multipart/\\(signed\\|encrypted\\)")
196 gnus-sorted-header-list '("^From:"
197 "^X-RT-Originator"
198 "^Newsgroups:"
199 "^Subject:"
200 "^Date:"
201 "^Envelope-To:"
202 "^Followup-To:"
203 "^Reply-To:"
204 "^Organization:"
205 "^Summary:"
206 "^Abstract:"
207 "^Keywords:"
208 "^To:"
209 "^[BGF]?Cc:"
210 "^Posted-To:"
211 "^Mail-Copies-To:"
212 "^Mail-Followup-To:"
213 "^Apparently-To:"
214 "^Resent-From:"
215 "^User-Agent:"
216 "^X-detected-operating-system:"
6b09fc8a
AB
217 "^X-Spam_action:"
218 "^X-Spam_bar:"
2087ae39
AB
219 "^Message-ID:"
220 ;; "^References:"
221 "^List-Id:"
222 "^Gnus-Warning:")
223 gnus-visible-headers (mapconcat 'identity
224 gnus-sorted-header-list
225 "\\|")
226 ;; local-lapsed article dates
227 ;; from https://www.emacswiki.org/emacs/GnusFormatting#toc11
228 gnus-article-date-headers '(user-defined)
229 gnus-article-time-format
230 (lambda (time)
231 (let* ((date (format-time-string "%a, %d %b %Y %T %z" time))
232 (local (article-make-date-line date 'local))
233 (combined-lapsed (article-make-date-line date
234 'combined-lapsed))
235 (lapsed (progn
236 (string-match " (.+" combined-lapsed)
237 (match-string 0 combined-lapsed))))
238 (concat local lapsed))))
c84be134 239 ;; local key bindings
41fb7da0 240 (declare-function org-store-link "ol" (arg &optional interactive?))
c84be134
AB
241 (define-key gnus-article-mode-map (kbd "M-L") #'org-store-link))
242
243(with-eval-after-load 'gnus-sum
244 (csetq gnus-thread-sort-functions '(gnus-thread-sort-by-number
245 gnus-thread-sort-by-subject
246 gnus-thread-sort-by-date))
247 ;; local key bindings
248 (define-key gnus-summary-mode-map (kbd "M-L") #'org-store-link)
4d3b70c6
AB
249 (define-key gnus-summary-mode-map (kbd "r")
250 #'gnus-summary-reply-with-original)
251 (define-key gnus-summary-mode-map (kbd "R")
252 #'gnus-summary-wide-reply-with-original)
c84be134
AB
253 (defvar b/gnus-summary-prefix-map)
254 (define-prefix-command 'b/gnus-summary-prefix-map)
255 (define-key gnus-summary-mode-map (kbd "v")
256 'b/gnus-summary-prefix-map)
257 (define-key b/gnus-summary-prefix-map (kbd "r")
258 #'gnus-summary-reply)
259 (define-key b/gnus-summary-prefix-map (kbd "w")
260 #'gnus-summary-wide-reply)
261 (define-key b/gnus-summary-prefix-map (kbd "v")
262 #'gnus-summary-show-raw-article))
263;; hooks
264(add-hook 'gnus-summary-mode-hook #'b/no-mouse-autoselect-window)
265
266(defvar b/sfl-p nil)
267(with-eval-after-load 'gnus-msg
2087ae39 268 (defvar b/shemshak-signature "Amin Bandali
312e2f7a
AB
269https://shemshak.org/~bandali")
270 (defvar b/uwaterloo-signature "Amin Bandali, MMath
9867e4bb
AB
271https://shemshak.org/~bandali")
272 (defvar b/csc-signature "Amin Bandali (https://shemshak.org/~bandali)
8c4704d0
AB
273Systems Committee <syscom@csclub.uwaterloo.ca>
274Computer Science Club of the University of Waterloo")
c49fa11a
AB
275 (defvar b/sfl-signature "Amin Bandali
276Free Software Consultant
277Savoir-faire Linux
9867e4bb 278jami:bandali")
c84be134
AB
279 (csetq
280 gnus-message-replysign t
281 gnus-posting-styles
282 '((".*"
a220fb5b
AB
283 (address "bandali@gnu.org")
284 ("X-Message-SMTP-Method" "smtp fencepost.gnu.org 587"))
c84be134
AB
285 ("nnimap\\+gnu:l\\..*"
286 (signature nil))
c84be134
AB
287 ((header "subject" "ThankCRM")
288 (to "webmasters-comment@gnu.org")
289 (body "")
290 (eval (setq b/message-cite-say-hi nil)))
291 ("nnimap\\+shemshak:.*"
292 (address "amin@shemshak.org")
a220fb5b 293 ("X-Message-SMTP-Method" "smtp mail.shemshak.org 587")
c84be134
AB
294 (body "\nBest,\n")
295 (signature b/shemshak-signature)
296 (gcc "nnimap+shemshak:Sent")
297 (eval (setq b/message-cite-say-hi t)))
298 ("nnimap\\+uwaterloo:.*"
299 (address "bandali@uwaterloo.ca")
a220fb5b 300 ("X-Message-SMTP-Method" "smtp connect.uwaterloo.ca 587")
c84be134
AB
301 (body "\nBest,\n")
302 (signature b/uwaterloo-signature))
303 ("nnimap\\+uwaterloo:INBOX"
304 (gcc "\"nnimap+uwaterloo:Sent Items\""))
305 ("nnimap\\+csc:.*"
306 (address "bandali@csclub.uwaterloo.ca")
a220fb5b 307 ("X-Message-SMTP-Method" "smtp mail.csclub.uwaterloo.ca 587")
c84be134
AB
308 (signature b/csc-signature)
309 (gcc "nnimap+csc:Sent"))
310 ("nnimap\\+sfl:.*"
311 (address "amin.bandali@savoirfairelinux.com")
312 (signature b/sfl-signature)
a220fb5b 313 ("X-Message-SMTP-Method" "smtp mail.savoirfairelinux.com 587")
c84be134 314 (gcc "nnimap+sfl:Sent")
41fb7da0 315 (eval (setq-local b/sfl-p t))))))
c84be134 316;; hooks
9867e4bb
AB
317;; (with-eval-after-load 'gnus
318;; (add-hook 'gnus-message-setup-hook
319;; (lambda ()
320;; (unless (or (mml-secure-is-encrypted-p)
321;; b/sfl-p)
322;; (mml-secure-message-sign)))))
c84be134
AB
323
324(with-eval-after-load 'gnus-topic
41fb7da0
AB
325 (csetq
326 gnus-topic-line-format "%i[ %A: %(%{%n%}%) ]%v\n"
327 gnus-topic-topology '(("Gnus" visible nil nil)
328 (("misc" visible nil nil))
329 (("sfl" visible nil nil))
330 (("csc" visible nil nil))
331 (("uwaterloo" visible nil nil))
332 (("shemshak" visible nil nil))
333 (("gnu" visible nil nil))
334 (("old-gnu" visible nil nil)))))
c84be134
AB
335
336(with-eval-after-load 'gnus-agent
337 (csetq gnus-agent-synchronize-flags 'ask))
338
339(with-eval-after-load 'gnus-group
340 (csetq gnus-permanently-visible-groups "\\(:INBOX$\\|:gnu$\\)"))
2087ae39 341
bc04a4d4
AB
342(with-eval-after-load 'gnus-win
343 (csetq gnus-use-full-window nil))
2087ae39 344
c84be134 345(with-eval-after-load 'gnus-dired
2087ae39
AB
346 (add-hook 'dired-mode-hook 'gnus-dired-mode))
347
927b50b7
AB
348;; (with-eval-after-load 'gnus-utils
349;; (csetq gnus-completing-read-function 'gnus-ido-completing-read))
c84be134
AB
350
351(with-eval-after-load 'mm-decode
352 (csetq mm-discouraged-alternatives '("text/html" "text/richtext")
353 mm-decrypt-option 'known
354 mm-verify-option 'known))
355
356(with-eval-after-load 'mm-uu
2087ae39
AB
357 (when (version< "27" emacs-version)
358 (set-face-attribute 'mm-uu-extract nil :extend t))
7c558c9b 359 (when (version< emacs-version "27")
c84be134
AB
360 (csetq mm-uu-diff-groups-regexp ".")))
361
362(with-eval-after-load 'mml-sec
363 (csetq mml-secure-openpgp-encrypt-to-self t
364 mml-secure-openpgp-sign-with-sender t))
365
366;; (require 'gnus-article-treat-patch)
367;; ;; note: be sure to customize faces with `:foreground "white"' when
368;; ;; using a theme with a white/light background :)
369;; (setq ft/gnus-article-patch-conditions
370;; '("^@@ -[0-9]+,[0-9]+ \\+[0-9]+,[0-9]+ @@"))
e2178fd3 371
2087ae39 372(provide 'bandali-gnus)
4c05c418 373;;; bandali-gnus.el ends here