diff options
Diffstat (limited to 'gnus.org')
-rw-r--r-- | gnus.org | 660 |
1 files changed, 660 insertions, 0 deletions
diff --git a/gnus.org b/gnus.org new file mode 100644 index 0000000..6d87741 --- /dev/null +++ b/gnus.org @@ -0,0 +1,660 @@ +#+PROPERTY: header-args :tangle yes :comments yes :results silent + +* Feature switching vars + #+BEGIN_SRC emacs-lisp + (defvar jao-gnus-use-local-imap t) + (defvar jao-gnus-use-leafnode t) + (defvar jao-gnus-use-pm-imap nil) + (defvar jao-gnus-use-gmail nil) + (defvar jao-gnus-use-gmane nil) + (defvar jao-gnus-use-nnml nil) + (defvar jao-gnus-use-maildirs nil) + (defvar jao-gnus-use-nnreddit nil) +#+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-gmail + (add-to-list 'gnus-secondary-select-methods + '(nnimap "gmail" (nnimap-address "imap.gmail.com"))) + (add-to-list 'gnus-secondary-select-methods + '(nnimap "bigml" (nnimap-address "imap.gmail.com")))) + #+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)) + + ;; (use-package nnreddit + ;; :ensure t + ;; :bind (:map gnus-group-mode-map (("R R" . gnus-group-restart)))) + + ;; (when jao-gnus-use-nnreddit + ;; (add-to-list 'gnus-secondary-select-methods '(nnreddit ""))) + + #+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 +* 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)))) + + (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")) + + + ;; 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) + (define-key gnus-group-mode-map "Z" 'jao-gnus-restart-servers) + #+END_SRC +* Group parameters + #+begin_src emacs-lisp + (setq jao-gnus-expirable + (format (concat "^nnimap:\\(" + "\\(\\(bigml\\|bml\\)/%s\\)\\|" + "\\(\\(jao\\|pm\\)/%s\\)\\|" + "\\(feeds/.+\\)\\|trash" + "\\)") + (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:trash") + (jao-gnus--archiving-group "nnimap:trove/jao")) + ("^nnimap:pm/.*" + (jao-gnus--trash-group "nnimap:pm/trash") + (jao-gnus--spam-group "nnimap:pm/spam") + (jao-gnus--archiving-group "nnimap:pm/archive")) + ("^nnimap:\\(jao\\|pm\\)/\\(trash\\|spam\\)" + (gcc-self . nil) + (auto-expire . t) + (total-expire . t) + (expiry-wait . 0.1) + (jao-gnus--trash-group nil) + (expiry-target . delete)) + ("^nnimap:jao/inbox" + (gcc-self . t) + (posting-style (gcc "nnimap:trove/jao"))) + ("^nnimap:b\\(ig\\)?ml/inbox" + (gcc-self . t) + (auto-expire . t) + (total-expire . t) + (expiry-wait . 7.0) + (jao-gnus--trash-group "nnimap:trash") + (expiry-target . "nnimap:bigml/trove")) + ("^nnimap:bml/inbox" + (jao-gnus--trash-group "nnimap:bml/trash") + (expiry-target . "nnimap:bml/trove")) + ("^nnimap:b\\(ig\\)?ml/.*" + (posting-style (address "jao@bigml.com")) + (jao-gnus--archiving-group "nnimap:bml/trove")) + ("^nnimap:b\\(ig\\)?ml/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/fun" + ;; (mm-text-html-renderer 'shr) + (gnus-inhibit-images nil)) + ("^nnimap:feeds/\\(papers\\|programming\\|math\\|physics\\)$" + (expiry-wait . 30) + (jao-gnus--archiving-group "nnimap:trove/tech") + (posting-style (address "jao@gnu.org"))) + ("^nnimap:feeds/\\(physics\\|math\\|papers\\)$" + (jao-gnus--archiving-group "nnimap:trove/sci")) + ("\\(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 <backspace>") '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+olp "misc.org" "Physics" "arXiv") + "* %: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 + ;; use w3m for html mail + (defun jao-gnus-html-renderer (handle) + (let ((w3m-message-silent t)) + (condition-case nil + (mm-inline-text-html-render-with-w3m handle) + (error (delete-region (point) (point-max)) + (mm-shr handle))))) + + (setq gnus-button-url 'browse-url-generic + gnus-inhibit-images t + mm-text-html-renderer 'jao-gnus-html-renderer ;; 'w3m ;; 'shr + shr-use-colors nil + shr-use-fonts nil + mm-w3m-safe-url-regexp 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: <a" nil t) + (let ((begin (- (point) 3))) + (when (re-search-forward "^\\(To\\|Subject\\):" nil t) + (beginning-of-line) + (let ((shr-width 1000)) + (shr-render-region begin (- (point) 1)) + (goto-char begin) + (insert " "))))))) + + (add-hook 'gnus-part-display-hook 'jao-gnus-remove-anchors) + + ;; show images + (defun jao-gnus-show-image (&optional external) + (interactive "P") + (when (eq major-mode 'gnus-summary-mode) + (gnus-summary-select-article-buffer)) + (let ((pos (next-single-property-change (point) 'w3m-image))) + (if (not pos) + (gnus-article-show-images) + (goto-char pos) + (if external (w3m-view-image) (w3m-toggle-inline-image))))) + + (defun jao-gnus-show-images (&optional external) + (interactive "P") + (save-window-excursion + (gnus-summary-select-article-buffer) + (save-excursion + (let ((pos (next-single-property-change (point) 'w3m-image))) + (if (not pos) + (gnus-article-show-images) + (goto-char pos) + (w3m-toggle-inline-images)))))) + #+END_SRC +*** Follow links and enclosures + #+begin_src emacs-lisp + (defun jao-gnus-follow-link (&optional external) + (interactive "P") + (when (eq major-mode 'gnus-summary-mode) + (gnus-summary-select-article-buffer)) + (save-excursion + (goto-char (point-min)) + (when (or (search-forward-regexp "^Via: h" nil t) + (search-forward-regexp "^URL: h" nil t) + (and (search-forward-regexp "^Link$" nil t) + (not (beginning-of-line)))) + (if external + (jao-browse-with-external-browser) + (w3m-safe-view-this-url))))) + + (defun jao-gnus-open-enclosure (&optional playp) + (interactive "P") + (gnus-summary-select-article-buffer) + (save-excursion + (goto-char (point-min)) + (when (search-forward "Enclosure:") + (forward-char 2) + (when-let ((url (thing-at-point-url-at-point))) + (message "%s %s ..." (if playp "Playing" "Adding") url) + (if playp (emms-play-url url) (emms-add-url url)) + (when playp + (sit-for 1) + (jao-emms-echo)))))) + #+end_src +*** Tweets and toots + #+BEGIN_SRC emacs-lisp + (defun jao-gnus--find-link () + (when (eq major-mode 'gnus-summary-mode) + (gnus-summary-select-article-buffer)) + (goto-char (point-max)) + (or (search-backward-regexp "^Link\\b" nil t) + (search-backward-regexp "^URL: h" nil t) + (search-backward-regexp "^Via: h")) + (goto-char (match-end 0)) + (jao-w3m--toot-text nil nil "")) + + (defun jao-gnus-tweet-link (&optional toot) + (interactive "P") + (save-excursion + (jao-gnus--find-link) + (if toot + (jao-w3m-toot nil nil (elt gnus-current-headers 1)) + (jao-w3m-tweet nil nil (elt gnus-current-headers 1))))) + + (defun jao-gnus-toot-link () + (interactive) + (jao-gnus-tweet-link t)) + + (defun jao-gnus-mail-link () + (interactive) + (let ((txt (jao-gnus--find-link))) + (when txt + (message-mail-other-window) + (message-goto-body) + (insert "\n\n" txt) + (message-goto-to)))) + #+END_SRC +* Keyboard shortcuts + #+BEGIN_SRC emacs-lisp + (define-key gnus-article-mode-map "\C-ci" 'w3m-view-image) + (define-key gnus-article-mode-map "\C-cb" 'jao-w3m-do-browse) + (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 "z" 'w3m-lnum-zoom-in-image) + (define-key gnus-article-mode-map "\C-ct" 'jao-gnus-tweet-link) + (define-key gnus-summary-mode-map "\C-ct" 'jao-gnus-tweet-link) + (define-key gnus-article-mode-map "\C-cT" 'jao-gnus-toot-link) + (define-key gnus-summary-mode-map "\C-cT" 'jao-gnus-toot-link) + (define-key gnus-article-mode-map "\M-g" 'jao-gnus-follow-link) + (define-key gnus-summary-mode-map "\M-g" 'jao-gnus-follow-link) + (define-key gnus-summary-mode-map "v" 'scroll-other-window) + (define-key gnus-summary-mode-map "V" 'scroll-other-window-down) + (define-key gnus-summary-mode-map "X" 'jao-gnus-arXiv-capture) + + (major-mode-hydra-define gnus-summary-mode nil + ("Browse" + (("g" jao-gnus-follow-link "Follow link in emacs") + ("G" (lambda () (interactive) (jao-gnus-follow-link t)) + "Follow link in external browser")) + "Capture" + (("x" jao-gnus-arXiv-capture "Capture arXiv entry") + ("e" jao-gnus-open-enclosure "Add enclosure to playlist") + ("E" (jao-gnus-open-enclosure t) "Play enclosure")) + "Images" + (("i" jao-gnus-show-images "Show images")) + "Toot" + (("t" jao-gnus-tweet-link "Tweet article") + ("T" jao-gnus-toot-link "Toot article")))) + + (major-mode-hydra-define gnus-article-mode nil + ("Browse" + (("g" jao-gnus-follow-link "Follow link in emacs") + ("G" (lambda () (interactive) (jao-gnus-follow-link t)) + "Follow link in external browser")) + "Capture" + (("x" jao-gnus-arXiv-capture "Capture arXiv entry") + ("e" jao-gnus-open-enclosure "Add enclosure to playlist") + ("E" (jao-gnus-open-enclosure t) "Play enclosure")) + "Images" + (("z" w3m-lnum-zoom-in-image "Zoom image at point") + ("I" w3m-view-image "View image at point") + ("i" jao-gnus-show-images "Show images")) + "Toot" + (("t" jao-gnus-tweet-link "Tweet article") + ("T" jao-gnus-toot-link "Toot article")))) + #+END_SRC |