summaryrefslogtreecommitdiffstats
path: root/.emacs.d/lisp/bandali-gnus.el
diff options
context:
space:
mode:
authorAmin Bandali <bandali@kelar.org>2025-01-30 22:55:32 -0500
committerAmin Bandali <bandali@kelar.org>2025-01-30 22:55:32 -0500
commitc7b47e03e0ac16d6db84d59d8cff58291b22fbaa (patch)
tree64997f5e10d25897966d496d905aa6ff835f5f94 /.emacs.d/lisp/bandali-gnus.el
parent563fb78037f21c6503c6489758e8f0d86173bb7e (diff)
downloadconfigs-c7b47e03e0ac16d6db84d59d8cff58291b22fbaa.tar.gz
configs-c7b47e03e0ac16d6db84d59d8cff58291b22fbaa.tar.xz
configs-c7b47e03e0ac16d6db84d59d8cff58291b22fbaa.zip
Break out .emacs.d/init.el into .emacs.d/lisp/bandali-*.el again
Having used the monolithic init.el approach, I found it somewhat unwieldy, especially as the file grows larger and larger.
Diffstat (limited to '.emacs.d/lisp/bandali-gnus.el')
-rw-r--r--.emacs.d/lisp/bandali-gnus.el392
1 files changed, 392 insertions, 0 deletions
diff --git a/.emacs.d/lisp/bandali-gnus.el b/.emacs.d/lisp/bandali-gnus.el
new file mode 100644
index 0000000..76a689b
--- /dev/null
+++ b/.emacs.d/lisp/bandali-gnus.el
@@ -0,0 +1,392 @@
+;;; bandali-gnus.el --- bandali's Gnus setup -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2025 Amin Bandali <bandali@gnu.org>
+
+;; Author: Amin Bandali <bandali@gnu.org>
+;; Keywords: mail, news
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; My trusty Gnus setup.
+
+;;; Code:
+
+(defvar b/maildir
+ (expand-file-name (convert-standard-filename "~/mail/")))
+(with-eval-after-load 'recentf
+ (add-to-list 'recentf-exclude b/maildir))
+
+(setopt
+ mail-user-agent 'gnus-user-agent
+ read-mail-command #'gnus)
+
+(eval-when-compile
+ (progn
+ (defvar nndraft-directory)
+ (defvar gnus-read-newsrc-file)
+ (defvar gnus-save-newsrc-file)
+ (defvar gnus-gcc-mark-as-read)
+ (defvar nnmail-split-abbrev-alist)))
+
+(declare-function article-make-date-line "gnus-art" (date type))
+
+(with-eval-after-load 'gnus
+ (with-eval-after-load 'nnimap
+ (setq nnimap-record-commands init-file-debug))
+
+ (setopt
+ gnus-select-method '(nnnil "")
+ gnus-secondary-select-methods
+ `((nnimap
+ "kelar"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "bandali@kelar.local")
+ ;; (nnmail-expiry-wait immediate)
+ (nnmail-expiry-target nnmail-fancy-expiry-target)
+ (nnmail-fancy-expiry-targets
+ (("from" ".*" "nnimap+kelar:Archive.%Y"))))
+ (nnimap
+ "shemshak"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "bandali@shemshak.local"))
+ (nnimap
+ "debian"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "bandali@debian.local")
+ ;; (nnmail-expiry-wait immediate)
+ (nnmail-expiry-target nnmail-fancy-expiry-target)
+ (nnmail-fancy-expiry-targets
+ (("from" ".*" "nnimap+debian:Archive.%Y"))))
+ (nnimap
+ "gnu"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "bandali@gnu.local")
+ (nnimap-inbox "INBOX")
+ (nnimap-split-methods 'nnimap-split-fancy)
+ (nnimap-split-fancy
+ (|
+ ;; (: gnus-registry-split-fancy-with-parent)
+ ;; (: gnus-group-split-fancy "INBOX" t "INBOX")
+ ;; spam
+ ("X-Spam_action" "reject" "Junk")
+ ;; keep debbugs emails in INBOX
+ (list ".*<\\(.*\\)\\.debbugs\\.gnu\\.org>.*" "INBOX")
+ ;; list moderation emails
+ (from ".+-\\(owner\\|bounces\\)@\\(non\\)?gnu\\.org" "listmod")
+ ;; gnu
+ (list ".*<\\(.*\\)\\.\\(non\\)?gnu\\.org>.*" "l.\\1")
+ ("Envelope-To" "emacsconf-donations@gnu.org" "l.emacsconf-donations")
+ ;; board-eval
+ (|
+ (list ".*<.*\\.board-eval\\.fsf\\.org>.*" "l.board-eval")
+ (from ".*@board-eval\\.fsf\\.org" "l.board-eval"))
+ ;; fsf
+ (list ".*<\\(.*\\)\\.fsf\\.org>.*" "l.\\1")
+ ;; cfarm
+ (from "cfarm-.*@lists\\.tetaneutral\\.net" "l.cfarm")
+ ;; debian
+ (list ".*<\\(.*\\)\\.\\(lists\\|other\\)\\.debian\\.org>.*" "l.\\1")
+ (list ".*<\\(.*\\)\\.alioth-lists\\.debian\\.net>.*" "l.\\1")
+ ;; gnus
+ (list ".*<\\(.*\\)\\.gnus\\.org>.*" "l.\\1")
+ ;; libreplanet
+ (list ".*<\\(.*\\)\\.libreplanet\\.org>.*" "l.\\1")
+ ;; iana (e.g. tz-announce)
+ (list ".*<\\(.*\\)\\.iana\\.org>.*" "l.\\1")
+ ;; mailop
+ (list ".*<\\(.*\\)\\.mailop\\.org>.*" "l.\\1")
+ ;; sdlu
+ (list ".*<\\(.*\\)\\.spammers\\.dontlike\\.us>.*" "l.sdlu")
+ ;; bitfolk
+ (from ".*@\\(.+\\)?bitfolk\\.com>.*" "bitfolk")
+ ;; haskell
+ (list ".*<\\(.*\\)\\.haskell\\.org>.*" "l.\\1")
+ ;; webmasters
+ (from "webmasters\\(-comment\\)?@gnu\\.org" "webmasters")
+ ;; other
+ (list ".*atreus.freelists.org" "l.atreus")
+ (list ".*deepspec.lists.cs.princeton.edu" "l.deepspec")
+ (list ".*haskell-art.we.lurk.org" "l.haskell-art")
+ (list ".*dev.lists.parabola.nu" "l.parabola-dev")
+ ;; otherwise, leave mail in INBOX
+ "INBOX")))
+ (nnimap
+ "csc"
+ (nnimap-stream plain)
+ (nnimap-address "127.0.0.1")
+ (nnimap-server-port 143)
+ (nnimap-authenticator plain)
+ (nnimap-user "abandali@csclub.uwaterloo.local")
+ (nnimap-inbox "INBOX")
+ (nnimap-split-methods 'nnimap-split-fancy)
+ (nnimap-split-fancy
+ (|
+ ;; cron reports and other messages from root
+ (from "root@\\(.*\\.\\)?csclub\\.uwaterloo\\.ca" "INBOX")
+ ;; spam
+ ("X-Spam-Flag" "YES" "Junk")
+ ;; catch-all
+ "INBOX"))))
+ gnus-message-archive-group "nnimap+kelar:INBOX"
+ gnus-parameters
+ '(("l\\.fencepost-users"
+ (to-address . "fencepost-users@gnu.org")
+ (to-list . "fencepost-users@gnu.org")
+ (list-identifier . "\\[Fencepost-users\\]"))
+ ("l\\.haskell-cafe"
+ (to-address . "haskell-cafe@haskell.org")
+ (to-list . "haskell-cafe@haskell.org")
+ (list-identifier . "\\[Haskell-cafe\\]")))
+ ;; gnus-large-newsgroup 50
+ gnus-process-mark-toggle t
+ gnus-home-directory (b/emacs.d "gnus/")
+ gnus-directory
+ (expand-file-name
+ (convert-standard-filename "news/") gnus-home-directory)
+ gnus-interactive-exit nil
+ gnus-user-agent '(emacs gnus type))
+
+ (with-eval-after-load 'message
+ (setopt
+ message-directory
+ (expand-file-name
+ (convert-standard-filename "mail/") gnus-home-directory)))
+
+ (with-eval-after-load 'nndraft
+ (setopt
+ nndraft-directory
+ (expand-file-name
+ (convert-standard-filename "drafts/") gnus-home-directory)))
+
+ (when (version< emacs-version "27")
+ (with-eval-after-load 'nnmail
+ (add-to-list
+ 'nnmail-split-abbrev-alist
+ '(list . "list-id\\|list-post\\|x-mailing-list\\|x-beenthere\\|x-loop")
+ 'append)))
+
+ (with-eval-after-load 'gnus-agent
+ (setopt gnus-agent-synchronize-flags 'ask))
+
+ (with-eval-after-load 'gnus-art ; article
+ (setopt
+ gnus-buttonized-mime-types
+ '("multipart/\\(signed\\|encrypted\\)")
+ gnus-sorted-header-list
+ '("^From:"
+ "^X-RT-Originator"
+ "^Newsgroups:"
+ "^Subject:"
+ "^Date:"
+ "^Envelope-To:"
+ "^Followup-To:"
+ "^Reply-To:"
+ "^Organization:"
+ "^Summary:"
+ "^Abstract:"
+ "^Keywords:"
+ "^To:"
+ "^[BGF]?Cc:"
+ "^Posted-To:"
+ "^Mail-Copies-To:"
+ "^Mail-Followup-To:"
+ "^Apparently-To:"
+ "^Resent-From:"
+ "^User-Agent:"
+ "^X-detected-operating-system:"
+ "^X-Spam_action:"
+ "^X-Spam_bar:"
+ "^Message-ID:"
+ ;; "^References:"
+ "^List-Id:"
+ "^Gnus-Warning:")
+ gnus-visible-headers
+ (mapconcat #'identity gnus-sorted-header-list "\\|")))
+
+ (with-eval-after-load 'gnus-dired
+ (with-eval-after-load 'dired
+ (add-hook 'dired-mode-hook #'gnus-dired-mode)))
+
+ (with-eval-after-load 'gnus-group
+ (setopt
+ gnus-permanently-visible-groups "\\(:INBOX$\\|:gnu$\\)")
+ (add-hook 'gnus-group-mode-hook #'gnus-topic-mode)
+ (add-hook 'gnus-group-mode-hook #'gnus-agent-mode))
+
+ (with-eval-after-load 'gnus-msg
+ (let ((bandali "Amin Bandali%s - https://kelar.org/~bandali"))
+ (defvar b/csc-signature
+ (mapconcat
+ #'identity
+ `(,(format bandali ", MMath")
+ "Systems Committee <syscom@csclub.uwaterloo.ca>"
+ "Computer Science Club of the University of Waterloo")
+ "\n")))
+ (setopt
+ gnus-gcc-mark-as-read t
+ gnus-message-replysign t
+ gnus-posting-styles
+ '(("nnimap\\+kelar:.*"
+ (address "bandali@kelar.org")
+ ("X-Message-SMTP-Method" "smtp mail.kelar.org 587")
+ (gcc "nnimap+kelar:INBOX"))
+ ("nnimap\\+shemshak:.*"
+ (address "amin@shemshak.org")
+ ("X-Message-SMTP-Method" "smtp mail.shemshak.org 587")
+ (gcc "nnimap+shemshak:Sent"))
+ ("nnimap\\+debian:.*"
+ (address "bandali@debian.org")
+ ("X-Message-SMTP-Method" "smtp mail-submit.debian.org 587")
+ (gcc "nnimap+debian:INBOX"))
+ ("nnimap\\+gnu:.*"
+ (address "bandali@gnu.org")
+ ("X-Message-SMTP-Method" "smtp fencepost.gnu.org 587")
+ (gcc "nnimap+gnu:INBOX"))
+ ("nnimap\\+.*:l\\.ubuntu-.*"
+ (address "bandali@ubuntu.com")
+ ("X-Message-SMTP-Method" "smtp mail.kelar.org 587"))
+ ((header "list-id" ".*\\.lists.ubuntu.com")
+ (address "bandali@ubuntu.com")
+ ("X-Message-SMTP-Method" "smtp mail.kelar.org 587"))
+ ("nnimap\\+csc:.*"
+ (address "bandali@csclub.uwaterloo.ca")
+ ("X-Message-SMTP-Method" "smtp mail.csclub.uwaterloo.ca 587")
+ (signature b/csc-signature)
+ (gcc "nnimap+csc:Sent")))))
+
+ ;; (require 'gnus-registry)
+ ;; (with-eval-after-load 'gnus-registry
+ ;; (setopt
+ ;; gnus-registry-max-entries 2500
+ ;; gnus-registry-ignored-groups
+ ;; (append gnus-registry-ignored-groups
+ ;; '(("^nnimap:gnu\\.l" t) ("webmasters$" t))))
+ ;; (gnus-registry-initialize))
+
+ (with-eval-after-load 'gnus-search
+ (setopt
+ gnus-search-use-parsed-queries t))
+
+ (with-eval-after-load 'gnus-start
+ (setopt
+ gnus-save-newsrc-file nil
+ gnus-read-newsrc-file nil)
+ (add-hook 'gnus-after-getting-new-news-hook #'gnus-notifications))
+
+ (with-eval-after-load 'gnus-sum ; summary
+ (setopt
+ gnus-thread-sort-functions
+ '(gnus-thread-sort-by-number
+ gnus-thread-sort-by-subject
+ gnus-thread-sort-by-date))
+ (with-eval-after-load 'message
+ (setopt
+ gnus-ignored-from-addresses message-dont-reply-to-names))
+
+ (defun b/gnus-junk-article (&optional n)
+ (interactive "P" gnus-summary-mode)
+ (gnus-summary-move-article
+ n
+ (gnus-group-prefixed-name
+ "Junk"
+ (gnus-find-method-for-group gnus-newsgroup-name))))
+
+ (defvar b/gnus-summary-prefix-map)
+ (define-prefix-command 'b/gnus-summary-prefix-map)
+ (b/keymap-set
+ gnus-summary-mode-map "v" 'b/gnus-summary-prefix-map)
+ (let ((m b/gnus-summary-prefix-map))
+ (b/keymap-set m "r r" #'gnus-summary-very-wide-reply)
+ (b/keymap-set m "r q" #'gnus-summary-very-wide-reply-with-original)
+ (b/keymap-set m "R r" #'gnus-summary-reply)
+ (b/keymap-set m "R q" #'gnus-summary-reply-with-original)
+ (b/keymap-set m "r a w" #'gnus-summary-show-raw-article)
+ (b/keymap-set m "s" #'b/gnus-junk-article)))
+
+ (with-eval-after-load 'gnus-topic
+ ;; (setopt gnus-topic-line-format "%i[ %A: %(%{%n%}%) ]%v\n")
+ (setopt gnus-topic-line-format "%i[ %(%{%n%}%) (%A) ]%v\n")
+ (setq gnus-topic-topology
+ `(("Gnus" visible nil nil)
+ (("misc" visible nil nil))
+ (("csc" visible nil nil))
+ (("kelar" visible nil nil))
+ (("shemshak" visible nil nil))
+ (("debian" visible nil nil))
+ (("gnu" visible nil nil))
+ ;; (("old-gnu" visible nil nil))
+ )))
+
+ (with-eval-after-load 'gnus-win
+ (setopt gnus-use-full-window nil))
+
+ (with-eval-after-load 'mm-archive
+ (add-to-list
+ 'mm-archive-decoders
+ '("application/gzip" nil "gunzip" "-S" ".zip" "-kd" "%f" "-r")))
+
+ (with-eval-after-load 'mm-decode
+ (setopt
+ ;; mm-attachment-override-types `("text/x-diff" "text/x-patch"
+ ;; ,@mm-attachment-override-types)
+ mm-discouraged-alternatives '("text/html" "text/richtext")
+ mm-decrypt-option 'known
+ mm-verify-option 'known)
+ (add-to-list
+ 'mm-inline-media-tests
+ `("application/gzip" mm-archive-dissect-and-inline identity))
+ (add-to-list 'mm-inlined-types "application/gzip" 'append))
+
+ (with-eval-after-load 'mm-uu
+ (when (version< "27" emacs-version)
+ (set-face-attribute 'mm-uu-extract nil :extend t))
+ (when (version< emacs-version "27")
+ (setopt mm-uu-diff-groups-regexp ".")))
+
+ (with-eval-after-load 'mml
+ (setopt
+ mml-attach-file-at-the-end t
+ mml-content-disposition-alist
+ '((text
+ (markdown . "attachment")
+ (rtf . "attachment")
+ (t . "inline"))
+ (t . "attachment"))))
+
+ (with-eval-after-load 'mml-sec
+ (setopt
+ mml-secure-openpgp-encrypt-to-self t
+ mml-secure-openpgp-sign-with-sender t))
+
+ (with-eval-after-load 'recentf
+ (add-to-list 'recentf-exclude gnus-home-directory)))
+(b/keymap-global-set "C-c g" #'gnus-plugged)
+(b/keymap-global-set "C-c G" #'gnus-unplugged)
+
+(provide 'bandali-gnus)
+;;; bandali-gnus.el ends here