de01c0f4e6f65b383bf07c2561745b745d01a6a3
[~bandali/configs] / lisp / bandali-gnus.el
1 ;;; bandali-gnus.el --- bandali's Gnus setup -*- lexical-binding: t; -*-
2
3 ;; Copyright (C) 2018-2020 Amin Bandali
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
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
43 (setq
44 mail-user-agent 'gnus-user-agent
45 read-mail-command 'gnus)
46
47 (use-package gnus
48 :bind (("s-m" . gnus-plugged)
49 ("s-M" . gnus-unplugged)
50 ("C-c a m" . gnus-plugged)
51 ("C-c a M" . gnus-unplugged))
52 :init
53 (setq
54 gnus-select-method '(nnnil "")
55 gnus-secondary-select-methods
56 '((nnimap "shemshak"
57 (nnimap-stream plain)
58 (nnimap-address "127.0.0.1")
59 (nnimap-server-port 143)
60 (nnimap-authenticator plain)
61 (nnimap-user "amin@shemshak.local"))
62 (nnimap "gnu"
63 (nnimap-stream plain)
64 (nnimap-address "127.0.0.1")
65 (nnimap-server-port 143)
66 (nnimap-authenticator plain)
67 (nnimap-user "bandali@gnu.local")
68 (nnimap-inbox "INBOX")
69 (nnimap-split-methods 'nnimap-split-fancy)
70 (nnimap-split-fancy (|
71 ;; (: gnus-registry-split-fancy-with-parent)
72 ;; (: gnus-group-split-fancy "INBOX" t "INBOX")
73 ;; gnu
74 (list ".*<\\(.*\\)\\.\\(non\\)?gnu\\.org>.*" "l.\\1")
75 ;; gnus
76 (list ".*<\\(.*\\)\\.gnus\\.org>.*" "l.\\1")
77 ;; libreplanet
78 (list ".*<\\(.*\\)\\.libreplanet\\.org>.*" "l.\\1")
79 ;; *.lists.sr.ht, omitting one dot if present
80 ;; add more \\.?\\([^.]*\\) if needed
81 (list ".*<~\\(.*\\)/\\([^.]*\\)\\.?\\([^.]*\\)\\.lists.sr.ht>.*" "l.~\\1.\\2\\3")
82 ;; webmasters
83 (from "webmasters\\(-comment\\)?@gnu\\.org" "webmasters")
84 ;; other
85 (list ".*atreus.freelists.org" "l.atreus")
86 (list ".*deepspec.lists.cs.princeton.edu" "l.deepspec")
87 ;; (list ".*haskell-art.we.lurk.org" "l.haskell.art") ;d
88 (list ".*haskell-cafe.haskell.org" "l.haskell-cafe")
89 ;; (list ".*notmuch.notmuchmail.org" "l.notmuch") ;u
90 ;; (list ".*dev.lists.parabola.nu" "l.parabola-dev") ;u
91 ;; ----------------------------------
92 ;; legend: (u)nsubscribed | (d)ead
93 ;; ----------------------------------
94 ;; otherwise, leave mail in INBOX
95 "INBOX")))
96 (nnimap "uw"
97 (nnimap-stream plain)
98 (nnimap-address "127.0.0.1")
99 (nnimap-server-port 143)
100 (nnimap-authenticator plain)
101 (nnimap-user "abandali@uw.local")
102 (nnimap-inbox "INBOX")
103 (nnimap-split-methods 'nnimap-split-fancy)
104 (nnimap-split-fancy (|
105 ;; (: gnus-registry-split-fancy-with-parent)
106 ;; se212-f19
107 ("subject" "SE\\s-?212" "course.se212-f19")
108 (from "SE\\s-?212" "course.se212-f19")
109 ;; catch-all
110 "INBOX")))
111 (nnimap "csc"
112 (nnimap-stream plain)
113 (nnimap-address "127.0.0.1")
114 (nnimap-server-port 143)
115 (nnimap-authenticator plain)
116 (nnimap-user "abandali@csc.uw.local")))
117 gnus-message-archive-group "nnimap+gnu:INBOX"
118 gnus-parameters
119 '(("l\\.atreus"
120 (to-address . "atreus@freelists.org")
121 (to-list . "atreus@freelists.org"))
122 ("l\\.deepspec"
123 (to-address . "deepspec@lists.cs.princeton.edu")
124 (to-list . "deepspec@lists.cs.princeton.edu")
125 (list-identifier . "\\[deepspec\\]"))
126 ("l\\.emacs-devel"
127 (to-address . "emacs-devel@gnu.org")
128 (to-list . "emacs-devel@gnu.org"))
129 ("l\\.help-gnu-emacs"
130 (to-address . "help-gnu-emacs@gnu.org")
131 (to-list . "help-gnu-emacs@gnu.org"))
132 ("l\\.info-gnu-emacs"
133 (to-address . "info-gnu-emacs@gnu.org")
134 (to-list . "info-gnu-emacs@gnu.org"))
135 ("l\\.emacs-orgmode"
136 (to-address . "emacs-orgmode@gnu.org")
137 (to-list . "emacs-orgmode@gnu.org")
138 (list-identifier . "\\[O\\]"))
139 ("l\\.emacs-tangents"
140 (to-address . "emacs-tangents@gnu.org")
141 (to-list . "emacs-tangents@gnu.org"))
142 ("l\\.emacsconf-committee"
143 (to-address . "emacsconf-committee@gnu.org")
144 (to-list . "emacsconf-committee@gnu.org"))
145 ("l\\.emacsconf-discuss"
146 (to-address . "emacsconf-discuss@gnu.org")
147 (to-list . "emacsconf-discuss@gnu.org"))
148 ("l\\.emacsconf-register"
149 (to-address . "emacsconf-register@gnu.org")
150 (to-list . "emacsconf-register@gnu.org"))
151 ("l\\.emacsconf-submit"
152 (to-address . "emacsconf-submit@gnu.org")
153 (to-list . "emacsconf-submit@gnu.org"))
154 ("l\\.fencepost-users"
155 (to-address . "fencepost-users@gnu.org")
156 (to-list . "fencepost-users@gnu.org")
157 (list-identifier . "\\[Fencepost-users\\]"))
158 ("l\\.gnewsense-art"
159 (to-address . "gnewsense-art@nongnu.org")
160 (to-list . "gnewsense-art@nongnu.org")
161 (list-identifier . "\\[gNewSense-art\\]"))
162 ("l\\.gnewsense-dev"
163 (to-address . "gnewsense-dev@nongnu.org")
164 (to-list . "gnewsense-dev@nongnu.org")
165 (list-identifier . "\\[Gnewsense-dev\\]"))
166 ("l\\.gnewsense-users"
167 (to-address . "gnewsense-users@nongnu.org")
168 (to-list . "gnewsense-users@nongnu.org")
169 (list-identifier . "\\[gNewSense-users\\]"))
170 ("l\\.gnunet-developers"
171 (to-address . "gnunet-developers@gnu.org")
172 (to-list . "gnunet-developers@gnu.org")
173 (list-identifier . "\\[GNUnet-developers\\]"))
174 ("l\\.help-gnunet"
175 (to-address . "help-gnunet@gnu.org")
176 (to-list . "help-gnunet@gnu.org")
177 (list-identifier . "\\[Help-gnunet\\]"))
178 ("l\\.bug-gnuzilla"
179 (to-address . "bug-gnuzilla@gnu.org")
180 (to-list . "bug-gnuzilla@gnu.org")
181 (list-identifier . "\\[Bug-gnuzilla\\]"))
182 ("l\\.gnuzilla-dev"
183 (to-address . "gnuzilla-dev@gnu.org")
184 (to-list . "gnuzilla-dev@gnu.org")
185 (list-identifier . "\\[Gnuzilla-dev\\]"))
186 ("l\\.guile-devel"
187 (to-address . "guile-devel@gnu.org")
188 (to-list . "guile-devel@gnu.org"))
189 ("l\\.guile-user"
190 (to-address . "guile-user@gnu.org")
191 (to-list . "guile-user@gnu.org"))
192 ("l\\.guix-devel"
193 (to-address . "guix-devel@gnu.org")
194 (to-list . "guix-devel@gnu.org"))
195 ("l\\.help-guix"
196 (to-address . "help-guix@gnu.org")
197 (to-list . "help-guix@gnu.org"))
198 ("l\\.info-guix"
199 (to-address . "info-guix@gnu.org")
200 (to-list . "info-guix@gnu.org"))
201 ("l\\.savannah-hackers-public"
202 (to-address . "savannah-hackers-public@gnu.org")
203 (to-list . "savannah-hackers-public@gnu.org"))
204 ("l\\.savannah-users"
205 (to-address . "savannah-users@gnu.org")
206 (to-list . "savannah-users@gnu.org"))
207 ("l\\.www-commits"
208 (to-address . "www-commits@gnu.org")
209 (to-list . "www-commits@gnu.org"))
210 ("l\\.www-discuss"
211 (to-address . "www-discuss@gnu.org")
212 (to-list . "www-discuss@gnu.org"))
213 ("l\\.haskell-art"
214 (to-address . "haskell-art@we.lurk.org")
215 (to-list . "haskell-art@we.lurk.org")
216 (list-identifier . "\\[haskell-art\\]"))
217 ("l\\.haskell-cafe"
218 (to-address . "haskell-cafe@haskell.org")
219 (to-list . "haskell-cafe@haskell.org")
220 (list-identifier . "\\[Haskell-cafe\\]"))
221 ("l\\.notmuch"
222 (to-address . "notmuch@notmuchmail.org")
223 (to-list . "notmuch@notmuchmail.org"))
224 ("l\\.parabola-dev"
225 (to-address . "dev@lists.parabola.nu")
226 (to-list . "dev@lists.parabola.nu")
227 (list-identifier . "\\[Dev\\]"))
228 ("l\\.~bandali\\.public-inbox"
229 (to-address . "~bandali/public-inbox@lists.sr.ht")
230 (to-list . "~bandali/public-inbox@lists.sr.ht"))
231 ("l\\.~sircmpwn\\.free-writers-club"
232 (to-address . "~sircmpwn/free-writers-club@lists.sr.ht")
233 (to-list . "~sircmpwn/free-writers-club@lists.sr.ht"))
234 ("l\\.~sircmpwn\\.srht-admins"
235 (to-address . "~sircmpwn/sr.ht-admins@lists.sr.ht")
236 (to-list . "~sircmpwn/sr.ht-admins@lists.sr.ht"))
237 ("l\\.~sircmpwn\\.srht-announce"
238 (to-address . "~sircmpwn/sr.ht-announce@lists.sr.ht")
239 (to-list . "~sircmpwn/sr.ht-announce@lists.sr.ht"))
240 ("l\\.~sircmpwn\\.srht-dev"
241 (to-address . "~sircmpwn/sr.ht-dev@lists.sr.ht")
242 (to-list . "~sircmpwn/sr.ht-dev@lists.sr.ht"))
243 ("l\\.~sircmpwn\\.srht-discuss"
244 (to-address . "~sircmpwn/sr.ht-discuss@lists.sr.ht")
245 (to-list . "~sircmpwn/sr.ht-discuss@lists.sr.ht"))
246 ("webmasters"
247 (to-address . "webmasters@gnu.org")
248 (to-list . "webmasters@gnu.org"))
249 ("gnu.*"
250 (gcc-self . t))
251 ("l\\."
252 (subscribed . t))
253 ("nnimap\\+uw:.*"
254 (gcc-self . t)))
255 gnus-large-newsgroup 50
256 gnus-home-directory (b/var "gnus/")
257 gnus-directory (concat gnus-home-directory "news/")
258 message-directory (concat gnus-home-directory "mail/")
259 nndraft-directory (concat gnus-home-directory "drafts/")
260 gnus-save-newsrc-file nil
261 gnus-read-newsrc-file nil
262 gnus-interactive-exit nil
263 gnus-gcc-mark-as-read t)
264 :config
265 (when (version< emacs-version "27")
266 (with-eval-after-load 'nnmail
267 (add-to-list
268 'nnmail-split-abbrev-alist
269 '(list . "list-id\\|list-post\\|x-mailing-list\\|x-beenthere\\|x-loop")
270 t)))
271
272 ;; (gnus-registry-initialize)
273
274 (with-eval-after-load 'recentf
275 (add-to-list 'recentf-exclude gnus-home-directory)))
276
277 (use-package gnus-art
278 :config
279 (setq
280 gnus-buttonized-mime-types '("multipart/\\(signed\\|encrypted\\)")
281 gnus-sorted-header-list '("^From:"
282 "^X-RT-Originator"
283 "^Newsgroups:"
284 "^Subject:"
285 "^Date:"
286 "^Envelope-To:"
287 "^Followup-To:"
288 "^Reply-To:"
289 "^Organization:"
290 "^Summary:"
291 "^Abstract:"
292 "^Keywords:"
293 "^To:"
294 "^[BGF]?Cc:"
295 "^Posted-To:"
296 "^Mail-Copies-To:"
297 "^Mail-Followup-To:"
298 "^Apparently-To:"
299 "^Resent-From:"
300 "^User-Agent:"
301 "^X-detected-operating-system:"
302 "^Message-ID:"
303 ;; "^References:"
304 "^List-Id:"
305 "^Gnus-Warning:")
306 gnus-visible-headers (mapconcat 'identity
307 gnus-sorted-header-list
308 "\\|")
309 ;; local-lapsed article dates
310 ;; from https://www.emacswiki.org/emacs/GnusFormatting#toc11
311 gnus-article-date-headers '(user-defined)
312 gnus-article-time-format
313 (lambda (time)
314 (let* ((date (format-time-string "%a, %d %b %Y %T %z" time))
315 (local (article-make-date-line date 'local))
316 (combined-lapsed (article-make-date-line date
317 'combined-lapsed))
318 (lapsed (progn
319 (string-match " (.+" combined-lapsed)
320 (match-string 0 combined-lapsed))))
321 (concat local lapsed))))
322 (bind-keys
323 :map gnus-article-mode-map
324 ("M-L" . org-store-link)))
325
326 (use-package gnus-sum
327 :bind (:map gnus-summary-mode-map
328 :prefix-map b/gnus-summary-prefix-map
329 :prefix "v"
330 ("r" . gnus-summary-reply)
331 ("w" . gnus-summary-wide-reply)
332 ("v" . gnus-summary-show-raw-article))
333 :config
334 (bind-keys
335 :map gnus-summary-mode-map
336 ("M-L" . org-store-link))
337 :hook (gnus-summary-mode . b/no-mouse-autoselect-window)
338 :custom
339 (gnus-thread-sort-functions '(gnus-thread-sort-by-number
340 gnus-thread-sort-by-subject
341 gnus-thread-sort-by-date)))
342
343 (use-package gnus-msg
344 :config
345 (defvar b/shemshak-signature "Amin Bandali
346 https://shemshak.org/~amin")
347 (defvar b/uw-signature "Amin Bandali, MMath Student
348 Cheriton School of Computer Science
349 University of Waterloo
350 https://bandali.eu.org")
351 (defvar b/csc-signature "Amin Bandali
352 System Administrator, Systems Committee
353 Computer Science Club, University of Waterloo
354 https://csclub.uwaterloo.ca/~abandali")
355 (setq gnus-message-replysign t
356 gnus-posting-styles
357 '((".*"
358 (address "bandali@gnu.org"))
359 ("nnimap\\+gnu:l\\..*"
360 (signature nil))
361 ("nnimap\\+gnu:.*"
362 (organization "GNU"))
363 ((header "subject" "ThankCRM")
364 (to "webmasters-comment@gnu.org")
365 (body "")
366 (eval (setq b/message-cite-say-hi nil)))
367 ("nnimap\\+shemshak:.*"
368 (address "amin@shemshak.org")
369 (body "\nBest,\n")
370 (signature b/shemshak-signature)
371 (gcc "nnimap+shemshak:Sent")
372 (eval (setq b/message-cite-say-hi t)))
373 ("nnimap\\+uw:.*"
374 (address "bandali@uwaterloo.ca")
375 (body "\nBest,\n")
376 (signature b/uw-signature))
377 ("nnimap\\+uw:INBOX"
378 (gcc "\"nnimap+uw:Sent Items\""))
379 ("nnimap\\+csc:.*"
380 (address "bandali@csclub.uwaterloo.ca")
381 (signature b/csc-signature)
382 (gcc "nnimap+csc:Sent"))))
383 :hook (gnus-message-setup . (lambda ()
384 (unless (mml-secure-is-encrypted-p)
385 (mml-secure-message-sign)))))
386
387 (use-package gnus-topic
388 :hook (gnus-group-mode . gnus-topic-mode)
389 :config (setq gnus-topic-line-format "%i[ %A: %(%{%n%}%) ]%v\n"))
390
391 (use-package gnus-agent
392 :config
393 (setq gnus-agent-synchronize-flags 'ask)
394 :hook (gnus-group-mode . gnus-agent-mode))
395
396 (use-package gnus-group
397 :config
398 (setq gnus-permanently-visible-groups "\\(:INBOX$\\|:gnu$\\)"))
399
400 (comment
401 ;; problematic with ebdb's popup, *EBDB-Gnus*
402 (use-package gnus-win
403 :config
404 (setq gnus-use-full-window nil)))
405
406 (use-package gnus-dired
407 :commands gnus-dired-mode
408 :init
409 (add-hook 'dired-mode-hook 'gnus-dired-mode))
410
411 (comment
412 (use-package gnus-utils
413 :custom
414 (gnus-completing-read-function 'gnus-ido-completing-read)))
415
416 (use-package mm-decode
417 :config
418 (setq mm-discouraged-alternatives '("text/html" "text/richtext")
419 mm-decrypt-option 'known
420 mm-verify-option 'known))
421
422 (use-package mm-uu
423 :config
424 (when (version< "27" emacs-version)
425 (set-face-attribute 'mm-uu-extract nil :extend t))
426 :custom
427 (mm-uu-diff-groups-regexp
428 "\\(gmane\\|gnu\\|l\\)\\..*\\(diff\\|commit\\|cvs\\|bug\\|dev\\)"))
429
430 (use-package mml)
431
432 (use-package mml-sec
433 :custom
434 (mml-secure-openpgp-encrypt-to-self t)
435 (mml-secure-openpgp-sign-with-sender t))
436
437 (use-package gnus-article-treat-patch
438 :disabled
439 :demand
440 :load-path "lisp/"
441 :config
442 ;; note: be sure to customize faces with `:foreground "white"' when
443 ;; using a theme with a white/light background :)
444 (setq ft/gnus-article-patch-conditions
445 '("^@@ -[0-9]+,[0-9]+ \\+[0-9]+,[0-9]+ @@")))
446
447 (provide 'bandali-gnus)
448 ;;; bandali-gnus.el ends here