dot_gnus.el 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. ;; Copyright © 2018, 2019, 2020, 2021, 2022, 2024 Oleg Pykhalov <go.wigust@gmail.com>
  2. ;; Released under the GNU GPLv3 or any later version.
  3. (require 'mailcap)
  4. (setq gnus-use-full-window nil)
  5. (setq gnus-select-method '(nnimap "USER"
  6. (nnimap-address "localhost")
  7. (nnimap-server-port "imaps")))
  8. (setq gnus-permanently-visible-groups ".*INBOX")
  9. (setq mm-discouraged-alternatives '("text/html" "text/richtext"))
  10. (setq gnus-check-new-newsgroups nil) ; Call `gnus-find-new-newsgroups' manually
  11. ;; (Info-goto-node "(gnus) Scoring On Other Headers")
  12. ;; I e s p To RET <your name> RET
  13. (setq gnus-extra-headers '(To Cc Keywords Gcc Newsgroups X-GM-LABELS List-Id X-Redmine-Issue-Author))
  14. (setq nnmail-extra-headers gnus-extra-headers)
  15. ;; TODO: gnus: Sort all IMAP groups by score.
  16. (setq gnus-parameters (mapcar (lambda (group)
  17. `(,group (gnus-thread-sort-functions
  18. 'gnus-thread-sort-by-score)))
  19. '("^INBOX$" "^majordomo-.*$")))
  20. (add-hook 'message-sent-hook #'gnus-score-followup-thread)
  21. (add-hook 'gnus-article-mode-hook 'goto-address-mode)
  22. ;; Code from: https://github.com/jwiegley/dot-emacs
  23. (defun switch-to-gnus (&optional arg)
  24. "Switch to a Gnus related buffer.
  25. Candidates are buffers starting with
  26. *mail or *reply or *wide reply
  27. *Summary or
  28. *Group*
  29. Use a prefix argument to start Gnus if no candidate exists."
  30. (interactive "P")
  31. (let (candidate
  32. (alist '(("^\\*\\(mail\\|\\(wide \\)?reply\\)" t)
  33. ("^\\*Group")
  34. ("^\\*Summary")
  35. ("^\\*Article" nil (lambda ()
  36. (buffer-live-p
  37. gnus-article-current-summary))))))
  38. (catch 'none-found
  39. (dolist (item alist)
  40. (let (last
  41. (regexp (nth 0 item))
  42. (optional (nth 1 item))
  43. (test (nth 2 item)))
  44. (dolist (buf (buffer-list))
  45. (when (and (string-match regexp (buffer-name buf))
  46. (> (buffer-size buf) 0))
  47. (setq last buf)))
  48. (cond ((and last (or (not test) (funcall test)))
  49. (setq candidate last))
  50. (optional
  51. nil)
  52. (t
  53. (throw 'none-found t))))))
  54. (cond (candidate
  55. (switch-to-buffer candidate))
  56. (arg
  57. (gnus))
  58. (t
  59. (error "No candidate found")))))
  60. (defun gnus-summary-limit-to-score (score &optional below)
  61. "Limit to articles with score at or above SCORE if BELOW is nil,
  62. below otherwise."
  63. (interactive (list (string-to-number
  64. (read-string
  65. (format "Limit to articles with score of at %s: "
  66. (if current-prefix-arg "most" "least"))))))
  67. (let* ((data gnus-newsgroup-data)
  68. (compare (if (or below current-prefix-arg) #'<= #'>=))
  69. articles)
  70. (while data
  71. (when (funcall compare (gnus-summary-article-score
  72. (gnus-data-number (car data)))
  73. score)
  74. (push (gnus-data-number (car data)) articles))
  75. (setq data (cdr data)))
  76. (prog1
  77. (gnus-summary-limit articles)
  78. (gnus-summary-position-point))))
  79. (setq gnus-visible-headers
  80. (concat "^From:"
  81. "\\|^Newsgroups:"
  82. "\\|^Subject:"
  83. "\\|^Date:"
  84. "\\|^Followup-To:"
  85. "\\|^Reply-To:"
  86. "\\|^Organization:"
  87. "\\|^Summary:"
  88. "\\|^Keywords:"
  89. "\\|^To:"
  90. "\\|^[BGF]?Cc:"
  91. "\\|^Posted-To:"
  92. "\\|^Mail-Copies-To:"
  93. "\\|^Mail-Followup-To:"
  94. "\\|^Apparently-To:"
  95. "\\|^User-Agent:"
  96. "\\|^Message-ID:"
  97. "\\|^Gnus-Warning:"
  98. "\\|^Resent-From:"))
  99. ;; Mimetypes configured in <~/.mailcap>.
  100. ;; See <https://www.emacswiki.org/emacs/MimeTypesWithGnus>.
  101. ;; Emacs ignores mailcap for PDF
  102. ;; See <https://lists.gnu.org/archive/html/info-gnus-english/2016-04/msg00001.html>.
  103. (setcdr
  104. (assoc "application" mailcap-mime-data)
  105. (remove '("pdf"
  106. (viewer . doc-view-mode)
  107. (type . "application/pdf")
  108. (test eq window-system 'x))
  109. (cdr (assoc "application" mailcap-mime-data))))
  110. (setcdr
  111. (assoc "application" mailcap-mime-data)
  112. (remove '("pdf"
  113. (viewer . pdf-view-mode)
  114. (type . "application/pdf")
  115. (test eq window-system 'x))
  116. (cdr (assoc "application" mailcap-mime-data))))
  117. ;; Origin <http://bbdb.sourceforge.net/bbdb.html#SEC2>.
  118. (bbdb-initialize 'gnus 'message)
  119. ;; Origin <https://emacs.stackexchange.com/a/166>.
  120. (bbdb-mua-auto-update-init 'message) ; use 'gnus for incoming messages too
  121. (setq bbdb-mua-auto-update-p 'query) ;; or 'create to create without asking
  122. (defcustom wi-gnus-subject-regexp-debbugs
  123. (rx-to-string `(and (* "[") "bug" "#" (group (+ alnum)) (* "]") (+ anything))
  124. t)
  125. "Regexp matching Debbugs bug in Gnus header.")
  126. (defun wi-gnus-subject-match-debbugs ()
  127. "Return Debbugs bug number from a Gnus article header."
  128. (interactive)
  129. (let* ((header (with-current-buffer gnus-summary-buffer
  130. (gnus-summary-article-header)))
  131. (subject (mail-header-subject header)))
  132. (string-match wi-gnus-subject-regexp-debbugs subject)
  133. (string-to-number (match-string 1 subject))))
  134. (defun wi-gnus-browse-debbugs ()
  135. "Open current Gnus article in with `debbugs-gnu-bugs'."
  136. (interactive)
  137. (debbugs-gnu-bugs (wi-gnus-subject-match-debbugs)))
  138. (defun wi-gnus-browse-guix-issues ()
  139. "Open current Gnus article in with `debbugs-gnu-bugs'."
  140. (interactive)
  141. (browse-url (format "https://issues.guix.info/issue/%d" (wi-gnus-subject-match-debbugs))))
  142. (with-eval-after-load 'gnus-group
  143. (let ((map gnus-group-mode-map))
  144. (define-key map (kbd "<f5>") 'mbsync)))
  145. (with-eval-after-load 'gnus
  146. (let ((map gnus-summary-mode-map))
  147. (define-key map (kbd "<f5>") 'mbsync)
  148. (define-key map (kbd "<f6>") 'org-capture-inbox)
  149. (define-key map (kbd "<C-return>") 'org-capture-inbox)))
  150. (with-eval-after-load 'gnus-art
  151. (let ((map gnus-article-mode-map))
  152. (define-key map (kbd "<f6>") 'org-capture-inbox)
  153. (define-key map (kbd "<C-return>") 'org-capture-inbox)))
  154. (setq gnus-summary-line-format "%U%R %d %i %I%(%[%4L: %-23,23f%]%) %s\n")
  155. (defun gnus-copy-message-id-subject ()
  156. (interactive)
  157. (let ((header (with-current-buffer gnus-summary-buffer
  158. (gnus-summary-article-header))))
  159. (kill-new (format "%s %s"
  160. (mail-header-message-id header)
  161. (mail-header-subject header)))))
  162. (setq gnus-posting-styles
  163. '((".*" ; Matches all groups of messages
  164. (address "Oleg Pykhalov <go.wigust@gmail.com>"))
  165. ("majordomo-.*" ; Matches Gnus group called "work"
  166. (name "Олег Пыхалов")
  167. (address "pyhalov@majordomo.ru")
  168. (organization "Majordomo"))
  169. ("majordomo-noc" ; Matches Gnus group called "work"
  170. (name "ООО Хостинг")
  171. (address "noc@majordomo.ru")
  172. (organization "Majordomo"))))
  173. ;; (setq nnmail-expiry-wait 'immediate)
  174. ;;
  175. ;; Alternative:
  176. ;;
  177. ;; in a *Group* buffer
  178. ;; G p
  179. ;; (expiry-wait . immediate) ; instead of 7 days
  180. ;; (auto-expire . t) ; kill, read, etc article will auto-expire
  181. ;; (gnus-add-configuration
  182. ;; '(article
  183. ;; (horizontal 1.0
  184. ;; (summary 0.60 point)
  185. ;; (article 1.0))))