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.el301
1 files changed, 171 insertions, 130 deletions
diff --git a/custom/jao-custom-gnus.el b/custom/jao-custom-gnus.el
index 70823ef..7483e39 100644
--- a/custom/jao-custom-gnus.el
+++ b/custom/jao-custom-gnus.el
@@ -30,11 +30,13 @@
nndraft-directory (jao-gnus-dir "drafts")
nnrss-directory (jao-gnus-dir "rss"))
+(setq gnus-uncacheable-groups "^nnml")
+
;;; 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)
@@ -42,17 +44,13 @@
gnus-generate-tree-function 'gnus-generate-horizontal-tree
gnus-tree-minimize-window nil)
-(when jao-gnus-use-three-panes
-
- ;; (dolist (m '(calendar-mode org-agenda-mode gnus-group-mode))
- ;; (add-to-list 'display-buffer-alist `((major-mode . ,m) (dedicated t))))
-
- (setq calendar-left-margin 6)
+(setq calendar-left-margin 6)
- (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*" 8)))
+ ("*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)))
@@ -88,59 +86,60 @@
(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
(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 ")
- ")")))
- (qstring (if (string-prefix-p "id:" qstring)
- (replace-regexp-in-string "<\\|>" "\"" qstring)
- qstring))
- (qstring (if (cdr (assoc 'thread query))
- (concat qstring " OR "
- (replace-regexp-in-string "id:\"" "ref:\""
- qstring))
- qstring))
- (qstring (replace-regexp-in-string " or " " OR " qstring))
- (qstring (replace-regexp-in-string " and " " AND " qstring))
- (q (format "mime:message %s (%s)" dirsq qstring)))
- ;; (message "query is: %s -- %S" q query)
- `("-b" "-t" "-q" ,q))))
+(use-package jao-recoll
+ :if (jao-is-linux))
;; (add-to-list 'gnus-parameters '("^nnselect:.*" (nnselect-rescan . t)))
@@ -194,26 +193,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/"))))))
+ (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-notmuch
+ (remove-prefix ,prefix))))))
(when jao-gnus-use-nnml
(dolist (p jao-gnus-nnml-group-params)
@@ -239,10 +254,12 @@
;;; 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)
@@ -318,12 +335,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)
@@ -447,13 +466,19 @@
(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\n(jao-gnus-org-paragraph \"%i\")"
+ "* %(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 ")
@@ -462,22 +487,27 @@
(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-subject (gnus-summary-article-subject))
+ (setq jao-gnus-subject (gnus-summary-article-subject))
(gnus-summary-select-article-buffer)
(gnus-article-goto-part 0)
- (setq-local transient-mark-mode 'lambda)
- (set-mark (point))
- (forward-paragraph)
- (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")
- (set-mark (point))
+ (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
@@ -494,6 +524,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
@@ -558,7 +589,7 @@
(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))))
(cond (external (jao-browse-with-external-browser))
@@ -580,7 +611,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)))
@@ -611,66 +642,66 @@
(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)))
+
+(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)))
(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
-(add-to-list 'jao-sleep-awake-functions #'jao-gnus-add-demon)
+(jao-when-linux (add-to-list 'jao-sleep-awake-functions #'jao-gnus-add-demon))
;;; 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\\.[^aibs]" "W" jao-themes-dimm)
- ("nnml:jao.hacking" "H" jao-themes-dimm)
- ("nnml:jao.write" "W" jao-themes-warning)
- ("nnml:jao.[^isthw]" "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)
- ("nnrss:.*" "R" jao-themes-dimm)
- ("^\\(gwene\\|gmane\\)\\." "N" 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)) (cons (cons (car g) n) r) 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--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 (jao-gnus--notify-strs))
+ (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"
@@ -689,6 +720,7 @@
(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)
@@ -725,6 +757,7 @@
;;;; 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)))))
@@ -765,12 +798,17 @@
'("message/rfc822" . jao-gnus-goto-file))))
;;;; notmuch
(use-package jao-notmuch-gnus
- :demand t)
+ :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
- :bind (:map gnus-group-mode-map ("S" . #'jao-gnus-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)
@@ -783,3 +821,6 @@
(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 "a" 'jao-gnus-refresh-workspace)
+
+(jao-when-darwin
+ (define-key gnus-group-mode-map "O" 'jao-mac-open-nnw))