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