1 ;;; bandali-gnus.el --- bandali's Gnus setup -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2018-2022 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
50 ((string= (system-name) "langa")
54 (nnimap-address "127.0.0.1")
55 (nnimap-server-port 143)
56 (nnimap-authenticator plain
)
57 (nnimap-user "bandali@kelar.local"))
61 (nnimap-address "127.0.0.1")
62 (nnimap-server-port 143)
63 (nnimap-authenticator plain
)
64 (nnimap-user "bandali@shemshak.local"))
68 (nnimap-address "127.0.0.1")
69 (nnimap-server-port 143)
70 (nnimap-authenticator plain
)
71 (nnimap-user "bandali@gnu.local")
72 (nnimap-inbox "INBOX")
73 (nnimap-split-methods 'nnimap-split-fancy
)
76 ;; (: gnus-registry-split-fancy-with-parent)
77 ;; (: gnus-group-split-fancy "INBOX" t "INBOX")
79 ("X-Spam_action" "reject" "Junk")
80 ;; keep debbugs emails in INBOX
81 (list ".*<\\(.*\\)\\.debbugs\\.gnu\\.org>.*" "INBOX")
82 ;; list moderation emails
83 (from ".+-\\(owner\\|bounces\\)@\\(non\\)?gnu\\.org" "listmod")
85 (list ".*<\\(.*\\)\\.\\(non\\)?gnu\\.org>.*" "l.\\1")
87 (list ".*<\\(.*\\)\\.fsf\\.org>.*" "l.\\1")
89 (list ".*<\\(.*\\)\\.gnus\\.org>.*" "l.\\1")
91 (list ".*<\\(.*\\)\\.libreplanet\\.org>.*" "l.\\1")
92 ;; iana (e.g. tz-announce)
93 (list ".*<\\(.*\\)\\.iana\\.org>.*" "l.\\1")
95 (list ".*<\\(.*\\)\\.mailop\\.org>.*" "l.\\1")
97 (list ".*<\\(.*\\)\\.spammers\\.dontlike\\.us>.*" "l.sdlu")
99 (from ".*@\\(.+\\)?bitfolk\\.com>.*" "bitfolk")
101 (list ".*<\\(.*\\)\\.haskell\\.org>.*" "l.\\1")
102 ;; *.lists.sr.ht, omitting one dot if present
103 ;; add more \\.?\\([^.]*\\) if needed
104 (list ".*<~\\(.*\\)/\\([^.]*\\)\\.?\\([^.]*\\)\\.lists\\.sr\\.ht>.*" "l.~\\1.\\2\\3")
106 (from "webmasters\\(-comment\\)?@gnu\\.org" "webmasters")
108 ("subject" "nagios-fsf:.*" "nagios-fsf")
109 (list ".*atreus.freelists.org" "l.atreus")
110 (list ".*deepspec.lists.cs.princeton.edu" "l.deepspec")
111 ;; (list ".*haskell-art.we.lurk.org" "l.haskell.art") ;d
112 ;; (list ".*notmuch.notmuchmail.org" "l.notmuch") ;u
113 (list ".*dev.lists.parabola.nu" "l.parabola-dev")
114 ;; ----------------------------------
115 ;; legend: (u)nsubscribed | (d)ead
116 ;; ----------------------------------
117 ;; otherwise, leave mail in INBOX
121 (nnimap-stream plain
)
122 (nnimap-address "127.0.0.1")
123 (nnimap-server-port 143)
124 (nnimap-authenticator plain
)
125 (nnimap-user "abandali@uwaterloo.local")
126 (nnimap-inbox "INBOX")
127 (nnimap-split-methods 'nnimap-split-fancy
)
130 ;; (: gnus-registry-split-fancy-with-parent)
132 ("subject" "SE\\s-?212" "course.se212-f19")
133 (from "SE\\s-?212" "course.se212-f19")
138 (nnimap-stream plain
)
139 (nnimap-address "127.0.0.1")
140 (nnimap-server-port 143)
141 (nnimap-authenticator plain
)
142 (nnimap-user "abandali@csclub.uwaterloo.local")
143 (nnimap-inbox "INBOX")
144 (nnimap-split-methods 'nnimap-split-fancy
)
147 ;; cron reports and other messages from root
148 (from "root@\\(.*\\.\\)?csclub\\.uwaterloo\\.ca" "INBOX")
150 ("X-Spam-Flag" "YES" "Junk")
153 ((string= (system-name) "jirud")
157 (nnimap-address "mail.savoirfairelinux.com")
158 (nnimap-user "amin.bandali"))))))
159 gnus-message-archive-group
"nnimap+gnu:INBOX"
162 (to-address .
"deepspec@lists.cs.princeton.edu")
163 (to-list .
"deepspec@lists.cs.princeton.edu")
164 (list-identifier .
"\\[deepspec\\]"))
165 ("l\\.fencepost-users"
166 (to-address .
"fencepost-users@gnu.org")
167 (to-list .
"fencepost-users@gnu.org")
168 (list-identifier .
"\\[Fencepost-users\\]"))
170 (to-address .
"haskell-cafe@haskell.org")
171 (to-list .
"haskell-cafe@haskell.org")
172 (list-identifier .
"\\[Haskell-cafe\\]"))
177 ("nnimap\\+uwaterloo:.*"
179 ;; nnimap-record-commands t
180 ;; gnus-large-newsgroup 50
181 ;; gnus-process-mark-toggle t
182 gnus-home-directory
(b/var
"gnus/")
183 gnus-directory
(concat gnus-home-directory
"news/")
184 message-directory
(concat gnus-home-directory
"mail/")
185 nndraft-directory
(concat gnus-home-directory
"drafts/")
186 gnus-save-newsrc-file nil
187 gnus-read-newsrc-file nil
188 gnus-search-use-parsed-queries t
189 gnus-interactive-exit nil
190 gnus-gcc-mark-as-read t
)
192 (with-eval-after-load 'gnus
193 (when (version< emacs-version
"27")
194 (with-eval-after-load 'nnmail
196 'nnmail-split-abbrev-alist
197 '(list .
"list-id\\|list-post\\|x-mailing-list\\|x-beenthere\\|x-loop")
200 ;; (require 'gnus-registry)
201 ;; (setq gnus-registry-max-entries 2500)
202 ;; (setq gnus-registry-ignored-groups
203 ;; (append gnus-registry-ignored-groups
204 ;; '(("^nnimap:gnu\\.l" t)
205 ;; ("webmasters$" t))))
206 ;; (gnus-registry-initialize)
208 (with-eval-after-load 'recentf
209 (add-to-list 'recentf-exclude gnus-home-directory
))
212 (add-hook 'gnus-group-mode-hook
#'gnus-topic-mode
)
213 (add-hook 'gnus-group-mode-hook
#'gnus-agent-mode
))
214 ;; global key bindings
215 (global-set-key (kbd "C-c g") #'gnus-plugged
)
216 (global-set-key (kbd "C-c G") #'gnus-unplugged
)
218 (with-eval-after-load 'gnus-art
220 gnus-buttonized-mime-types
'("multipart/\\(signed\\|encrypted\\)")
221 gnus-sorted-header-list
'("^From:"
241 "^X-detected-operating-system:"
248 gnus-visible-headers
(mapconcat 'identity
249 gnus-sorted-header-list
251 ;; local-lapsed article dates
252 ;; from https://www.emacswiki.org/emacs/GnusFormatting#toc11
253 gnus-article-date-headers
'(user-defined)
254 gnus-article-time-format
256 (let* ((date (format-time-string "%a, %d %b %Y %T %z" time
))
257 (local (article-make-date-line date
'local
))
258 (combined-lapsed (article-make-date-line date
261 (string-match " (.+" combined-lapsed
)
262 (match-string 0 combined-lapsed
))))
263 (concat local lapsed
))))
264 ;; local key bindings
265 (declare-function org-store-link
"ol" (arg &optional interactive?
))
266 (define-key gnus-article-mode-map
(kbd "M-L") #'org-store-link
))
268 (with-eval-after-load 'gnus-sum
269 (setq gnus-thread-sort-functions
'(gnus-thread-sort-by-number
270 gnus-thread-sort-by-subject
271 gnus-thread-sort-by-date
))
272 ;; local key bindings
273 (define-key gnus-summary-mode-map
(kbd "M-L") #'org-store-link
)
274 ;; (define-key gnus-summary-mode-map (kbd "r")
275 ;; #'gnus-summary-reply-with-original)
276 ;; (define-key gnus-summary-mode-map (kbd "R")
277 ;; #'gnus-summary-wide-reply-with-original)
278 (defvar b
/gnus-summary-prefix-map
)
279 (define-prefix-command 'b
/gnus-summary-prefix-map
)
280 (define-key gnus-summary-mode-map
(kbd "v")
281 'b
/gnus-summary-prefix-map
)
282 (define-key b
/gnus-summary-prefix-map
(kbd "r")
283 #'gnus-summary-reply
)
284 (define-key b
/gnus-summary-prefix-map
(kbd "w")
285 #'gnus-summary-wide-reply
)
286 (define-key b
/gnus-summary-prefix-map
(kbd "v")
287 #'gnus-summary-show-raw-article
))
289 (add-hook 'gnus-summary-mode-hook
#'b
/no-mouse-autoselect-window
)
292 (with-eval-after-load 'gnus-msg
293 (defvar b
/shemshak-signature
"Amin Bandali
294 https://shemshak.org/~bandali")
295 (defvar b
/uwaterloo-signature
"Amin Bandali, MMath
296 https://shemshak.org/~bandali")
297 (defvar b
/csc-signature
"Amin Bandali (https://shemshak.org/~bandali)
298 Systems Committee <syscom@csclub.uwaterloo.ca>
299 Computer Science Club of the University of Waterloo")
300 (defvar b
/sfl-signature
"Amin Bandali
301 Free Software Consultant
305 gnus-message-replysign t
308 (address "bandali@gnu.org")
309 ("X-Message-SMTP-Method" "smtp fencepost.gnu.org 587"))
310 ;; ("nnimap\\+gnu:l\\..*"
312 ((header "subject" "ThankCRM")
313 (to "webmasters-comment@gnu.org")
315 (eval (setq b
/message-cite-say-hi nil
)))
317 (address "bandali@kelar.org")
318 ("X-Message-SMTP-Method" "smtp mail.kelar.org 587")
320 (gcc "nnimap+kelar:Sent")
321 (eval (setq b
/message-cite-say-hi t
)))
322 ("nnimap\\+shemshak:.*"
323 (address "amin@shemshak.org")
324 ("X-Message-SMTP-Method" "smtp mail.shemshak.org 587")
326 (signature b
/shemshak-signature
)
327 (gcc "nnimap+shemshak:Sent")
328 (eval (setq b
/message-cite-say-hi t
)))
329 ("nnimap\\+uwaterloo:.*"
330 (address "bandali@uwaterloo.ca")
331 ("X-Message-SMTP-Method" "smtp connect.uwaterloo.ca 587")
333 (signature b
/uwaterloo-signature
))
334 ("nnimap\\+uwaterloo:INBOX"
335 (gcc "\"nnimap+uwaterloo:Sent Items\""))
337 (address "bandali@csclub.uwaterloo.ca")
338 ("X-Message-SMTP-Method" "smtp mail.csclub.uwaterloo.ca 587")
339 (signature b
/csc-signature
)
340 (gcc "nnimap+csc:Sent"))
342 (address "amin.bandali@savoirfairelinux.com")
343 (signature b
/sfl-signature
)
344 ("X-Message-SMTP-Method" "smtp mail.savoirfairelinux.com 587")
345 (gcc "nnimap+sfl:Sent")
346 (eval (setq-local b
/sfl-p t
))))))
348 ;; (with-eval-after-load 'gnus
349 ;; (add-hook 'gnus-message-setup-hook
351 ;; (unless (or (mml-secure-is-encrypted-p)
353 ;; (mml-secure-message-sign)))))
355 (with-eval-after-load 'gnus-topic
357 gnus-topic-line-format
"%i[ %A: %(%{%n%}%) ]%v\n"
359 `(("Gnus" visible nil nil
)
360 (("misc" visible nil nil
))
362 ((string= (system-name) "jirud")
363 '((("sfl" visible nil nil
))))
364 ((string= (system-name) "langa")
365 '((("csc" visible nil nil
))
366 (("uwaterloo" visible nil nil
))
367 (("kelar" visible nil nil
))
368 (("shemshak" visible nil nil
))
369 (("gnu" visible nil nil
))
370 (("old-gnu" visible nil nil
))))))))
372 (with-eval-after-load 'gnus-agent
373 (setq gnus-agent-synchronize-flags
'ask
))
375 (with-eval-after-load 'gnus-group
376 (setq gnus-permanently-visible-groups
"\\(:INBOX$\\|:gnu$\\)"))
378 (with-eval-after-load 'gnus-win
379 (setq gnus-use-full-window nil
))
381 (with-eval-after-load 'gnus-dired
382 (add-hook 'dired-mode-hook
'gnus-dired-mode
))
384 (with-eval-after-load 'mm-decode
386 ;; mm-attachment-override-types `("text/x-diff" "text/x-patch"
387 ;; ,@mm-attachment-override-types)
388 mm-discouraged-alternatives
'("text/html" "text/richtext")
389 mm-decrypt-option
'known
390 mm-verify-option
'known
))
392 (with-eval-after-load 'mm-uu
393 (when (version< "27" emacs-version
)
394 (set-face-attribute 'mm-uu-extract nil
:extend t
))
395 (when (version< emacs-version
"27")
396 (setq mm-uu-diff-groups-regexp
".")))
398 (with-eval-after-load 'mml-sec
399 (setq mml-secure-openpgp-encrypt-to-self t
400 mml-secure-openpgp-sign-with-sender t
))
402 (provide 'bandali-gnus
)
403 ;;; bandali-gnus.el ends here