Switch to EXWM
[~bandali/configs] / .emacs.d / lisp / bandali-gnus.el
CommitLineData
4c05c418
AB
1;;; bandali-gnus.el --- bandali's Gnus setup -*- lexical-binding: t; -*-
2
78d731e1 3;; Copyright (C) 2018-2022 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
78d731e1 43(setq
c84be134
AB
44 mail-user-agent 'gnus-user-agent
45 read-mail-command 'gnus
46
47 gnus-select-method '(nnnil "")
48 gnus-secondary-select-methods
f1b31451
AB
49 `(,@(if (string= (system-name) "darya")
50 '((nnimap
51 "canonical"
52 (nnimap-stream plain)
53 (nnimap-address "127.0.0.1")
54 (nnimap-server-port 143)
55 (nnimap-authenticator plain)
56 (nnimap-user "bandali@canonical.local")))
8ab693f8 57 '((nnimap
3d36fc1a
AB
58 "kelar"
59 (nnimap-stream plain)
60 (nnimap-address "127.0.0.1")
61 (nnimap-server-port 143)
62 (nnimap-authenticator plain)
63 (nnimap-user "bandali@kelar.local"))
64 (nnimap
8ab693f8
AB
65 "shemshak"
66 (nnimap-stream plain)
67 (nnimap-address "127.0.0.1")
68 (nnimap-server-port 143)
69 (nnimap-authenticator plain)
70 (nnimap-user "bandali@shemshak.local"))
71 (nnimap
72 "gnu"
73 (nnimap-stream plain)
74 (nnimap-address "127.0.0.1")
75 (nnimap-server-port 143)
76 (nnimap-authenticator plain)
77 (nnimap-user "bandali@gnu.local")
78 (nnimap-inbox "INBOX")
79 (nnimap-split-methods 'nnimap-split-fancy)
80 (nnimap-split-fancy
81 (|
82 ;; (: gnus-registry-split-fancy-with-parent)
83 ;; (: gnus-group-split-fancy "INBOX" t "INBOX")
ae80aec8
AB
84 ;; spam
85 ("X-Spam_action" "reject" "Junk")
8ab693f8
AB
86 ;; keep debbugs emails in INBOX
87 (list ".*<\\(.*\\)\\.debbugs\\.gnu\\.org>.*" "INBOX")
88 ;; list moderation emails
89 (from ".+-\\(owner\\|bounces\\)@\\(non\\)?gnu\\.org" "listmod")
90 ;; gnu
91 (list ".*<\\(.*\\)\\.\\(non\\)?gnu\\.org>.*" "l.\\1")
3d36fc1a
AB
92 ;; fsf
93 (list ".*<\\(.*\\)\\.fsf\\.org>.*" "l.\\1")
8ab693f8
AB
94 ;; gnus
95 (list ".*<\\(.*\\)\\.gnus\\.org>.*" "l.\\1")
96 ;; libreplanet
97 (list ".*<\\(.*\\)\\.libreplanet\\.org>.*" "l.\\1")
98 ;; iana (e.g. tz-announce)
99 (list ".*<\\(.*\\)\\.iana\\.org>.*" "l.\\1")
3d36fc1a
AB
100 ;; mailop
101 (list ".*<\\(.*\\)\\.mailop\\.org>.*" "l.\\1")
102 ;; sdlu
103 (list ".*<\\(.*\\)\\.spammers\\.dontlike\\.us>.*" "l.sdlu")
104 ;; bitfolk
105 (from ".*@\\(.+\\)?bitfolk\\.com>.*" "bitfolk")
8ab693f8
AB
106 ;; haskell
107 (list ".*<\\(.*\\)\\.haskell\\.org>.*" "l.\\1")
108 ;; *.lists.sr.ht, omitting one dot if present
109 ;; add more \\.?\\([^.]*\\) if needed
110 (list ".*<~\\(.*\\)/\\([^.]*\\)\\.?\\([^.]*\\)\\.lists\\.sr\\.ht>.*" "l.~\\1.\\2\\3")
111 ;; webmasters
112 (from "webmasters\\(-comment\\)?@gnu\\.org" "webmasters")
113 ;; other
114 ("subject" "nagios-fsf:.*" "nagios-fsf")
115 (list ".*atreus.freelists.org" "l.atreus")
116 (list ".*deepspec.lists.cs.princeton.edu" "l.deepspec")
117 ;; (list ".*haskell-art.we.lurk.org" "l.haskell.art") ;d
118 ;; (list ".*notmuch.notmuchmail.org" "l.notmuch") ;u
119 (list ".*dev.lists.parabola.nu" "l.parabola-dev")
120 ;; ----------------------------------
121 ;; legend: (u)nsubscribed | (d)ead
122 ;; ----------------------------------
8ab693f8
AB
123 ;; otherwise, leave mail in INBOX
124 "INBOX")))
125 (nnimap
126 "uwaterloo"
127 (nnimap-stream plain)
128 (nnimap-address "127.0.0.1")
129 (nnimap-server-port 143)
130 (nnimap-authenticator plain)
131 (nnimap-user "abandali@uwaterloo.local")
132 (nnimap-inbox "INBOX")
133 (nnimap-split-methods 'nnimap-split-fancy)
134 (nnimap-split-fancy
135 (|
136 ;; (: gnus-registry-split-fancy-with-parent)
137 ;; se212-f19
138 ("subject" "SE\\s-?212" "course.se212-f19")
139 (from "SE\\s-?212" "course.se212-f19")
140 ;; catch-all
141 "INBOX")))
142 (nnimap
143 "csc"
144 (nnimap-stream plain)
145 (nnimap-address "127.0.0.1")
146 (nnimap-server-port 143)
147 (nnimap-authenticator plain)
148 (nnimap-user "abandali@csclub.uwaterloo.local")
149 (nnimap-inbox "INBOX")
150 (nnimap-split-methods 'nnimap-split-fancy)
151 (nnimap-split-fancy
152 (|
153 ;; cron reports and other messages from root
154 (from "root@\\(.*\\.\\)?csclub\\.uwaterloo\\.ca" "INBOX")
155 ;; spam
156 ("X-Spam-Flag" "YES" "Junk")
157 ;; catch-all
f1b31451 158 "INBOX")))
e23aff47
AB
159 (nnimap
160 "sfl"
161 (nnimap-stream plain)
162 (nnimap-address "127.0.0.1")
163 (nnimap-server-port 143)
164 (nnimap-authenticator plain)
165 (nnimap-user "amin.bandali@savoirfairelinux.local")))))
c84be134
AB
166 gnus-message-archive-group "nnimap+gnu:INBOX"
167 gnus-parameters
9867e4bb 168 '(("l\\.deepspec"
c84be134
AB
169 (to-address . "deepspec@lists.cs.princeton.edu")
170 (to-list . "deepspec@lists.cs.princeton.edu")
171 (list-identifier . "\\[deepspec\\]"))
c84be134
AB
172 ("l\\.fencepost-users"
173 (to-address . "fencepost-users@gnu.org")
174 (to-list . "fencepost-users@gnu.org")
175 (list-identifier . "\\[Fencepost-users\\]"))
c84be134
AB
176 ("l\\.haskell-cafe"
177 (to-address . "haskell-cafe@haskell.org")
178 (to-list . "haskell-cafe@haskell.org")
179 (list-identifier . "\\[Haskell-cafe\\]"))
c84be134 180 ("gnu.*"
c84be134
AB
181 (gcc-self . t)))
182 ;; nnimap-record-commands t
41fb7da0 183 ;; gnus-large-newsgroup 50
52b7a57a 184 ;; gnus-process-mark-toggle t
c84be134
AB
185 gnus-home-directory (b/var "gnus/")
186 gnus-directory (concat gnus-home-directory "news/")
187 message-directory (concat gnus-home-directory "mail/")
188 nndraft-directory (concat gnus-home-directory "drafts/")
189 gnus-save-newsrc-file nil
190 gnus-read-newsrc-file nil
adba94a7 191 gnus-search-use-parsed-queries t
c84be134
AB
192 gnus-interactive-exit nil
193 gnus-gcc-mark-as-read t)
194
195(with-eval-after-load 'gnus
2087ae39
AB
196 (when (version< emacs-version "27")
197 (with-eval-after-load 'nnmail
198 (add-to-list
199 'nnmail-split-abbrev-alist
200 '(list . "list-id\\|list-post\\|x-mailing-list\\|x-beenthere\\|x-loop")
201 t)))
202
6b09fc8a
AB
203 ;; (require 'gnus-registry)
204 ;; (setq gnus-registry-max-entries 2500)
205 ;; (setq gnus-registry-ignored-groups
206 ;; (append gnus-registry-ignored-groups
207 ;; '(("^nnimap:gnu\\.l" t)
208 ;; ("webmasters$" t))))
2087ae39
AB
209 ;; (gnus-registry-initialize)
210
211 (with-eval-after-load 'recentf
c84be134
AB
212 (add-to-list 'recentf-exclude gnus-home-directory))
213
214 ;; hooks
215 (add-hook 'gnus-group-mode-hook #'gnus-topic-mode)
216 (add-hook 'gnus-group-mode-hook #'gnus-agent-mode))
217;; global key bindings
55ac7968
AB
218(global-set-key (kbd "C-c g") #'gnus-plugged)
219(global-set-key (kbd "C-c G") #'gnus-unplugged)
2087ae39 220
c84be134 221(with-eval-after-load 'gnus-art
78d731e1 222 (setq
2087ae39
AB
223 gnus-buttonized-mime-types '("multipart/\\(signed\\|encrypted\\)")
224 gnus-sorted-header-list '("^From:"
225 "^X-RT-Originator"
226 "^Newsgroups:"
227 "^Subject:"
228 "^Date:"
229 "^Envelope-To:"
230 "^Followup-To:"
231 "^Reply-To:"
232 "^Organization:"
233 "^Summary:"
234 "^Abstract:"
235 "^Keywords:"
236 "^To:"
237 "^[BGF]?Cc:"
238 "^Posted-To:"
239 "^Mail-Copies-To:"
240 "^Mail-Followup-To:"
241 "^Apparently-To:"
242 "^Resent-From:"
243 "^User-Agent:"
244 "^X-detected-operating-system:"
6b09fc8a
AB
245 "^X-Spam_action:"
246 "^X-Spam_bar:"
2087ae39
AB
247 "^Message-ID:"
248 ;; "^References:"
249 "^List-Id:"
250 "^Gnus-Warning:")
f1b31451 251 gnus-visible-headers (mapconcat #'identity
2087ae39
AB
252 gnus-sorted-header-list
253 "\\|")
254 ;; local-lapsed article dates
255 ;; from https://www.emacswiki.org/emacs/GnusFormatting#toc11
256 gnus-article-date-headers '(user-defined)
257 gnus-article-time-format
258 (lambda (time)
259 (let* ((date (format-time-string "%a, %d %b %Y %T %z" time))
260 (local (article-make-date-line date 'local))
261 (combined-lapsed (article-make-date-line date
262 'combined-lapsed))
263 (lapsed (progn
264 (string-match " (.+" combined-lapsed)
265 (match-string 0 combined-lapsed))))
266 (concat local lapsed))))
c84be134 267 ;; local key bindings
41fb7da0 268 (declare-function org-store-link "ol" (arg &optional interactive?))
c84be134
AB
269 (define-key gnus-article-mode-map (kbd "M-L") #'org-store-link))
270
271(with-eval-after-load 'gnus-sum
78d731e1
AB
272 (setq gnus-thread-sort-functions '(gnus-thread-sort-by-number
273 gnus-thread-sort-by-subject
274 gnus-thread-sort-by-date))
c84be134
AB
275 ;; local key bindings
276 (define-key gnus-summary-mode-map (kbd "M-L") #'org-store-link)
5efecfcd
AB
277 ;; (define-key gnus-summary-mode-map (kbd "r")
278 ;; #'gnus-summary-reply-with-original)
279 ;; (define-key gnus-summary-mode-map (kbd "R")
280 ;; #'gnus-summary-wide-reply-with-original)
c84be134
AB
281 (defvar b/gnus-summary-prefix-map)
282 (define-prefix-command 'b/gnus-summary-prefix-map)
283 (define-key gnus-summary-mode-map (kbd "v")
284 'b/gnus-summary-prefix-map)
285 (define-key b/gnus-summary-prefix-map (kbd "r")
286 #'gnus-summary-reply)
287 (define-key b/gnus-summary-prefix-map (kbd "w")
288 #'gnus-summary-wide-reply)
289 (define-key b/gnus-summary-prefix-map (kbd "v")
290 #'gnus-summary-show-raw-article))
291;; hooks
292(add-hook 'gnus-summary-mode-hook #'b/no-mouse-autoselect-window)
293
294(defvar b/sfl-p nil)
295(with-eval-after-load 'gnus-msg
f1b31451
AB
296 (let ((bandali "Amin Bandali (https://kelar.org/~bandali)"))
297 (defvar b/canonical-signature
298 (mapconcat
299 #'identity
300 `(,bandali
301 "Software Engineer (Desktop), Canonical")
302 "\n"))
303 (defvar b/csc-signature
304 (mapconcat
305 #'identity
306 `(,bandali
307 "Systems Committee <syscom@csclub.uwaterloo.ca>"
308 "Computer Science Club of the University of Waterloo")
309 "\n"))
310 (defvar b/sfl-signature
311 (mapconcat
312 #'identity
313 `(,bandali
314 "Volunteer, Savoir-faire Linux"
315 "jami:bandali")
316 "\n")))
78d731e1 317 (setq
c84be134
AB
318 gnus-message-replysign t
319 gnus-posting-styles
320 '((".*"
a220fb5b
AB
321 (address "bandali@gnu.org")
322 ("X-Message-SMTP-Method" "smtp fencepost.gnu.org 587"))
c84be134
AB
323 ((header "subject" "ThankCRM")
324 (to "webmasters-comment@gnu.org")
f1b31451 325 (body ""))
3d36fc1a
AB
326 ("nnimap\\+kelar:.*"
327 (address "bandali@kelar.org")
328 ("X-Message-SMTP-Method" "smtp mail.kelar.org 587")
f1b31451 329 (gcc "nnimap+kelar:Sent"))
c84be134
AB
330 ("nnimap\\+shemshak:.*"
331 (address "amin@shemshak.org")
a220fb5b 332 ("X-Message-SMTP-Method" "smtp mail.shemshak.org 587")
f1b31451
AB
333 (gcc "nnimap+shemshak:Sent"))
334 ("nnimap\\+canonical:.*"
335 (address "amin.bandali@canonical.com")
336 ("X-Message-SMTP-Method" "smtp smtp.canonical.com 587")
337 (signature b/canonical-signature)
338 (gcc "nnimap+canonical:Sent"))
c84be134
AB
339 ("nnimap\\+csc:.*"
340 (address "bandali@csclub.uwaterloo.ca")
a220fb5b 341 ("X-Message-SMTP-Method" "smtp mail.csclub.uwaterloo.ca 587")
c84be134
AB
342 (signature b/csc-signature)
343 (gcc "nnimap+csc:Sent"))
344 ("nnimap\\+sfl:.*"
345 (address "amin.bandali@savoirfairelinux.com")
a220fb5b 346 ("X-Message-SMTP-Method" "smtp mail.savoirfairelinux.com 587")
f1b31451
AB
347 (signature b/sfl-signature)
348 (eval (setq-local b/sfl-p t))
349 (gcc "nnimap+sfl:Sent")))))
c84be134 350;; hooks
9867e4bb
AB
351;; (with-eval-after-load 'gnus
352;; (add-hook 'gnus-message-setup-hook
353;; (lambda ()
354;; (unless (or (mml-secure-is-encrypted-p)
355;; b/sfl-p)
356;; (mml-secure-message-sign)))))
c84be134
AB
357
358(with-eval-after-load 'gnus-topic
78d731e1 359 (setq
41fb7da0 360 gnus-topic-line-format "%i[ %A: %(%{%n%}%) ]%v\n"
8ab693f8
AB
361 gnus-topic-topology
362 `(("Gnus" visible nil nil)
363 (("misc" visible nil nil))
f1b31451
AB
364 ,@(if (string= (system-name) "darya")
365 '((("canonical" visible nil nil)))
8ab693f8
AB
366 '((("csc" visible nil nil))
367 (("uwaterloo" visible nil nil))
3d36fc1a 368 (("kelar" visible nil nil))
8ab693f8
AB
369 (("shemshak" visible nil nil))
370 (("gnu" visible nil nil))
f1b31451
AB
371 (("old-gnu" visible nil nil))
372 (("sfl" visible nil nil)))))))
c84be134
AB
373
374(with-eval-after-load 'gnus-agent
78d731e1 375 (setq gnus-agent-synchronize-flags 'ask))
c84be134
AB
376
377(with-eval-after-load 'gnus-group
78d731e1 378 (setq gnus-permanently-visible-groups "\\(:INBOX$\\|:gnu$\\)"))
2087ae39 379
bc04a4d4 380(with-eval-after-load 'gnus-win
78d731e1 381 (setq gnus-use-full-window nil))
2087ae39 382
c84be134 383(with-eval-after-load 'gnus-dired
2087ae39
AB
384 (add-hook 'dired-mode-hook 'gnus-dired-mode))
385
c84be134 386(with-eval-after-load 'mm-decode
78d731e1
AB
387 (setq
388 ;; mm-attachment-override-types `("text/x-diff" "text/x-patch"
389 ;; ,@mm-attachment-override-types)
390 mm-discouraged-alternatives '("text/html" "text/richtext")
391 mm-decrypt-option 'known
392 mm-verify-option 'known))
c84be134
AB
393
394(with-eval-after-load 'mm-uu
2087ae39
AB
395 (when (version< "27" emacs-version)
396 (set-face-attribute 'mm-uu-extract nil :extend t))
7c558c9b 397 (when (version< emacs-version "27")
78d731e1 398 (setq mm-uu-diff-groups-regexp ".")))
c84be134
AB
399
400(with-eval-after-load 'mml-sec
78d731e1
AB
401 (setq mml-secure-openpgp-encrypt-to-self t
402 mml-secure-openpgp-sign-with-sender t))
c84be134 403
2087ae39 404(provide 'bandali-gnus)
4c05c418 405;;; bandali-gnus.el ends here