summaryrefslogtreecommitdiffhomepage
path: root/custom/jao-custom-gnus.el
diff options
context:
space:
mode:
Diffstat (limited to 'custom/jao-custom-gnus.el')
-rw-r--r--custom/jao-custom-gnus.el513
1 files changed, 288 insertions, 225 deletions
diff --git a/custom/jao-custom-gnus.el b/custom/jao-custom-gnus.el
index 68cf0a5..b3e1cb6 100644
--- a/custom/jao-custom-gnus.el
+++ b/custom/jao-custom-gnus.el
@@ -1,6 +1,6 @@
;; gnus configuration -*- lexical-binding: t -*-
-;;; Feature switching vars
+;;; features
(defvar jao-gnus-use-local-imap nil)
(defvar jao-gnus-use-leafnode nil)
(defvar jao-gnus-use-gandi-imap nil)
@@ -9,15 +9,9 @@
(defvar jao-gnus-use-nnml nil)
(defvar jao-gnus-use-maildirs nil)
(defvar jao-notmuch-enabled nil)
+(defvar jao-gnus-nnml-group-params nil)
-;;; Startup and kill
-(setq gnus-interactive-exit t)
-
-(defun jao-quit-gnus () (gnus-group-exit) t)
-
-(add-hook 'kill-emacs-query-functions #'jao-quit-gnus)
-
-;;; Directories
+;;; directories
(defun jao-gnus-dir (dir)
(expand-file-name dir gnus-home-directory))
@@ -36,12 +30,16 @@
nndraft-directory (jao-gnus-dir "drafts")
nnrss-directory (jao-gnus-dir "rss"))
-;;; Verbosity
-(setq gnus-verbose 4)
+(setq gnus-uncacheable-groups "^nnml")
+
+;;; private config
+(require 'jao-gnus-private nil t)
-;;; Looks
+;;; looks
+;;;; verbosity
+(setq gnus-verbose 4)
;;;; geometry
-(defvar jao-gnus-use-three-panes t)
+(defvar jao-gnus-use-three-panes (not jao-notmuch-enabled))
(defvar jao-gnus-groups-width 50)
(defvar jao-gnus-wide-width 190)
@@ -49,15 +47,13 @@
gnus-generate-tree-function 'gnus-generate-horizontal-tree
gnus-tree-minimize-window nil)
-(when jao-gnus-use-three-panes
+(setq calendar-left-margin 6)
- ;; (dolist (m '(calendar-mode org-agenda-mode gnus-group-mode))
- ;; (add-to-list 'display-buffer-alist `((major-mode . ,m) (dedicated t))))
-
- (let ((side-bar '(vertical 1.0
+(defun jao-gnus-use-three-panes ()
+ (let ((side-bar `(vertical 1.0
("inbox.org" 0.4)
("*Org Agenda*" 1.0)
- ("*Calendar*" 9)))
+ ("*Calendar*" ,(jao-d-l 9 8))))
(wide-len jao-gnus-wide-width)
(groups-len jao-gnus-groups-width)
(summary-len (- jao-gnus-wide-width jao-gnus-groups-width)))
@@ -93,53 +89,64 @@
(article 100)
,side-bar)))))
+(defun jao-gnus-use-two-panes ()
+ (let ((groups-len jao-gnus-groups-width)
+ (summary-len (- jao-gnus-wide-width jao-gnus-groups-width))
+ (msg-edit '(horizontal 1.0
+ (message 1.0 point)
+ (vertical 0.5
+ ("*Org Agenda*" 0.5)
+ ("inbox.org" 1.0)))))
+ (gnus-add-configuration
+ `(article
+ (horizontal 1.0
+ (vertical ,groups-len (group 1.0))
+ (vertical 1.0
+ (summary 0.25 point)
+ (article 1.0)))))
+
+ (gnus-add-configuration
+ `(group (horizontal 1.0
+ (group 0.5 point)
+ (vertical 1.0
+ ("*Org Agenda*" 1.0)
+ ("*Calendar*" 9)))))
+
+ (gnus-add-configuration
+ `(summary
+ (horizontal 1.0
+ (vertical ,groups-len (group 1.0))
+ (vertical 1.0 (summary 1.0 point)))))
+
+ (gnus-add-configuration `(message ,msg-edit))
+
+ (gnus-add-configuration `(forward ,msg-edit))
+
+ (gnus-add-configuration `(reply-yank ,msg-edit))
+
+ (gnus-add-configuration
+ `(reply (horizontal 1.0 (message 0.5 point) (article 1.0))))))
+
+(if jao-gnus-use-three-panes
+ (jao-gnus-use-three-panes)
+ (jao-gnus-use-two-panes))
+
;;;; no blue icon
(advice-add 'gnus-mode-line-buffer-identification :override #'identity)
(setq gnus-mode-line-image-cache nil)
-;;; Search
+;;; search
(setq gnus-search-use-parsed-queries nil
- gnus-search-notmuch-raw-queries-p nil
+ gnus-search-notmuch-raw-queries-p t
gnus-permanently-visible-groups "^nnselect:.*"
gnus-search-ignored-newsgroups "nndraft.*\\|nnselect.*")
-(with-eval-after-load "gnus-search"
- (defclass gnus-search-recoll (gnus-search-indexed)
- ((separator :type string :initform ".")
- (program :initform "recoll")
- (raw-queries-p :initform t)))
-
- (cl-defmethod gnus-search-indexed-extract ((_engine gnus-search-recoll))
- (prog1 (and (looking-at "^file://\\(.+\\)$") (list (match-string 1) 100))
- (forward-line 1)))
-
- (cl-defmethod gnus-search-transform-expression ((_engine gnus-search-recoll)
- expr)
- expr)
-
- (cl-defmethod gnus-search-indexed-search-command ((engine gnus-search-recoll)
- (qstring string)
- _query
- &optional groups)
- (let* ((subdir (slot-value engine 'remove-prefix))
- (sep (slot-value engine 'separator))
- (gdirs (mapcar (lambda (g)
- (let ((g (gnus-group-short-name g)))
- (replace-regexp-in-string "\\." sep g)))
- (or groups
- (and (not (string= "" subdir)) (list subdir)))))
- (dirsq (and gdirs
- (concat "("
- (mapconcat (lambda (d) (format "dir:%s" d))
- gdirs " OR ")
- ")")))
- (q (concat "mime:message " dirsq " (" qstring ")")))
- ;; (message "query is: %s" q)
- `("-b" "-t" "-q" ,q))))
+(use-package jao-recoll
+ :if (jao-is-linux))
;; (add-to-list 'gnus-parameters '("^nnselect:.*" (nnselect-rescan . t)))
-;;; News server
+;;; news
(defvar jao-gnus-leafnode-spool "/var/spool/news/")
(setq gnus-select-method
(cond
@@ -171,7 +178,7 @@
(dolist (p jao-gnus-leafnode-group-params)
(add-to-list 'gnus-parameters p t)))
-;;; Mail
+;;; mail
;;;; nnmail
(setq nnmail-treat-duplicates 'delete
nnmail-scan-directory-mail-source-once nil
@@ -189,91 +196,42 @@
nnml-get-new-mail t
nnml-directory message-directory)
+(defvar jao-local-mail-sources
+ (append (mapcar (lambda (f)
+ `(maildir :path ,(expand-file-name f jao-maildir)))
+ '("local/" "feeds/"))
+ (jao-when-darwin '((file :path "/var/mail/jao")))))
+
+(defun jao-pm-label-mail-sources (pwd &rest labels)
+ (mapcar (lambda (b)
+ `(imap :server "127.0.0.1" :port 1143
+ :user "jaor@pm.me" :password ,pwd
+ :stream starttls :predicate "1:*"
+ :fetchflag "\\Deleted \\Seen"
+ :mailbox ,(concat "Labels/#" b)))
+ (or labels '("inbox" "drivel" "hacking" "bills" "prog" "words"))))
+
+(defun jao-pm-folder-mail-sources (pwd &rest folders)
+ (mapcar (lambda (b)
+ `(imap :server "127.0.0.1" :port 1143
+ :user "jaor@pm.me" :password ,pwd
+ :stream starttls :predicate ""
+ :fetchflag ""
+ :mailbox ,(if b (concat "Folders/" b) "INBOX")))
+ (or folders '(nil "drivel" "hacking" "bills" "prog" "words"))))
+
(setq mail-sources
(let* ((pwd (auth-source-pick-first-password :host "proton-bridge"))
- (mds (mapcar (lambda (f)
- `(maildir :path ,(expand-file-name f "~/var/mail/")))
- '("local/" "feeds/")))
- (ims (mapcar (lambda (b)
- `(imap :server "127.0.0.1" :port 1143
- :user "mail@jao.io" :password ,pwd
- :stream starttls :predicate "1:*"
- :fetchflag "\\Deleted \\Seen"
- :mailbox ,(concat "Labels/#" b)))
- '("inbox" "drivel" "hacking" "bills"
- "bigml" "prog" "words"))))
- (append mds ims)))
+ (ims (jao-pm-label-mail-sources pwd)))
+ (append jao-local-mail-sources ims)))
(when jao-gnus-use-nnml
- (add-to-list
- 'gnus-secondary-select-methods
- `(nnml "" (gnus-search-engine gnus-search-recoll
- (remove-prefix ,(jao-gnus-dir "Mail/"))))))
-
-(defvar jao-gnus-nnml-group-params
- `(("nnml:\\(local\\|trash\\|spam\\)"
- (auto-expire . t)
- (total-expire . t)
- (expiry-wait . 1)
- (expiry-target . delete))
- ("nnml:jao\\..*"
- (posting-style ("Gcc" "nnml:jao.trove")) ;; ("Bcc" "proton@jao.io")
- (jao-gnus--trash-group "nnml:trash")
- (jao-gnus--spam-group "nnml:spam")
- (jao-gnus--archiving-group "nnml:jao.trove")
- (gcc-self . t))
- ("nnml:jao\\.hacking"
- (posting-style ("Gcc" "nnml:jao.hacking")
- (address "jao@gnu.org"))) ;; ("Bcc" "hacking@jao.io")
- ("nnml:jao\\.drivel"
- (auto-expire . t)
- (total-expire . t)
- (expiry-wait . 3)
- (expiry-target . delete))
- ("nnml:bigml\\..*"
- (gcc-self . nil)
- (auto-expire . t)
- (total-expire . t)
- (expiry-wait . 3)
- (expiry-target . delete)
- (posting-style (address "jao@bigml.com"))
- (jao-gnus--trash-group "nnml:trash")
- (jao-gnus--spam-group "nnml:spam")
- (jao-gnus--archiving-group "nnml:bigml.trove"))
- ("nnml:bigml\\.inbox"
- (gcc-self . t)
- (auto-expire . t)
- (total-expire . t)
- (expiry-wait . 7)
- (expiry-target . "nnml:bigml.trove"))
- ("nnml:bigml\\.alba"
- (gcc-self . t)
- (auto-expire . nil)
- (total-expire . nil)
- (expiry-target . nil)
- (expiry-wait . nil))
- ("nnml:bigml\\.trove"
- (auto-expire . t)
- (total-expire . t)
- (expiry-target . delete)
- (expiry-wait . 365))
- ("nnml:feeds\\.\\(.*\\)"
- (posting-style ("Gcc" "nnml:feeds.trove")
- (address "jao@gnu.org"))
- (auto-expire . t)
- (total-expire . t)
- (expiry-wait . 7)
- (expiry-target . delete)
- (comment . "feeds.\\1")
- (jao-gnus--archiving-group "nnml:feeds.trove"))
- ("nnml:feeds\\.\\(news\\|emacs-\\(bugs\\|diffs|\\github\\)\\)$"
- (expiry-wait . 2))
- ("nnml:feeds\\.trove"
- (auto-expire . nil)
- (total-expire . nil))
- ("nnml:feeds\\.fun"
- (mm-html-inhibit-images nil)
- (mm-html-blocked-images nil))))
+ (let ((prefix (expand-file-name "gnus/" jao-maildir)))
+ (add-to-list
+ ;; `(nnml "" ,(jao-recoll-gnus-search-engine (jao-gnus-dir "Mail/")))
+ 'gnus-secondary-select-methods
+ `(nnml "" (gnus-search-engine gnus-search-jao-notmuch
+ (remove-prefix ,prefix))))))
(when jao-gnus-use-nnml
(dolist (p jao-gnus-nnml-group-params)
@@ -297,12 +255,14 @@
(add-to-list 'gnus-secondary-select-methods
'(nnimap "gandi" (nnimap-address "mail.gandi.net"))))
-;;; Groups
+;;; groups
(setq gnus-group-line-format
- " %m%S%p%3y%P%* %~(pad-right 30)G %B\n"
+ " %m%S%p%3y%P%* %~(pad-right 25)G %B\n"
;; " %m%S%p%P:%~(pad-right 35)c %3y %B\n"
;; " %m%S%p%3y%P%* %~(pad-right 30)C %B\n"
- gnus-topic-line-format "%i[ %(%{%n%}%) -- %A ]%v\n"
+ ;; gnus-topic-line-format "%i[ %(%{%n%}%) -- %A ]%v\n"
+ gnus-face-2 'jao-themes-f11
+ gnus-topic-line-format "%i %2{%~(pad-right 8)n ┄┄ %A%v%}\n"
gnus-group-uncollapsed-levels 2
gnus-auto-select-subject 'unread
gnus-large-newsgroup 2000)
@@ -310,7 +270,26 @@
(add-hook 'gnus-select-group-hook 'gnus-group-set-timestamp)
(add-hook 'gnus-group-mode-hook 'gnus-topic-mode)
-;;; Summary
+;;; rss
+(setq nnrss-use-local t ;; M-x nnrss-generate-download-script
+ nnrss-ignore-article-fields '(category
+ dc:creator
+ dc:date
+ enclosure
+ guid
+ link
+ media:content
+ media:thumbnail
+ media:title
+ post-id
+ pubDate
+ slash:comments))
+
+(add-to-list 'gnus-parameters `(,(format "nnrss:%s.*"
+ (regexp-opt jao-gnus-image-groups t))
+ (mm-html-inhibit-images nil)
+ (mm-html-blocked-images nil)))
+;;; summary
;;;; configuration
(setq gnus-summary-ignore-duplicates t
gnus-suppress-duplicates t
@@ -326,16 +305,15 @@
gnus-refer-thread-use-search t
gnus-summary-make-false-root 'adopt
gnus-summary-gather-subject-limit nil ;; 120
- gnus-summary-thread-gathering-function #'gnus-gather-threads-by-subject
+ gnus-summary-thread-gathering-function #'gnus-gather-threads-by-references
gnus-sort-gathered-threads-function 'gnus-thread-sort-by-date
-
- gnus-thread-sort-functions '(gnus-thread-sort-by-number))
+ gnus-thread-sort-functions '(gnus-thread-sort-by-date))
(defun jao-fix-protonmail-references (header)
(let ((references (mail-header-references header)))
(setf (mail-header-references header)
(mapconcat #'(lambda (x)
- (if (string-match "protonmail.internalid" x) "" x))
+ (if (string-match-p "protonmail.internalid" x) "" x))
(gnus-split-references references)
" "))
header))
@@ -360,12 +338,14 @@
"\n"))
(defun jao-gnus--set-summary-line (&optional w)
- (let* ((d (if jao-gnus-use-three-panes (+ jao-gnus-groups-width 11) 12))
- (w (- (or w (window-width)) d)))
+ (let* ((d (if jao-gnus-use-three-panes
+ (+ jao-gnus-groups-width 11)
+ (+ jao-gnus-groups-width 12)))
+ (w (or w (if jao-gnus-use-three-panes (window-width) (frame-width))))
+ (w (- w d)))
(setq gnus-summary-line-format (format jao-gnus--summary-line-fmt w))))
(add-hook 'gnus-select-group-hook 'jao-gnus--set-summary-line)
-;; (jao-gnus--set-summary-line 187)
(add-to-list 'nnmail-extra-headers 'Cc)
(add-to-list 'nnmail-extra-headers 'BCc)
@@ -392,7 +372,8 @@
"ElDiario.es - ElDiario.es: "
"The Guardian: "
"Aeon | a world of ideas: "
- "Planet Debian: "))
+ "Planet Debian: "
+ " via The Rust Programming Language Forum"))
"\\|The Conversation – Articles (.+): "
"\\|unofficial mirror of [^:]+: "
"\\|[gq].+ updates on arXiv.org: "))
@@ -489,22 +470,51 @@
(use-package org-capture
:config
(add-to-list 'org-capture-templates
+ '("x" "arXiv" entry (file "notes/physics/arxiv.org")
+ "* %(jao-gnus-subject)\n\n %i\n\n %(jao-gnus-org-url)"
+ :immediate-finish t)
+ t)
+ (add-to-list 'org-capture-templates
'("X" "arXiv" entry (file "notes/physics/arxiv.org")
- "* %:subject\n %i" :immediate-finish t)
+ "* %(jao-gnus-subject)\n\n%(jao-gnus-org-paragraph \"%i\")"
+ :immediate-finish t)
t)
(org-capture-upgrade-templates org-capture-templates))
+(defvar jao-gnus-org-url nil)
+(defun jao-gnus-org-url () jao-gnus-org-url)
+(defun jao-gnus-org-paragraph (x)
+ (with-temp-buffer
+ (insert " " (string-trim (or x "")) "\n ")
+ (goto-char 0)
+ (fill-paragraph)
+ (goto-char (point-max))
+ (open-rectangle 0 (point))
+ (concat (buffer-string) "\n " (or jao-gnus-org-url ""))))
+(defvar jao-gnus-subject nil)
+(defun jao-gnus-subject () jao-gnus-subject)
+
(defun jao-gnus-arXiv-capture ()
(interactive)
+ (unless (derived-mode-p '(gnus-summary-mode)) (gnus-article-show-summary))
+ (setq jao-gnus-subject (gnus-summary-article-subject))
(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"))
-
-;;; Article
+ (let ((transient-mark-mode t))
+ (set-mark (point))
+ (forward-paragraph)
+ (or (and (save-excursion
+ (when (re-search-forward "^Link" nil t)
+ (beginning-of-line)
+ (setq jao-gnus-org-url (org-eww-url-below-point))))
+ (org-capture nil "X"))
+ (and (save-excursion
+ (when (re-search-forward "^URL: " nil t)
+ (setq jao-gnus-org-url (thing-at-point-url-at-point))))
+ (org-capture nil "x"))))
+ (gnus-article-show-summary))
+
+;;; article
;;;; config, headers
(setq mail-source-delete-incoming t)
(setq gnus-gcc-mark-as-read t)
@@ -518,6 +528,7 @@
(setq gnus-single-article-buffer nil)
(setq gnus-article-update-lapsed-header 60)
(setq gnus-article-update-date-headers 60)
+(setq gnus-article-truncate-lines t)
(with-eval-after-load "gnus-art"
(setq gnus-visible-headers
@@ -561,8 +572,8 @@
(gnus-article-remove-images)))))
(jao-gnus-browse-html)))
-;;;; remove html in From:
-(require 'shr)
+;;;; format from:
+
(defvar jao-gnus--from-rx
(concat "From: \\\"?\\( *" jao-gnus--news-rx "\\)"))
@@ -582,12 +593,21 @@
(save-excursion
(goto-char (point-min))
(when (or (search-forward-regexp "^Via: h" nil t)
- (search-forward-regexp "^URL: h" nil t)
+ (search-forward-regexp "^URL:[\n ]h" nil t)
(and (search-forward-regexp "^Link$" nil t)
(not (beginning-of-line))))
- (if external
- (jao-browse-with-external-browser)
- (browse-url (jao-url-around-point))))))
+ (cond (external (jao-browse-with-external-browser))
+ ((featurep 'jao-custom-eww) (eww (jao-url-around-point)))
+ (t (browse-url (jao-url-around-point)))))))
+
+(defun jao-gnus-from-eww (keep-eww-buffer)
+ (interactive "P")
+ (unless keep-eww-buffer (jao-eww-close))
+ (jao-afio-goto-mail)
+ (gnus-article-show-summary))
+
+(with-eval-after-load 'eww
+ (define-key eww-mode-map (kbd "h") #'jao-gnus-from-eww))
(defun jao-gnus-open-enclosure ()
(interactive)
@@ -595,7 +615,7 @@
(gnus-summary-select-article-buffer)
(save-excursion
(goto-char (point-min))
- (let ((offset (or (and (search-forward-regexp "^Enclosure: " nil t) 2)
+ (let ((offset (or (and (search-forward-regexp "^Enclosure: ?" nil t) 2)
(and (search-forward-regexp "^Enclosure$" nil t) -2))))
(when offset (forward-char offset))
(if-let ((url (jao-url-around-point)))
@@ -609,63 +629,12 @@
(eval-after-load "message"
'(setq message-draft-headers (remove 'Date message-draft-headers)))
-;;; Add-ons
-;;;; notifications
-;;;;; minibuffer
-(defvar jao-gnus-tracked-groups
- (let ((feeds (thread-first
- (directory-files mail-source-directory nil "feeds\\.[^e]")
- (seq-difference '("feeds.trove")))))
- `(("nnml:bigml\\.inbox" "B" jao-themes-f00)
- ("nnml:bigml\\.alba" "A" jao-themes-f00)
- ("nnml:bigml\\.bugs" "b" jao-themes-error)
- ("nnml:bigml\\.support" "S" default)
- ("nnml:jao\\.\\(inbox\\|trove\\)" "I" jao-themes-f01)
- ("nnml:bigml\\.[^ibs]" "W" jao-themes-dimm)
- ("nnml:jao.hacking" "H" jao-themes-dimm)
- ("nnml:jao.[^isth]" "J" jao-themes-dimm)
- (,(format "^nnml:%s" (regexp-opt feeds)) "F" jao-themes-dimm)
- ("feeds\\.e" "E" jao-themes-dimm)
- ("nnml:local" "l" jao-themes-dimm))))
-
-(defun jao-gnus--unread-counts ()
- (seq-reduce (lambda (r g)
- (let ((n (gnus-group-unread (car g))))
- (if (and (numberp n) (> n 0))
- (prog1 (cons (cons (car g) n) r)
- (gnus-message 7 "%s in %s" n g))
- r)))
- gnus-newsrc-alist
- ()))
-
-(defun jao-gnus--unread-label (counts rx label face)
- (let ((n (seq-reduce (lambda (n c)
- (if (string-match-p rx (car c)) (+ n (cdr c)) n))
- counts
- 0)))
- (when (> n 0) `(:propertize ,(format "%s%d " label n) face ,face))))
-
-(defvar jao-gnus--notify-strs ())
-
-(defun jao-gnus--notify-strs ()
- (let ((counts (jao-gnus--unread-counts)))
- (seq-filter #'identity
- (seq-map (lambda (args)
- (apply 'jao-gnus--unread-label counts args))
- jao-gnus-tracked-groups))))
-
-(defun jao-gnus--notify ()
- (setq jao-gnus--notify-strs (jao-gnus--notify-strs))
- (jao-minibuffer-refresh))
-
-(with-eval-after-load "jao-minibuffer"
- (jao-minibuffer-add-variable 'jao-gnus--notify-strs -20))
-
-(add-hook 'gnus-started-hook #'jao-gnus--notify)
-(add-hook 'gnus-summary-exit-hook #'jao-gnus--notify)
-(add-hook 'gnus-after-getting-new-news-hook #'jao-gnus--notify)
+;;; daemon and exit
+(setq gnus-interactive-exit t)
+(defun jao-quit-gnus () (gnus-group-exit) t)
+(add-hook 'kill-emacs-query-functions #'jao-quit-gnus)
-;;;;; daemon config
+;; daemon config
(setq mail-user-agent 'gnus-user-agent)
(setq gnus-asynchronous t)
(setq gnus-use-article-prefetch nil)
@@ -677,13 +646,85 @@
(defun jao-gnus--scan ()
(let ((inhibit-message t))
(gnus-demon-scan-news)
+ (jao-shell-exec "notmuch-gnus-tags.sh")
+ (when-let* ((a (get-buffer "*Org Agenda*")))
+ (with-current-buffer a (org-agenda-redo-all)))
(jao-gnus--notify)))
-(gnus-demon-add-handler 'jao-gnus--scan 5 1)
+(defun jao-gnus--scan-local-mail ()
+ (let ((inhibit-message nil))
+ (message "Scanning local news in demon...")
+ (let ((mail-sources jao-local-mail-sources))
+ (gnus-demon-scan-news))
+ (jao-gnus--notify)))
-;;;;; agenda updates
-(add-hook 'gnus-summary-exit-hook #'jao-org-agenda)
+(defun jao-gnus-add-demon ()
+ (interactive)
+ (message "Adding scan demon for Gnus...")
+ (gnus-demon-add-handler 'jao-gnus--scan 5 1))
+(defun jao-gnus-remove-demon ()
+ (interactive)
+ (message "Removing scan demon for Gnus...")
+ (gnus-demon-remove-handler 'jao-gnus--scan))
+
+(jao-gnus-add-demon)
+(gnus-demon-init)
+
+;; this is, in theory, not needed; but at some point in the way to emacs
+;; version 31 this idle timers have ceased to work after a sleep/awake cycle
+(jao-when-linux (add-to-list 'jao-sleep-awake-functions #'jao-gnus-add-demon))
+
+;;; add-ons
+;;;; notifications
+;;;;; minibuffer
+(defvar jao-gnus--notify-strs ())
+
+(defun jao-gnus--xbar-echo ()
+ (let* ((total (cdr (assoc "Gnus" gnus-topic-unreads)))
+ (jao (cdr (assoc "jao" gnus-topic-unreads)))
+ (str (concat (when (> total 0) (format "%d" total))
+ " "
+ (when (> jao 0) (format "J%d" jao)))))
+ (jao-shell-exec
+ (format "echo '%s | color=#8b3626 | size=11' >/tmp/xbar" str))))
+
+(defvar jao-gnus-group-notifications
+ '(("Gnus" "" jao-themes-dimm)
+ ("jao" "J" jao-themes-warning)
+ ("news" "N" jao-themes-dimm)
+ ("prog" "P" jao-themes-dimm)
+ ("sci" "S" jao-themes-dimm)))
+
+(defun jao-gnus--notify-group-str (p)
+ (let* ((n (cdr p))
+ (f (cdr (assoc (car p) jao-gnus-group-notifications))))
+ (when (and f (> n 0))
+ `(:propertize ,(format "%s%d " (car f) n) face ,(cadr f)))))
+
+(defun jao-gnus--notify ()
+ (setq jao-gnus--notify-strs
+ (seq-keep 'jao-gnus--notify-group-str gnus-topic-unreads))
+ (jao-when-darwin (jao-gnus--xbar-echo))
+ (jao-minibuffer-refresh))
+
+(with-eval-after-load "jao-minibuffer"
+ (jao-minibuffer-add-variable 'jao-gnus--notify-strs -20))
+
+(add-hook 'gnus-started-hook #'jao-gnus--notify)
+;; (add-hook 'gnus-summary-exit-hook #'jao-gnus--notify)
+(add-hook 'gnus-after-getting-new-news-hook #'jao-gnus--notify)
+
+;;;;; agenda and other updates on summary exit
+(let ((exit-count 0))
+ (defun jao-gnus--on-summary-exit ()
+ (when (> (setq exit-count (+ 1 exit-count)) 20)
+ (setq exit-count 0)
+ (jao-org-agenda))
+ (jao-gnus--notify)))
+
+(add-hook 'gnus-summary-exit-hook #'jao-gnus--on-summary-exit)
+(add-hook 'gnus-exit-group-hook #'jao-gnus--notify)
;;;; open mail file in gnus
(defun jao-gnus-file-to-group (file &optional maildir newsdir m-server n-server)
@@ -720,11 +761,16 @@
;;;; afio
(defun jao-gnus--on-afio-switch ()
(when (derived-mode-p 'gnus-group-mode)
+ (jao-gnus--notify)
(let ((no (or (gnus-group-unread (gnus-group-group-name)) 0)))
(unless (> no 0) (gnus-group-first-unread-group)))))
(add-hook 'jao-afio-switch-hook #'jao-gnus--on-afio-switch)
+(defun jao-gnus-refresh-workspace ()
+ (interactive)
+ (save-window-excursion (calendar) (jao-org-agenda)))
+
;;;; gnus-icalendar
(require 'ol-gnus)
(use-package gnus-icalendar
@@ -754,7 +800,21 @@
(with-eval-after-load "consult-recoll"
(add-to-list 'consult-recoll-open-fns
'("message/rfc822" . jao-gnus-goto-file))))
-;;; Keyboard shortcuts
+;;;; notmuch
+(use-package jao-notmuch-gnus
+ :demand t
+ :init
+ (jao-when-darwin
+ (setq jao-notmuch-gnus-mail-directory
+ (expand-file-name "gnus" jao-maildir))))
+
+(jao-load-path "consult-notmuch")
+
+(use-package consult-notmuch
+ :ensure t
+ :bind (:map gnus-group-mode-map ("/" . #'jao-gnus-consult-notmuch)))
+
+;;; keyboard shortcuts
(define-key gnus-article-mode-map "i" 'jao-gnus-show-images)
(define-key gnus-summary-mode-map "i" 'jao-gnus-show-images)
(define-key gnus-article-mode-map "\M-g" 'jao-gnus-follow-link)
@@ -764,4 +824,7 @@
(define-key gnus-summary-mode-map "X" 'jao-gnus-arXiv-capture)
(define-key gnus-summary-mode-map "e" 'jao-gnus-open-enclosure)
(define-key gnus-summary-mode-map "\C-l" nil)
-(define-key gnus-group-mode-map (kbd "A") 'nil)
+(define-key gnus-group-mode-map "a" 'jao-gnus-refresh-workspace)
+
+(jao-when-darwin
+ (define-key gnus-group-mode-map "O" 'jao-mac-open-nnw))