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
49 `(,@(if (string= (system-name) "darya")
53 (nnimap-address "127.0.0.1")
54 (nnimap-server-port 143)
55 (nnimap-authenticator plain
)
56 (nnimap-user "bandali@canonical.local")))
60 (nnimap-address "127.0.0.1")
61 (nnimap-server-port 143)
62 (nnimap-authenticator plain
)
63 (nnimap-user "bandali@kelar.local"))
67 (nnimap-address "127.0.0.1")
68 (nnimap-server-port 143)
69 (nnimap-authenticator plain
)
70 (nnimap-user "bandali@shemshak.local"))
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
)
82 ;; (: gnus-registry-split-fancy-with-parent)
83 ;; (: gnus-group-split-fancy "INBOX" t "INBOX")
85 ("X-Spam_action" "reject" "Junk")
86 ;; keep debbugs emails in INBOX
87 (list ".*<\\(.*\\)\\.debbugs\\.gnu\\.org>.*" "INBOX")
88 ;; list moderation emails
89 (from ".+-\\(owner\\|bounces\\)@\\(non\\)?gnu\\.org" "listmod")
91 (list ".*<\\(.*\\)\\.\\(non\\)?gnu\\.org>.*" "l.\\1")
93 (list ".*<\\(.*\\)\\.fsf\\.org>.*" "l.\\1")
95 (list ".*<\\(.*\\)\\.gnus\\.org>.*" "l.\\1")
97 (list ".*<\\(.*\\)\\.libreplanet\\.org>.*" "l.\\1")
98 ;; iana (e.g. tz-announce)
99 (list ".*<\\(.*\\)\\.iana\\.org>.*" "l.\\1")
101 (list ".*<\\(.*\\)\\.mailop\\.org>.*" "l.\\1")
103 (list ".*<\\(.*\\)\\.spammers\\.dontlike\\.us>.*" "l.sdlu")
105 (from ".*@\\(.+\\)?bitfolk\\.com>.*" "bitfolk")
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")
112 (from "webmasters\\(-comment\\)?@gnu\\.org" "webmasters")
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 ;; ----------------------------------
123 ;; otherwise, leave mail in INBOX
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
)
136 ;; (: gnus-registry-split-fancy-with-parent)
138 ("subject" "SE\\s-?212" "course.se212-f19")
139 (from "SE\\s-?212" "course.se212-f19")
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
)
153 ;; cron reports and other messages from root
154 (from "root@\\(.*\\.\\)?csclub\\.uwaterloo\\.ca" "INBOX")
156 ("X-Spam-Flag" "YES" "Junk")
161 ;; (nnimap-stream tls)
162 ;; (nnimap-address "mail.savoirfairelinux.com")
163 ;; (nnimap-user "amin.bandali"))
165 gnus-message-archive-group
"nnimap+gnu:INBOX"
168 (to-address .
"deepspec@lists.cs.princeton.edu")
169 (to-list .
"deepspec@lists.cs.princeton.edu")
170 (list-identifier .
"\\[deepspec\\]"))
171 ("l\\.fencepost-users"
172 (to-address .
"fencepost-users@gnu.org")
173 (to-list .
"fencepost-users@gnu.org")
174 (list-identifier .
"\\[Fencepost-users\\]"))
176 (to-address .
"haskell-cafe@haskell.org")
177 (to-list .
"haskell-cafe@haskell.org")
178 (list-identifier .
"\\[Haskell-cafe\\]"))
181 ;; nnimap-record-commands t
182 ;; gnus-large-newsgroup 50
183 ;; gnus-process-mark-toggle t
184 gnus-home-directory
(b/var
"gnus/")
185 gnus-directory
(concat gnus-home-directory
"news/")
186 message-directory
(concat gnus-home-directory
"mail/")
187 nndraft-directory
(concat gnus-home-directory
"drafts/")
188 gnus-save-newsrc-file nil
189 gnus-read-newsrc-file nil
190 gnus-search-use-parsed-queries t
191 gnus-interactive-exit nil
192 gnus-gcc-mark-as-read t
)
194 (with-eval-after-load 'gnus
195 (when (version< emacs-version
"27")
196 (with-eval-after-load 'nnmail
198 'nnmail-split-abbrev-alist
199 '(list .
"list-id\\|list-post\\|x-mailing-list\\|x-beenthere\\|x-loop")
202 ;; (require 'gnus-registry)
203 ;; (setq gnus-registry-max-entries 2500)
204 ;; (setq gnus-registry-ignored-groups
205 ;; (append gnus-registry-ignored-groups
206 ;; '(("^nnimap:gnu\\.l" t)
207 ;; ("webmasters$" t))))
208 ;; (gnus-registry-initialize)
210 (with-eval-after-load 'recentf
211 (add-to-list 'recentf-exclude gnus-home-directory
))
214 (add-hook 'gnus-group-mode-hook
#'gnus-topic-mode
)
215 (add-hook 'gnus-group-mode-hook
#'gnus-agent-mode
))
216 ;; global key bindings
217 (global-set-key (kbd "C-c g") #'gnus-plugged
)
218 (global-set-key (kbd "C-c G") #'gnus-unplugged
)
220 (with-eval-after-load 'gnus-art
222 gnus-buttonized-mime-types
'("multipart/\\(signed\\|encrypted\\)")
223 gnus-sorted-header-list
'("^From:"
243 "^X-detected-operating-system:"
250 gnus-visible-headers
(mapconcat #'identity
251 gnus-sorted-header-list
253 ;; local-lapsed article dates
254 ;; from https://www.emacswiki.org/emacs/GnusFormatting#toc11
255 gnus-article-date-headers
'(user-defined)
256 gnus-article-time-format
258 (let* ((date (format-time-string "%a, %d %b %Y %T %z" time
))
259 (local (article-make-date-line date
'local
))
260 (combined-lapsed (article-make-date-line date
263 (string-match " (.+" combined-lapsed
)
264 (match-string 0 combined-lapsed
))))
265 (concat local lapsed
))))
266 ;; local key bindings
267 (declare-function org-store-link
"ol" (arg &optional interactive?
))
268 (define-key gnus-article-mode-map
(kbd "M-L") #'org-store-link
))
270 (with-eval-after-load 'gnus-sum
271 (setq gnus-thread-sort-functions
'(gnus-thread-sort-by-number
272 gnus-thread-sort-by-subject
273 gnus-thread-sort-by-date
))
274 ;; local key bindings
275 (define-key gnus-summary-mode-map
(kbd "M-L") #'org-store-link
)
276 ;; (define-key gnus-summary-mode-map (kbd "r")
277 ;; #'gnus-summary-reply-with-original)
278 ;; (define-key gnus-summary-mode-map (kbd "R")
279 ;; #'gnus-summary-wide-reply-with-original)
280 (defvar b
/gnus-summary-prefix-map
)
281 (define-prefix-command 'b
/gnus-summary-prefix-map
)
282 (define-key gnus-summary-mode-map
(kbd "v")
283 'b
/gnus-summary-prefix-map
)
284 (define-key b
/gnus-summary-prefix-map
(kbd "r")
285 #'gnus-summary-reply
)
286 (define-key b
/gnus-summary-prefix-map
(kbd "w")
287 #'gnus-summary-wide-reply
)
288 (define-key b
/gnus-summary-prefix-map
(kbd "v")
289 #'gnus-summary-show-raw-article
))
291 (add-hook 'gnus-summary-mode-hook
#'b
/no-mouse-autoselect-window
)
294 (with-eval-after-load 'gnus-msg
295 (let ((bandali "Amin Bandali (https://kelar.org/~bandali)"))
296 (defvar b
/canonical-signature
300 "Software Engineer (Desktop), Canonical")
302 (defvar b
/csc-signature
306 "Systems Committee <syscom@csclub.uwaterloo.ca>"
307 "Computer Science Club of the University of Waterloo")
309 (defvar b
/sfl-signature
313 "Volunteer, Savoir-faire Linux"
317 gnus-message-replysign t
320 (address "bandali@gnu.org")
321 ("X-Message-SMTP-Method" "smtp fencepost.gnu.org 587"))
322 ((header "subject" "ThankCRM")
323 (to "webmasters-comment@gnu.org")
326 (address "bandali@kelar.org")
327 ("X-Message-SMTP-Method" "smtp mail.kelar.org 587")
328 (gcc "nnimap+kelar:Sent"))
329 ("nnimap\\+shemshak:.*"
330 (address "amin@shemshak.org")
331 ("X-Message-SMTP-Method" "smtp mail.shemshak.org 587")
332 (gcc "nnimap+shemshak:Sent"))
333 ("nnimap\\+canonical:.*"
334 (address "amin.bandali@canonical.com")
335 ("X-Message-SMTP-Method" "smtp smtp.canonical.com 587")
336 (signature b
/canonical-signature
)
337 (gcc "nnimap+canonical:Sent"))
339 (address "bandali@csclub.uwaterloo.ca")
340 ("X-Message-SMTP-Method" "smtp mail.csclub.uwaterloo.ca 587")
341 (signature b
/csc-signature
)
342 (gcc "nnimap+csc:Sent"))
344 (address "amin.bandali@savoirfairelinux.com")
345 ("X-Message-SMTP-Method" "smtp mail.savoirfairelinux.com 587")
346 (signature b
/sfl-signature
)
347 (eval (setq-local b
/sfl-p t
))
348 (gcc "nnimap+sfl:Sent")))))
350 ;; (with-eval-after-load 'gnus
351 ;; (add-hook 'gnus-message-setup-hook
353 ;; (unless (or (mml-secure-is-encrypted-p)
355 ;; (mml-secure-message-sign)))))
357 (with-eval-after-load 'gnus-topic
359 gnus-topic-line-format
"%i[ %A: %(%{%n%}%) ]%v\n"
361 `(("Gnus" visible nil nil
)
362 (("misc" visible nil nil
))
363 ,@(if (string= (system-name) "darya")
364 '((("canonical" visible nil nil
)))
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
))
371 (("sfl" visible nil nil
)))))))
373 (with-eval-after-load 'gnus-agent
374 (setq gnus-agent-synchronize-flags
'ask
))
376 (with-eval-after-load 'gnus-group
377 (setq gnus-permanently-visible-groups
"\\(:INBOX$\\|:gnu$\\)"))
379 (with-eval-after-load 'gnus-win
380 (setq gnus-use-full-window nil
))
382 (with-eval-after-load 'gnus-dired
383 (add-hook 'dired-mode-hook
'gnus-dired-mode
))
385 (with-eval-after-load 'mm-decode
387 ;; mm-attachment-override-types `("text/x-diff" "text/x-patch"
388 ;; ,@mm-attachment-override-types)
389 mm-discouraged-alternatives
'("text/html" "text/richtext")
390 mm-decrypt-option
'known
391 mm-verify-option
'known
))
393 (with-eval-after-load 'mm-uu
394 (when (version< "27" emacs-version
)
395 (set-face-attribute 'mm-uu-extract nil
:extend t
))
396 (when (version< emacs-version
"27")
397 (setq mm-uu-diff-groups-regexp
".")))
399 (with-eval-after-load 'mml-sec
400 (setq mml-secure-openpgp-encrypt-to-self t
401 mml-secure-openpgp-sign-with-sender t
))
403 (provide 'bandali-gnus
)
404 ;;; bandali-gnus.el ends here