1 ;;; bandali-gnus.el --- bandali's Gnus setup -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2018-2020 Amin Bandali
5 ;; Author: Amin Bandali <bandali@gnu.org>
6 ;; Keywords: mail, news
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.
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.
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/>.
23 ;; My trusty super awesome Gnus setup.
27 (defvar b
/maildir
(expand-file-name "~/mail/"))
28 (with-eval-after-load 'recentf
29 (add-to-list 'recentf-exclude b
/maildir
))
31 (defvar b
/gnus-init-file
(b/etc
"gnus"))
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
)))
41 (declare-function article-make-date-line
"gnus-art" (date type
))
44 mail-user-agent
'gnus-user-agent
45 read-mail-command
'gnus
47 gnus-select-method
'(nnnil "")
48 gnus-secondary-select-methods
51 (nnimap-address "127.0.0.1")
52 (nnimap-server-port 143)
53 (nnimap-authenticator plain
)
54 (nnimap-user "bandali@shemshak.local"))
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")
68 ;; list moderation emails
69 (from ".+-\\(owner\\|bounces\\)@\\(non\\)?gnu\\.org" "listmod")
71 (list ".*<\\(.*\\)\\.\\(non\\)?gnu\\.org>.*" "l.\\1")
73 (list ".*<\\(.*\\)\\.gnus\\.org>.*" "l.\\1")
75 (list ".*<\\(.*\\)\\.libreplanet\\.org>.*" "l.\\1")
76 ;; iana (e.g. tz-announce)
77 (list ".*<\\(.*\\)\\.iana\\.org>.*" "l.\\1")
78 ;; orbitalfox (e.g. gemini)
79 (list ".*<\\(.*\\)\\.lists\\.orbitalfox\\.eu>.*" "l.\\1")
80 ;; *.lists.sr.ht, omitting one dot if present
81 ;; add more \\.?\\([^.]*\\) if needed
82 (list ".*<~\\(.*\\)/\\([^.]*\\)\\.?\\([^.]*\\)\\.lists\\.sr\\.ht>.*" "l.~\\1.\\2\\3")
84 (from "webmasters\\(-comment\\)?@gnu\\.org" "webmasters")
86 (list ".*atreus.freelists.org" "l.atreus")
87 (list ".*deepspec.lists.cs.princeton.edu" "l.deepspec")
88 ;; (list ".*haskell-art.we.lurk.org" "l.haskell.art") ;d
89 (list ".*haskell-cafe.haskell.org" "l.haskell-cafe")
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 ;; ----------------------------------
96 ("X-Spam_action" "reject" "Junk")
97 ;; otherwise, leave mail in INBOX
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)
110 ("subject" "SE\\s-?212" "course.se212-f19")
111 (from "SE\\s-?212" "course.se212-f19")
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")
126 ("X-Spam-Flag" "YES" "Junk")
131 (nnimap-address "mail.savoirfairelinux.com")
132 (nnimap-user "amin.bandali")))
133 gnus-message-archive-group
"nnimap+gnu:INBOX"
136 (to-address .
"atreus@freelists.org")
137 (to-list .
"atreus@freelists.org"))
139 (to-address .
"deepspec@lists.cs.princeton.edu")
140 (to-list .
"deepspec@lists.cs.princeton.edu")
141 (list-identifier .
"\\[deepspec\\]"))
143 (to-address .
"emacs-devel@gnu.org")
144 (to-list .
"emacs-devel@gnu.org"))
145 ("l\\.help-gnu-emacs"
146 (to-address .
"help-gnu-emacs@gnu.org")
147 (to-list .
"help-gnu-emacs@gnu.org"))
148 ("l\\.info-gnu-emacs"
149 (to-address .
"info-gnu-emacs@gnu.org")
150 (to-list .
"info-gnu-emacs@gnu.org"))
152 (to-address .
"emacs-orgmode@gnu.org")
153 (to-list .
"emacs-orgmode@gnu.org")
154 (list-identifier .
"\\[O\\]"))
155 ("l\\.emacs-tangents"
156 (to-address .
"emacs-tangents@gnu.org")
157 (to-list .
"emacs-tangents@gnu.org"))
158 ("l\\.emacsconf-committee"
159 (to-address .
"emacsconf-committee@gnu.org")
160 (to-list .
"emacsconf-committee@gnu.org"))
161 ("l\\.emacsconf-discuss"
162 (to-address .
"emacsconf-discuss@gnu.org")
163 (to-list .
"emacsconf-discuss@gnu.org"))
165 (to-address .
"emacsconf-org@gnu.org")
166 (to-list .
"emacsconf-org@gnu.org"))
167 ("l\\.emacsconf-org-private"
168 (to-address .
"emacsconf-org-private@gnu.org")
169 (to-list .
"emacsconf-org-private@gnu.org"))
170 ("l\\.emacsconf-register"
171 (to-address .
"emacsconf-register@gnu.org")
172 (to-list .
"emacsconf-register@gnu.org"))
173 ("l\\.emacsconf-submit"
174 (to-address .
"emacsconf-submit@gnu.org")
175 (to-list .
"emacsconf-submit@gnu.org"))
176 ("l\\.fencepost-users"
177 (to-address .
"fencepost-users@gnu.org")
178 (to-list .
"fencepost-users@gnu.org")
179 (list-identifier .
"\\[Fencepost-users\\]"))
181 (to-address .
"gnewsense-art@nongnu.org")
182 (to-list .
"gnewsense-art@nongnu.org")
183 (list-identifier .
"\\[gNewSense-art\\]"))
185 (to-address .
"gnewsense-dev@nongnu.org")
186 (to-list .
"gnewsense-dev@nongnu.org")
187 (list-identifier .
"\\[Gnewsense-dev\\]"))
188 ("l\\.gnewsense-users"
189 (to-address .
"gnewsense-users@nongnu.org")
190 (to-list .
"gnewsense-users@nongnu.org")
191 (list-identifier .
"\\[gNewSense-users\\]"))
192 ("l\\.gnunet-developers"
193 (to-address .
"gnunet-developers@gnu.org")
194 (to-list .
"gnunet-developers@gnu.org")
195 (list-identifier .
"\\[GNUnet-developers\\]"))
197 (to-address .
"help-gnunet@gnu.org")
198 (to-list .
"help-gnunet@gnu.org")
199 (list-identifier .
"\\[Help-gnunet\\]"))
201 (to-address .
"bug-gnuzilla@gnu.org")
202 (to-list .
"bug-gnuzilla@gnu.org")
203 (list-identifier .
"\\[Bug-gnuzilla\\]"))
205 (to-address .
"gnuzilla-dev@gnu.org")
206 (to-list .
"gnuzilla-dev@gnu.org")
207 (list-identifier .
"\\[Gnuzilla-dev\\]"))
209 (to-address .
"guile-devel@gnu.org")
210 (to-list .
"guile-devel@gnu.org"))
212 (to-address .
"guile-user@gnu.org")
213 (to-list .
"guile-user@gnu.org"))
215 (to-address .
"guix-devel@gnu.org")
216 (to-list .
"guix-devel@gnu.org"))
218 (to-address .
"help-guix@gnu.org")
219 (to-list .
"help-guix@gnu.org"))
221 (to-address .
"info-guix@gnu.org")
222 (to-list .
"info-guix@gnu.org"))
223 ("l\\.savannah-hackers-public"
224 (to-address .
"savannah-hackers-public@gnu.org")
225 (to-list .
"savannah-hackers-public@gnu.org"))
226 ("l\\.savannah-users"
227 (to-address .
"savannah-users@gnu.org")
228 (to-list .
"savannah-users@gnu.org"))
230 (to-address .
"www-commits@gnu.org")
231 (to-list .
"www-commits@gnu.org"))
233 (to-address .
"www-discuss@gnu.org")
234 (to-list .
"www-discuss@gnu.org"))
236 (to-address .
"haskell-art@we.lurk.org")
237 (to-list .
"haskell-art@we.lurk.org")
238 (list-identifier .
"\\[haskell-art\\]"))
240 (to-address .
"haskell-cafe@haskell.org")
241 (to-list .
"haskell-cafe@haskell.org")
242 (list-identifier .
"\\[Haskell-cafe\\]"))
244 (to-address .
"notmuch@notmuchmail.org")
245 (to-list .
"notmuch@notmuchmail.org"))
247 (to-address .
"dev@lists.parabola.nu")
248 (to-list .
"dev@lists.parabola.nu")
249 (list-identifier .
"\\[Dev\\]"))
250 ("l\\.~bandali\\.public-inbox"
251 (to-address .
"~bandali/public-inbox@lists.sr.ht")
252 (to-list .
"~bandali/public-inbox@lists.sr.ht"))
253 ("l\\.~sircmpwn\\.free-writers-club"
254 (to-address .
"~sircmpwn/free-writers-club@lists.sr.ht")
255 (to-list .
"~sircmpwn/free-writers-club@lists.sr.ht"))
256 ("l\\.~sircmpwn\\.srht-admins"
257 (to-address .
"~sircmpwn/sr.ht-admins@lists.sr.ht")
258 (to-list .
"~sircmpwn/sr.ht-admins@lists.sr.ht"))
259 ("l\\.~sircmpwn\\.srht-announce"
260 (to-address .
"~sircmpwn/sr.ht-announce@lists.sr.ht")
261 (to-list .
"~sircmpwn/sr.ht-announce@lists.sr.ht"))
262 ("l\\.~sircmpwn\\.srht-dev"
263 (to-address .
"~sircmpwn/sr.ht-dev@lists.sr.ht")
264 (to-list .
"~sircmpwn/sr.ht-dev@lists.sr.ht"))
265 ("l\\.~sircmpwn\\.srht-discuss"
266 (to-address .
"~sircmpwn/sr.ht-discuss@lists.sr.ht")
267 (to-list .
"~sircmpwn/sr.ht-discuss@lists.sr.ht"))
269 (to-address .
"webmasters@gnu.org")
270 (to-list .
"webmasters@gnu.org"))
275 ("nnimap\\+uwaterloo:.*"
277 ;; nnimap-record-commands t
278 gnus-large-newsgroup
50
279 gnus-home-directory
(b/var
"gnus/")
280 gnus-directory
(concat gnus-home-directory
"news/")
281 message-directory
(concat gnus-home-directory
"mail/")
282 nndraft-directory
(concat gnus-home-directory
"drafts/")
283 gnus-save-newsrc-file nil
284 gnus-read-newsrc-file nil
285 gnus-interactive-exit nil
286 gnus-gcc-mark-as-read t
)
288 (with-eval-after-load 'gnus
289 (when (version< emacs-version
"27")
290 (with-eval-after-load 'nnmail
292 'nnmail-split-abbrev-alist
293 '(list .
"list-id\\|list-post\\|x-mailing-list\\|x-beenthere\\|x-loop")
296 ;; (require 'gnus-registry)
297 ;; (setq gnus-registry-max-entries 2500)
298 ;; (setq gnus-registry-ignored-groups
299 ;; (append gnus-registry-ignored-groups
300 ;; '(("^nnimap:gnu\\.l" t)
301 ;; ("webmasters$" t))))
302 ;; (gnus-registry-initialize)
304 (with-eval-after-load 'recentf
305 (add-to-list 'recentf-exclude gnus-home-directory
))
308 (add-hook 'gnus-group-mode-hook
#'gnus-topic-mode
)
309 (add-hook 'gnus-group-mode-hook
#'gnus-agent-mode
))
310 ;; global key bindings
311 (global-set-key (kbd "s-m") #'gnus-plugged
)
312 (global-set-key (kbd "s-M") #'gnus-unplugged
)
313 (global-set-key (kbd "C-c a m") #'gnus-plugged
)
314 (global-set-key (kbd "C-c a M") #'gnus-unplugged
)
316 (with-eval-after-load 'gnus-art
318 gnus-buttonized-mime-types
'("multipart/\\(signed\\|encrypted\\)")
319 gnus-sorted-header-list
'("^From:"
339 "^X-detected-operating-system:"
346 gnus-visible-headers
(mapconcat 'identity
347 gnus-sorted-header-list
349 ;; local-lapsed article dates
350 ;; from https://www.emacswiki.org/emacs/GnusFormatting#toc11
351 gnus-article-date-headers
'(user-defined)
352 gnus-article-time-format
354 (let* ((date (format-time-string "%a, %d %b %Y %T %z" time
))
355 (local (article-make-date-line date
'local
))
356 (combined-lapsed (article-make-date-line date
359 (string-match " (.+" combined-lapsed
)
360 (match-string 0 combined-lapsed
))))
361 (concat local lapsed
))))
362 ;; local key bindings
363 (define-key gnus-article-mode-map
(kbd "M-L") #'org-store-link
))
365 (with-eval-after-load 'gnus-sum
366 (csetq gnus-thread-sort-functions
'(gnus-thread-sort-by-number
367 gnus-thread-sort-by-subject
368 gnus-thread-sort-by-date
))
369 ;; local key bindings
370 (define-key gnus-summary-mode-map
(kbd "M-L") #'org-store-link
)
371 (defvar b
/gnus-summary-prefix-map
)
372 (define-prefix-command 'b
/gnus-summary-prefix-map
)
373 (define-key gnus-summary-mode-map
(kbd "v")
374 'b
/gnus-summary-prefix-map
)
375 (define-key b
/gnus-summary-prefix-map
(kbd "r")
376 #'gnus-summary-reply
)
377 (define-key b
/gnus-summary-prefix-map
(kbd "w")
378 #'gnus-summary-wide-reply
)
379 (define-key b
/gnus-summary-prefix-map
(kbd "v")
380 #'gnus-summary-show-raw-article
))
382 (add-hook 'gnus-summary-mode-hook
#'b
/no-mouse-autoselect-window
)
385 (with-eval-after-load 'gnus-msg
386 (defvar b
/shemshak-signature
"Amin Bandali
387 https://shemshak.org/~bandali")
388 (defvar b
/uwaterloo-signature
"Amin Bandali, MMath
390 (defvar b
/csc-signature
"Amin Bandali (https://bndl.org)
391 Systems Committee <syscom@csclub.uwaterloo.ca>
392 Computer Science Club of the University of Waterloo")
393 (defvar b
/sfl-signature
"Amin Bandali
394 Free Software Consultant
398 gnus-message-replysign t
401 (address "bandali@gnu.org"))
402 ("nnimap\\+gnu:l\\..*"
405 (organization "GNU"))
406 ((header "subject" "ThankCRM")
407 (to "webmasters-comment@gnu.org")
409 (eval (setq b
/message-cite-say-hi nil
)))
410 ("nnimap\\+shemshak:.*"
411 (address "amin@shemshak.org")
413 (signature b
/shemshak-signature
)
414 (gcc "nnimap+shemshak:Sent")
415 (eval (setq b
/message-cite-say-hi t
)))
416 ("nnimap\\+uwaterloo:.*"
417 (address "bandali@uwaterloo.ca")
419 (signature b
/uwaterloo-signature
))
420 ("nnimap\\+uwaterloo:INBOX"
421 (gcc "\"nnimap+uwaterloo:Sent Items\""))
423 (address "bandali@csclub.uwaterloo.ca")
424 (signature b
/csc-signature
)
425 (gcc "nnimap+csc:Sent"))
427 (address "amin.bandali@savoirfairelinux.com")
428 (signature b
/sfl-signature
)
429 (gcc "nnimap+sfl:Sent")
430 (eval (setq-local b
/sfl-p t
))))))
432 (with-eval-after-load 'gnus
433 (add-hook 'gnus-message-setup-hook
435 (unless (or (mml-secure-is-encrypted-p)
437 (mml-secure-message-sign)))))
439 (with-eval-after-load 'gnus-topic
440 (csetq gnus-topic-line-format
"%i[ %A: %(%{%n%}%) ]%v\n"))
442 (with-eval-after-load 'gnus-agent
443 (csetq gnus-agent-synchronize-flags
'ask
))
445 (with-eval-after-load 'gnus-group
446 (csetq gnus-permanently-visible-groups
"\\(:INBOX$\\|:gnu$\\)"))
448 ;; problematic with ebdb's popup, *EBDB-Gnus*
449 ;; (with-eval-after-load 'gnus-win
450 ;; (csetq gnus-use-full-window nil))
452 (with-eval-after-load 'gnus-dired
453 (add-hook 'dired-mode-hook
'gnus-dired-mode
))
455 ;; (with-eval-after-load 'gnus-utils
456 ;; (csetq gnus-completing-read-function 'gnus-ido-completing-read))
458 (with-eval-after-load 'mm-decode
459 (csetq mm-discouraged-alternatives
'("text/html" "text/richtext")
460 mm-decrypt-option
'known
461 mm-verify-option
'known
))
463 (with-eval-after-load 'mm-uu
464 (when (version< "27" emacs-version
)
465 (set-face-attribute 'mm-uu-extract nil
:extend t
))
466 (when (version< emacs-version
"27")
467 (csetq mm-uu-diff-groups-regexp
".")))
469 (with-eval-after-load 'mml-sec
470 (csetq mml-secure-openpgp-encrypt-to-self t
471 mml-secure-openpgp-sign-with-sender t
))
473 ;; (require 'gnus-article-treat-patch)
474 ;; ;; note: be sure to customize faces with `:foreground "white"' when
475 ;; ;; using a theme with a white/light background :)
476 ;; (setq ft/gnus-article-patch-conditions
477 ;; '("^@@ -[0-9]+,[0-9]+ \\+[0-9]+,[0-9]+ @@"))
479 (provide 'bandali-gnus
)
480 ;;; bandali-gnus.el ends here