diff options
Diffstat (limited to 'custom/jao-custom-gnus.el')
| -rw-r--r-- | custom/jao-custom-gnus.el | 301 | 
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)) | 
