From ccdad04ec478ddabbd39949170fba071bbfbf99a Mon Sep 17 00:00:00 2001 From: jao Date: Fri, 7 May 2021 00:15:08 +0100 Subject: gnus to the attic --- attic/gnus.org | 697 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 697 insertions(+) create mode 100644 attic/gnus.org (limited to 'attic') diff --git a/attic/gnus.org b/attic/gnus.org new file mode 100644 index 0000000..5631aec --- /dev/null +++ b/attic/gnus.org @@ -0,0 +1,697 @@ +#+title: Gnus +#+PROPERTY: header-args :tangle yes :comments yes :results silent +#+auto_tangle: t + +* Feature switching vars + #+begin_src emacs-lisp + (defvar jao-gnus-use-local-imap t) + (defvar jao-gnus-use-leafnode t) + (defvar jao-gnus-use-gandi-imap nil) + (defvar jao-gnus-use-pm-imap nil) + (defvar jao-gnus-use-gmane nil) + (defvar jao-gnus-use-nnml nil) + (defvar jao-gnus-use-maildirs nil) + #+end_src +* Startup and kill + #+begin_src emacs-lisp + ;;;;; close gnus when closing emacs, but ask when exiting + (setq gnus-interactive-exit t) + + (defun jao-gnus-started-hook () + (add-hook 'before-kill-emacs-hook 'gnus-group-exit)) + + (add-hook 'gnus-started-hook 'jao-gnus-started-hook) + + (defun jao-gnus-after-exiting-hook () + (remove-hook 'before-kill-emacs-hook 'gnus-group-exit)) + + (add-hook 'gnus-after-exiting-gnus-hook 'jao-gnus-after-exiting-hook) + + ;; define a wrapper around the save-buffers-kill-emacs + ;; to run the new hook before: + (defadvice save-buffers-kill-emacs + (before my-save-buffers-kill-emacs activate) + "Install hook when emacs exits before emacs asks to save this and that." + (run-hooks 'before-kill-emacs-hook)) + #+end_src +* Directories + #+begin_src emacs-lisp + (setq gnus-home-directory "~/.emacs.d/gnus" + gnus-directory gnus-home-directory) + + (defun jao-gnus-dir (dir) + (expand-file-name dir gnus-home-directory)) + + (setq smtpmail-queue-dir (jao-gnus-dir "Mail/queued-mail/")) + + (with-eval-after-load "gnus" + (setq mail-source-directory (jao-gnus-dir "Mail/") + message-auto-save-directory (jao-gnus-dir "Mail/drafts/") + message-directory (jao-gnus-dir "Mail/"))) + + (setq gnus-default-directory (expand-file-name "~") + gnus-startup-file (jao-gnus-dir "newsrc") + gnus-agent-directory (jao-gnus-dir "News/agent") + gnus-home-score-file (jao-gnus-dir "scores") + gnus-article-save-directory (jao-gnus-dir "saved/") + nntp-authinfo-file (jao-gnus-dir "authinfo") + nnmail-message-id-cache-file (jao-gnus-dir "nnmail-cache") + nndraft-directory (jao-gnus-dir "drafts") + nnrss-directory (jao-gnus-dir "rss")) + #+end_src +* Looks +*** Verbosity + #+begin_src emacs-lisp + (setq gnus-verbose 5) + #+end_src +*** Geometry + #+BEGIN_SRC emacs-lisp + ;;; geometry: + (defvar jao-gnus-use-three-panes t) + + (setq gnus-use-trees nil + gnus-generate-tree-function 'gnus-generate-horizontal-tree + gnus-tree-minimize-window nil) + + (when jao-gnus-use-three-panes + (let ((side-bar '(vertical 1.0 + ("inbox.org" 0.4) + ("*Org Agenda*" 1.0) + ("*Calendar*" 8))) + (wide-len 190)) + (gnus-add-configuration + `(article + (horizontal 1.0 + (vertical 63 (group 1.0)) + (vertical 127 + (summary 0.25 point) + (article 1.0)) + ,side-bar))) + + (gnus-add-configuration + `(group (horizontal 1.0 (group ,wide-len point) ,side-bar))) + + (gnus-add-configuration + `(message (horizontal 1.0 (message ,wide-len point) ,side-bar))) + + (gnus-add-configuration + `(reply-yank (horizontal 1.0 (message ,wide-len point) ,side-bar))) + + (gnus-add-configuration + `(summary + (horizontal 1.0 + (vertical 63 (group 1.0)) + (vertical 127 (summary 1.0 point)) + ,side-bar))) + + (gnus-add-configuration + `(reply + (horizontal 1.0 + (message 90 point) + (article 100) + ,side-bar))))) + + (defun jao-gnus--summary-done () + (save-window-excursion (org-agenda-list))) + + (add-hook 'gnus-summary-prepared-hook #'jao-gnus--summary-done) + #+END_SRC +*** No blue icon + #+begin_src emacs-lisp + ;; (defalias 'gnus-mode-line-buffer-identification 'identity) + (advice-add 'gnus-mode-line-buffer-identification :override #'identity) + (setq gnus-mode-line-image-cache nil) + #+end_src +* Search + [[info:gnus#Searching][info:gnus#Searching]] + #+begin_src emacs-lisp + (setq gnus-search-use-parsed-queries t + jao-gnus-search-prefix (expand-file-name "~/var/mail/")) + + (defun jao-gnus-search-engine (engine) + `(gnus-search-engine ,engine (remove-prefix ,jao-gnus-search-prefix))) + #+end_src +* News server + #+begin_src emacs-lisp + (setq gnus-select-method + (cond (jao-gnus-use-leafnode + `(nntp "localhost" + ,(jao-gnus-search-engine 'gnus-search-notmuch))) + (jao-gnus-use-gmane '(nntp "news.gmane.io")) + (t '(nnnil "")))) + (setq gnus-secondary-select-methods '()) + + (setq gnus-ignored-newsgroups + "^to\\.\\|^[0-9. ]+\\( \\|$\\)\\|^[\"]]\"[#'()]") + + ;; nntp options + (setq nnheader-read-timeout 0.02) + #+end_src +* IMAP servers + #+begin_src emacs-lisp + ;; archiving messages + (setq gnus-message-archive-group nil) + + ;; imap + (when jao-gnus-use-local-imap + (add-to-list 'gnus-secondary-select-methods + `(nnimap "" + (nnimap-expunge immediately) + (nnimap-address "localhost")))) + + (when jao-gnus-use-pm-imap + (add-to-list 'gnus-secondary-select-methods + '(nnimap "pm" + (nnimap-address "127.0.0.1") + (nnimap-stream network) + (nnimap-server-port 1143)))) + + (when jao-gnus-use-gandi-imap + (add-to-list 'gnus-secondary-select-methods + '(nnimap "gandi" (nnimap-address "mail.gandi.net")))) + #+end_src +* Mailbox and maildir servers + #+begin_src emacs-lisp + (setq mail-sources '((file :path "/var/mail/jao"))) + + (setq nnml-get-new-mail t + nnmail-treat-duplicates 'delete + nnmail-scan-directory-mail-source-once t + nnmail-cache-accepted-message-ids t + nnmail-message-id-cache-length 50000 + nnmail-cache-ignore-groups ".*\\(trove\\.\\|feeds\\.\\|spamish\\).*" + nnmail-split-fancy-with-parent-ignore-groups nil + nnmail-crosspost t) + + (setq nnmail-resplit-incoming t + nnmail-mail-splitting-decodes t + nnmail-split-methods 'nnmail-split-fancy) + + (when jao-gnus-use-nnml + (add-to-list 'gnus-secondary-select-methods `(nnml ""))) + + (when jao-gnus-use-maildirs + (add-to-list 'gnus-secondary-select-methods + '(nnmaildir "bml" (directory "/home/jao/var/maildir/bigml/"))) + (add-to-list 'gnus-secondary-select-methods + '(nnmaildir "jao" (directory "/home/jao/var/maildir/jao/"))) + (add-to-list 'gnus-secondary-select-methods + '(nnmaildir "gmail" (directory "/home/jao/var/maildir/gmail/")))) + + #+end_src +* RSS servers + #+begin_src emacs-lisp + (setq nnrss-use-local nil + nnrss-directory (jao-gnus-dir "rss")) + (setq nnrss-wash-html-in-text-plain-parts t) + (setq nnrss-ignore-article-fields '(description + comments + dc:date + slash:comments + slash:description)) + #+end_src +* Agents, demons, synchronicity + #+BEGIN_SRC emacs-lisp + ;; gnus agent(s) and demons + ;; (setq gnus-agent nil) + (setq mail-user-agent 'gnus-user-agent) + (require 'gnus-demon) + (when (featurep 'gnus-desktop-notify) + (gnus-desktop-notify-mode 1) + (gnus-demon-add-scanmail)) + + ;; synchronicity + (setq gnus-asynchronous t) + ;;; prefetch as many articles as possible + (setq gnus-use-article-prefetch nil) + + (setq gnus-save-killed-list nil) + (setq gnus-check-new-newsgroups nil) + + (setq gnus-gcc-mark-as-read t) + #+END_SRC +* Delayed messages + #+BEGIN_SRC emacs-lisp + ;;; delayed messages (C-cC-j in message buffer) + (require 'gnus-util) + (gnus-delay-initialize) + (setq gnus-delay-default-delay "3h") + ;;; so that the Date is set when the message is sent, not when it's + ;;; delayed + (eval-after-load "message" + '(setq message-draft-headers (remove 'Date message-draft-headers))) + #+END_SRC +* Add-ons +*** icalendar + #+begin_src emacs-lisp + (use-package gnus-icalendar + :demand t + :init (setq gnus-icalendar-org-capture-file + (expand-file-name "inbox.org" org-directory) + gnus-icalendar-org-capture-headline '("Appointments")) + :config (gnus-icalendar-org-setup)) + #+end_src +*** bbdb + #+begin_src emacs-lisp + (with-eval-after-load "bbdb" + (bbdb-initialize 'gnus 'message 'pgp 'mail) + (bbdb-mua-auto-update-init 'gnus) + (eval-after-load "gnus-sum" + '(progn + (define-key gnus-summary-mode-map ":" 'bbdb-mua-annotate-sender) + (define-key gnus-summary-mode-map ";" 'bbdb-mua-annotate-recipients)))) + #+end_src +*** randomsig + #+begin_src emacs-lisp + (with-eval-after-load "randomsig" + (with-eval-after-load "gnus-sum" + (define-key gnus-summary-save-map "-" + 'gnus/randomsig-summary-read-sig))) + #+end_src +*** notmuch -> gnus + #+begin_src emacs-lisp + (defun jao-notmuch-goto-message-in-gnus () + "Open a summary buffer containing the current notmuch article." + (interactive) + (let ((group (jao-maildir-file-to-group (notmuch-show-get-filename))) + (message-id (replace-regexp-in-string "^id:" + "" + (notmuch-show-get-message-id)))) + (if (and group message-id) + (org-gnus-follow-link group message-id) + (message "Couldn't get relevant infos for switching to Gnus.")))) + (eval-after-load "notmuch-show" + '(define-key notmuch-show-mode-map (kbd "C-c C-c") + #'jao-notmuch-goto-message-in-gnus)) + #+end_src +*** gnus-recent + #+begin_src emacs-lisp :load no + (use-package gnus-recent + :ensure t + :after gnus + :bind (:map gnus-summary-mode-map + (("l" . #'gnus-recent-goto-previous)) + :map gnus-group-mode-map + (("C-c l" . #'gnus-recent-goto-previous) + ("C-c r" . #'gnus-recent)))) + #+end_src +* Groups buffer + #+BEGIN_SRC emacs-lisp + ;; (setq gnus-group-line-format " %m%S%p%P:%~(pad-right 35)c %3y %B\n") + (setq gnus-group-line-format " %m%S%p%3y%P%* %~(pad-right 45)G %B\n") + (setq gnus-topic-line-format "%i[ %(%{%n%}%) -- %A ]%v\n") + (setq gnus-group-uncollapsed-levels 2) + (setq gnus-auto-select-subject 'unread) + (setq-default gnus-large-newsgroup nil) + + (add-hook 'gnus-select-group-hook 'gnus-group-set-timestamp) + (add-hook 'gnus-group-mode-hook 'gnus-topic-mode) + + (defvar jao-gnus--expire-every 50) + (defvar jao-gnus--get-count (1+ jao-gnus--expire-every)) + + (defun jao-gnus-get-new-news (&optional arg) + (interactive "p") + (when (and jao-gnus--expire-every + (> jao-gnus--get-count jao-gnus--expire-every)) + (when jao-gnus-use-pm-imap (gnus-group-catchup "nnimap:pm/spam" t)) + (gnus-group-expire-all-groups) + (setq jao-gnus--get-count 0)) + (setq jao-gnus--get-count (1+ jao-gnus--get-count)) + (gnus-group-get-new-news (max (if (= 1 jao-gnus--get-count) 4 3) + (or arg 0)))) + ;; To limit expiration to the `g' count, `jao-gnus--get-count': + ;; (remove-hook 'gnus-summary-prepare-exit-hook 'gnus-summary-expire-articles) + ;; (define-key gnus-group-mode-map "g" 'jao-gnus-get-new-news) + + (defun jao-gnus-restart-servers () + (interactive) + (message "Restarting all servers...") + (gnus-group-enter-server-mode) + (gnus-server-close-all-servers) + (gnus-server-open-all-servers) + (gnus-server-exit) + (message "Restarting all servers... done")) + + + (define-key gnus-group-mode-map "Z" #'jao-gnus-restart-servers) + (define-key gnus-group-mode-map "Gg"#'consult-notmuch) + #+END_SRC +* Group parameters + #+begin_src emacs-lisp + (setq jao-gnus-expirable + (format (concat "^nnimap:\\(" + "\\(\\(bigml\\|bml\\)/%s\\)\\|" + "\\(\\(jao\\|pm\\)/%s\\)\\|" + "\\(feeds/.+\\)\\|trash\\|spam" + "\\)") + (regexp-opt '("support" "reports" "deploys" + "lists" "drivel" "bugs")) + (regexp-opt '("books" "think" "local" "drivel" + "lists" "emacs" "lobsters")))) + + (setq gnus-parameters + `(("^nnimap:jao/.*" + (jao-gnus--trash-group "nnimap:jao/trash") + (jao-gnus--spam-group "nnimap:jao/spam") + (jao-gnus--archiving-group "nnimap:trove/jao")) + ("^nnimap:\\(jao\\|pm\\|bigml\\)/\\(trash\\|spam\\)" + (gcc-self . nil) + (auto-expire . t) + (total-expire . t) + (expiry-wait . 1) + (jao-gnus--trash-group nil) + (expiry-target . delete)) + ("^nnimap:jao/inbox" + (gcc-self . t)) + ("^nnimap:bigml/.*" + (posting-style (address "jao@bigml.com")) + (jao-gnus--spam-group "nnimap:bigml/spam")) + ("^nnimap:bigml/inbox" + (gcc-self . t) + (auto-expire . t) + (total-expire . t) + (expiry-wait . 365) + (jao-gnus--trash-group "nnimap:trash") + (expiry-target . delete)) + ("^nnimap:bigml/support" + (posting-style (address "support@bigml.com"))) + (,jao-gnus-expirable + (jao-gnus--trash-group nil) + (gcc-self . nil) + (auto-expire . t) + (total-expire . t) + (expiry-wait . 3) + (expiry-target . delete)) + ("^nnimap:feeds/podcasts" + (auto-expire . nil) + (total-expire . nil)) + ("^nnimap:feeds/\\(papers\\|programming\\|math\\|physics\\)$" + (expiry-wait . 30) + (jao-gnus--archiving-group "nnimap:trove/tech") + (posting-style (address "jao@gnu.org"))) + ("^nnimap:jao/hacking$" + (jao-gnus--archiving-group "nnimap:trove/tech")) + ("^nnimap:jao/gnu$" + (expiry-target . "nnimap:trove/gnu") + (jao-gnus--archiving-group "nnimap:trove/gnu")) + ("^nnimap:jao/bills$" + (expiry-target . "nnimap:trove/bills") + (jao-gnus--archiving-group "nnimap:trove/bills")) + ("\\(gmane\\|gwene\\)\\..*" + (jao-gnus--archiving-group "nnimap:trove/tech") + (posting-style (address "jao@gnu.org"))))) + #+end_src +* Summary buffer +*** Configuration, summary line + #+BEGIN_SRC emacs-lisp + (setq gnus-summary-ignore-duplicates t + gnus-suppress-duplicates t + gnus-summary-ignored-from-addresses jao-mails-regexp) + + (setq gnus-show-threads t + gnus-thread-hide-subtree t + gnus-summary-make-false-root 'adopt + gnus-summary-gather-subject-limit 120 + gnus-sort-gathered-threads-function 'gnus-thread-sort-by-date + gnus-thread-sort-functions '(gnus-thread-sort-by-date)) + + (setq gnus-face-1 'jao-gnus-face-tree) + + (setq gnus-not-empty-thread-mark ?·) ; ↓) + (setq jao-gnus--summary-line-fmt + (concat "%%U %%*%%R %%uj " + "[ %%~(max-right 20)~(pad-right 20)n " + " %%I%%~(pad-left 2)t ] %%s" + "%%-%s=" + "%%~(max-right 8)~(pad-left 8)&user-date;" + "\n")) + + (defun jao-gnus--set-summary-line () + (let* ((d (if jao-gnus-use-three-panes 75 12)) + (w (- (window-width) d))) + (setq gnus-summary-line-format (format jao-gnus--summary-line-fmt w)))) + + (add-hook 'gnus-group-prepare-hook 'jao-gnus--set-summary-line) + + (add-to-list 'nnmail-extra-headers 'Cc) + (add-to-list 'nnmail-extra-headers 'BCc) + (add-to-list 'gnus-extra-headers 'Cc) + (add-to-list 'gnus-extra-headers 'BCc) + + (defun gnus-user-format-function-j (headers) + (let ((to (gnus-extra-header 'To headers))) + (if (string-match jao-mails-regexp to) + (if (string-match "," to) "¬" "»") ;; "~" "=") + (if (or (string-match jao-mails-regexp + (gnus-extra-header 'Cc headers)) + (string-match jao-mails-regexp + (gnus-extra-header 'BCc headers))) + "¬" ;; "~" + " ")))) + + (setq gnus-summary-user-date-format-alist + '(((gnus-seconds-today) . "%H:%M") + ((+ 86400 (gnus-seconds-today)) . "'%H:%M") + ;; (604800 . "%a %H:%M") ;;that's one week + ((gnus-seconds-month) . "%a %d") + ((gnus-seconds-year) . "%b %d") + (t . "%b '%y"))) + + ;; old name, for emacs 23 + (setq gnus-user-date-format-alist gnus-summary-user-date-format-alist) + #+END_SRC +*** Moving messages around + #+BEGIN_SRC emacs-lisp + (defvar-local jao-gnus--spam-group nil) + (defvar-local jao-gnus--archiving-group nil) + (defvar-local jao-gnus--archive-as-copy-p nil) + + (defvar jao-gnus--last-move nil) + (defun jao-gnus-move-hook (a headers c to d) + (setq jao-gnus--last-move (cons to (mail-header-id headers)))) + (defun jao-gnus-goto-last-moved () + (interactive) + (when jao-gnus--last-move + (when (eq major-mode 'gnus-summary-mode) (gnus-summary-exit)) + (gnus-group-goto-group (car jao-gnus--last-move)) + (gnus-group-select-group) + (gnus-summary-goto-article (cdr jao-gnus--last-move) nil t))) + (add-hook 'gnus-summary-article-move-hook 'jao-gnus-move-hook) + + (defun jao-gnus-archive (follow) + (interactive "P") + (if jao-gnus--archiving-group + (progn + (if (or jao-gnus--archive-as-copy-p + (not (gnus-check-backend-function + 'request-move-article gnus-newsgroup-name))) + (gnus-summary-copy-article nil jao-gnus--archiving-group) + (gnus-summary-move-article nil jao-gnus--archiving-group)) + (when follow (jao-gnus-goto-last-moved))) + (gnus-summary-mark-as-read) + (gnus-summary-delete-article))) + + (defun jao-gnus-archive-tickingly () + (interactive) + (gnus-summary-tick-article) + (jao-gnus-archive) + (when jao-gnus--archive-as-copy-p + (gnus-summary-mark-as-read))) + + (defun jao-gnus-show-tickled () + (interactive) + (gnus-summary-limit-to-marks "!")) + + (make-variable-buffer-local + (defvar jao-gnus--trash-group nil)) + + (defun jao-gnus-trash () + (interactive) + (gnus-summary-mark-as-read) + (if jao-gnus--trash-group + (gnus-summary-move-article nil jao-gnus--trash-group) + (gnus-summary-delete-article))) + + (defun jao-gnus-move-to-spam () + (interactive) + (gnus-summary-mark-as-read) + (gnus-summary-move-article nil jao-gnus--spam-group)) + + (define-key gnus-summary-mode-map "Ba" 'jao-gnus-archive) + (define-key gnus-summary-mode-map "BA" 'jao-gnus-archive-tickingly) + (define-key gnus-summary-mode-map "Bl" 'jao-gnus-goto-last-moved) + + (define-key gnus-summary-mode-map (kbd "B DEL") 'jao-gnus-trash) + (define-key gnus-summary-mode-map (kbd "B ") 'jao-gnus-trash) + (define-key gnus-summary-mode-map "Bs" 'jao-gnus-move-to-spam) + (define-key gnus-summary-mode-map "/!" 'jao-gnus-show-tickled) + (define-key gnus-summary-mode-map [f7] 'gnus-summary-force-verify-and-decrypt) + #+END_SRC +*** Writing emails + #+BEGIN_SRC emacs-lisp + (setq gnus-default-article-saver 'gnus-summary-save-article-mail) + (defvar jao-gnus-file-save-directory (expand-file-name "~/tmp")) + (defun jao-gnus-file-save (newsgroup headers &optional last-file) + (expand-file-name (format "%s.eml" (mail-header-subject headers)) + jao-gnus-file-save-directory)) + (setq gnus-mail-save-name 'jao-gnus-file-save) + #+END_SRC +*** arXiv capture + #+begin_src emacs-lisp + (use-package org-capture + :config + (add-to-list 'org-capture-templates + '("X" "arXiv" entry (file "notes/physics/arxiv.org") + "* %:subject\n %i" :immediate-finish t) + t) + (org-capture-upgrade-templates org-capture-templates)) + + (defun jao-gnus-arXiv-capture () + (interactive) + (gnus-summary-select-article-buffer) + (gnus-article-goto-part 0) + (forward-paragraph) + (setq-local transient-mark-mode 'lambda) + (set-mark (point)) + (goto-char (point-max)) + (org-capture nil "X")) + #+end_src +* Article buffer +*** Config, headers + #+BEGIN_SRC emacs-lisp + (setq mail-source-delete-incoming t) + (setq gnus-treat-display-smileys nil) + (setq gnus-treat-fill-long-lines nil) + (setq gnus-treat-fill-article nil) + (setq gnus-article-auto-eval-lisp-snippets nil) + (setq gnus-posting-styles '((".*" (name "Jose A. Ortega Ruiz")))) + (setq gnus-single-article-buffer nil) + (setq gnus-article-update-lapsed-header 60) + (setq gnus-article-update-date-headers 60) + + (eval-after-load "gnus-art" + '(setq + gnus-visible-headers + (concat + gnus-visible-headers + "\\|^X-Newsreader:\\|^X-Mailer:\\|User-Agent:\\|X-User-Agent:"))) + #+END_SRC +*** HTML email + #+BEGIN_SRC emacs-lisp + (setq gnus-button-url 'browse-url-generic + gnus-inhibit-images nil + mm-discouraged-alternatives nil ;; '("text/html" "text/richtext") + mm-inline-large-images 'resize) + + ;; no html in From: (washing articles from arxiv feeds) + (require 'shr) + (defun jao-gnus-remove-anchors () + (save-excursion + (goto-char (point-min)) + (when (re-search-forward "updates on arXiv.org: