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 plain
)
162 (nnimap-address "127.0.0.1")
163 (nnimap-server-port 143)
164 (nnimap-authenticator plain
)
165 (nnimap-user "amin.bandali@savoirfairelinux.local")))))
166 gnus-message-archive-group
"nnimap+gnu:INBOX"
169 (to-address .
"deepspec@lists.cs.princeton.edu")
170 (to-list .
"deepspec@lists.cs.princeton.edu")
171 (list-identifier .
"\\[deepspec\\]"))
172 ("l\\.fencepost-users"
173 (to-address .
"fencepost-users@gnu.org")
174 (to-list .
"fencepost-users@gnu.org")
175 (list-identifier .
"\\[Fencepost-users\\]"))
177 (to-address .
"haskell-cafe@haskell.org")
178 (to-list .
"haskell-cafe@haskell.org")
179 (list-identifier .
"\\[Haskell-cafe\\]"))
182 ;; nnimap-record-commands t
183 ;; gnus-large-newsgroup 50
184 ;; gnus-process-mark-toggle t
185 gnus-home-directory
(b/var
"gnus/")
186 gnus-directory
(concat gnus-home-directory
"news/")
187 message-directory
(concat gnus-home-directory
"mail/")
188 nndraft-directory
(concat gnus-home-directory
"drafts/")
189 gnus-save-newsrc-file nil
190 gnus-read-newsrc-file nil
191 gnus-search-use-parsed-queries t
192 gnus-interactive-exit nil
193 gnus-gcc-mark-as-read t
)
195 (with-eval-after-load 'gnus
196 (when (version< emacs-version
"27")
197 (with-eval-after-load 'nnmail
199 'nnmail-split-abbrev-alist
200 '(list .
"list-id\\|list-post\\|x-mailing-list\\|x-beenthere\\|x-loop")
203 ;; (require 'gnus-registry)
204 ;; (setq gnus-registry-max-entries 2500)
205 ;; (setq gnus-registry-ignored-groups
206 ;; (append gnus-registry-ignored-groups
207 ;; '(("^nnimap:gnu\\.l" t)
208 ;; ("webmasters$" t))))
209 ;; (gnus-registry-initialize)
211 (with-eval-after-load 'recentf
212 (add-to-list 'recentf-exclude gnus-home-directory
))
215 (add-hook 'gnus-group-mode-hook
#'gnus-topic-mode
)
216 (add-hook 'gnus-group-mode-hook
#'gnus-agent-mode
))
217 ;; global key bindings
218 (global-set-key (kbd "C-c g") #'gnus-plugged
)
219 (global-set-key (kbd "C-c G") #'gnus-unplugged
)
221 (with-eval-after-load 'gnus-art
223 gnus-buttonized-mime-types
'("multipart/\\(signed\\|encrypted\\)")
224 gnus-sorted-header-list
'("^From:"
244 "^X-detected-operating-system:"
251 gnus-visible-headers
(mapconcat #'identity
252 gnus-sorted-header-list
254 ;; local-lapsed article dates
255 ;; from https://www.emacswiki.org/emacs/GnusFormatting#toc11
256 gnus-article-date-headers
'(user-defined)
257 gnus-article-time-format
259 (let* ((date (format-time-string "%a, %d %b %Y %T %z" time
))
260 (local (article-make-date-line date
'local
))
261 (combined-lapsed (article-make-date-line date
264 (string-match " (.+" combined-lapsed
)
265 (match-string 0 combined-lapsed
))))
266 (concat local lapsed
))))
267 ;; local key bindings
268 (declare-function org-store-link
"ol" (arg &optional interactive?
))
269 (define-key gnus-article-mode-map
(kbd "M-L") #'org-store-link
))
271 (with-eval-after-load 'gnus-sum
272 (setq gnus-thread-sort-functions
'(gnus-thread-sort-by-number
273 gnus-thread-sort-by-subject
274 gnus-thread-sort-by-date
))
275 ;; local key bindings
276 (define-key gnus-summary-mode-map
(kbd "M-L") #'org-store-link
)
277 ;; (define-key gnus-summary-mode-map (kbd "r")
278 ;; #'gnus-summary-reply-with-original)
279 ;; (define-key gnus-summary-mode-map (kbd "R")
280 ;; #'gnus-summary-wide-reply-with-original)
281 (defvar b
/gnus-summary-prefix-map
)
282 (define-prefix-command 'b
/gnus-summary-prefix-map
)
283 (define-key gnus-summary-mode-map
(kbd "v")
284 'b
/gnus-summary-prefix-map
)
285 (define-key b
/gnus-summary-prefix-map
(kbd "r")
286 #'gnus-summary-reply
)
287 (define-key b
/gnus-summary-prefix-map
(kbd "w")
288 #'gnus-summary-wide-reply
)
289 (define-key b
/gnus-summary-prefix-map
(kbd "v")
290 #'gnus-summary-show-raw-article
))
292 (add-hook 'gnus-summary-mode-hook
#'b
/no-mouse-autoselect-window
)
295 (with-eval-after-load 'gnus-msg
296 (let ((bandali "Amin Bandali (https://kelar.org/~bandali)"))
297 (defvar b
/canonical-signature
301 "Software Engineer (Desktop), Canonical")
303 (defvar b
/csc-signature
307 "Systems Committee <syscom@csclub.uwaterloo.ca>"
308 "Computer Science Club of the University of Waterloo")
310 (defvar b
/sfl-signature
314 "Volunteer, Savoir-faire Linux"
318 gnus-message-replysign t
321 (address "bandali@gnu.org")
322 ("X-Message-SMTP-Method" "smtp fencepost.gnu.org 587"))
323 ((header "subject" "ThankCRM")
324 (to "webmasters-comment@gnu.org")
327 (address "bandali@kelar.org")
328 ("X-Message-SMTP-Method" "smtp mail.kelar.org 587")
329 (gcc "nnimap+kelar:Sent"))
330 ("nnimap\\+shemshak:.*"
331 (address "amin@shemshak.org")
332 ("X-Message-SMTP-Method" "smtp mail.shemshak.org 587")
333 (gcc "nnimap+shemshak:Sent"))
334 ("nnimap\\+canonical:.*"
335 (address "amin.bandali@canonical.com")
336 ("X-Message-SMTP-Method" "smtp smtp.canonical.com 587")
337 (signature b
/canonical-signature
)
338 (gcc "nnimap+canonical:Sent"))
340 (address "bandali@csclub.uwaterloo.ca")
341 ("X-Message-SMTP-Method" "smtp mail.csclub.uwaterloo.ca 587")
342 (signature b
/csc-signature
)
343 (gcc "nnimap+csc:Sent"))
345 (address "amin.bandali@savoirfairelinux.com")
346 ("X-Message-SMTP-Method" "smtp mail.savoirfairelinux.com 587")
347 (signature b
/sfl-signature
)
348 (eval (setq-local b
/sfl-p t
))
349 (gcc "nnimap+sfl:Sent")))))
351 ;; (with-eval-after-load 'gnus
352 ;; (add-hook 'gnus-message-setup-hook
354 ;; (unless (or (mml-secure-is-encrypted-p)
356 ;; (mml-secure-message-sign)))))
358 (with-eval-after-load 'gnus-topic
360 gnus-topic-line-format
"%i[ %A: %(%{%n%}%) ]%v\n"
362 `(("Gnus" visible nil nil
)
363 (("misc" visible nil nil
))
364 ,@(if (string= (system-name) "darya")
365 '((("canonical" visible nil nil
)))
366 '((("csc" visible nil nil
))
367 (("uwaterloo" visible nil nil
))
368 (("kelar" visible nil nil
))
369 (("shemshak" visible nil nil
))
370 (("gnu" visible nil nil
))
371 (("old-gnu" visible nil nil
))
372 (("sfl" visible nil nil
)))))))
374 (with-eval-after-load 'gnus-agent
375 (setq gnus-agent-synchronize-flags
'ask
))
377 (with-eval-after-load 'gnus-group
378 (setq gnus-permanently-visible-groups
"\\(:INBOX$\\|:gnu$\\)"))
380 (with-eval-after-load 'gnus-win
381 (setq gnus-use-full-window nil
))
383 (with-eval-after-load 'gnus-dired
384 (add-hook 'dired-mode-hook
'gnus-dired-mode
))
386 (with-eval-after-load 'mm-decode
388 ;; mm-attachment-override-types `("text/x-diff" "text/x-patch"
389 ;; ,@mm-attachment-override-types)
390 mm-discouraged-alternatives
'("text/html" "text/richtext")
391 mm-decrypt-option
'known
392 mm-verify-option
'known
))
394 (with-eval-after-load 'mm-uu
395 (when (version< "27" emacs-version
)
396 (set-face-attribute 'mm-uu-extract nil
:extend t
))
397 (when (version< emacs-version
"27")
398 (setq mm-uu-diff-groups-regexp
".")))
400 (with-eval-after-load 'mml-sec
401 (setq mml-secure-openpgp-encrypt-to-self t
402 mml-secure-openpgp-sign-with-sender t
))
404 (provide 'bandali-gnus
)
405 ;;; bandali-gnus.el ends here