init-mu4e.el 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. ;;; mu4e
  2. ;;; REVIEW: Reply to all by default.
  3. ;;; https://github.com/djcb/mu/issues/1135
  4. ;;; TODO: Is it possible to mbsync without attachments?
  5. ;;; REVIEW: Do not cite when replying: https://github.com/djcb/mu/issues/1110.
  6. ;;; TODO: Face of `message-cited-text' does not work.
  7. ;;; REVIEW: Handle attachments in attached e-mails.
  8. ;;; See https://github.com/djcb/mu/issues/454#issuecomment-320616279.
  9. ;;; TODO: <tab> should go to next link in text e-mails too.
  10. ;; We need 'main' to setup pinentry-emacs for GPG.
  11. (require 'main)
  12. (when (require 'mu4e-maildirs-extension nil t)
  13. (mu4e-maildirs-extension))
  14. (defun ambrevar/mu4e-headers ()
  15. "Like `mu4e' but show the header view.
  16. Default to unread messages if the header buffer does not already exist."
  17. (interactive)
  18. (mu4e~start)
  19. (if (get-buffer "*mu4e-headers*" )
  20. (switch-to-buffer "*mu4e-headers*")
  21. (mu4e-headers-search "flag:unread AND NOT flag:trashed")))
  22. (setq
  23. ;; Attachments
  24. mu4e-attachment-dir "~/temp"
  25. mu4e-save-multiple-attachments-without-asking t
  26. ;; IMAP sync.
  27. mu4e-maildir "~/.cache/mail"
  28. mu4e-get-mail-command "mbsync -a"
  29. mu4e-update-interval 90
  30. mu4e-headers-auto-update nil ; Don't refresh so that we don't lose the current filter upon, e.g. reading e-mails.
  31. mu4e-change-filenames-when-moving t ; Preferred for mbsync according to the man page.
  32. ;; SMTP
  33. message-send-mail-function 'smtpmail-send-it
  34. ;; Don't bother me with context on startup.
  35. mu4e-context-policy nil
  36. ;; Don't keep sent e-mail buffer.
  37. message-kill-buffer-on-exit t
  38. ;; For reporting bugs, "C-x m", etc.
  39. mail-user-agent 'mu4e-user-agent
  40. mu4e-compose-dont-reply-to-self t
  41. ;; Display
  42. mu4e-headers-date-format "%F %R"
  43. mu4e-headers-fields '((:human-date . 16)
  44. (:flags . 6)
  45. (:size . 6)
  46. (:mailing-list . 10)
  47. (:from . 22)
  48. (:subject))
  49. mu4e-headers-time-format "%R"
  50. mu4e-view-show-addresses t
  51. mu4e-view-show-images t
  52. mu4e-view-image-max-width 800
  53. mu4e-hide-index-messages t
  54. ;; If you're using a dark theme, and the messages are hard to read, it
  55. ;; can help to change the luminosity, e.g.:
  56. shr-color-visible-luminance-min 80
  57. ;; Gmail-style threading.
  58. mu4e-headers-include-related t
  59. ;; Gmail likes format=flowed(?)
  60. ;; mu4e-compose-format-flowed
  61. ;; Also crypt to self so that we can read sent e-mails.
  62. mml-secure-openpgp-encrypt-to-self t
  63. ;; Because default completion can be extended (e.g. Helm, Ivy).
  64. mu4e-completing-read-function 'completing-read)
  65. ;;; Press "aV" to view in browser.
  66. (add-to-list 'mu4e-view-actions '("ViewInBrowser" . mu4e-action-view-in-browser) t)
  67. ;;; Unicode chars for decoration might cause issues with some fonts or in terminals.
  68. ;;; https://github.com/djcb/mu/issues/733
  69. ;;; https://github.com/djcb/mu/issues/1062
  70. ;; (setq mu4e-use-fancy-chars t)
  71. ;;; REVIEW: Sorting in ascending order is impeded by `mu4e-search-results-limit': the 500 oldest e-mails will be displayed first.
  72. ;;; https://github.com/djcb/mu/issues/809
  73. ;; (setq mu4e-headers-sort-direction 'ascending)
  74. ;;; Since we sort in ascending direction, we default to the end of buffer.
  75. ;; (add-hook 'mu4e-headers-found-hook 'end-of-buffer)
  76. (defvar ambrevar/mu4e-compose-fortune-p t "Whether or not to include a fortune in the signature.")
  77. (defun ambrevar/mu4e-add-fortune-signature ()
  78. (require 'functions) ; For `call-process-to-string'.
  79. (setq mu4e-compose-signature
  80. (if (and ambrevar/mu4e-compose-fortune-p
  81. (executable-find "fortune"))
  82. (format "%s\n\n%s"
  83. user-full-name
  84. (ambrevar/call-process-to-string "fortune" "-s"))
  85. user-full-name)))
  86. (add-hook 'mu4e-compose-pre-hook 'ambrevar/mu4e-add-fortune-signature)
  87. ;;; Make some e-mails stand out a bit.
  88. (set-face-foreground 'mu4e-unread-face "yellow")
  89. (set-face-attribute 'mu4e-flagged-face nil :inherit 'font-lock-warning-face)
  90. ;;; Confirmation on every mark execution is too slow to my taste.
  91. (defun ambrevar/mu4e-mark-execute-all-no-confirm ()
  92. (interactive)
  93. (mu4e-mark-execute-all t))
  94. (define-key mu4e-headers-mode-map "x" 'ambrevar/mu4e-mark-execute-all-no-confirm)
  95. (when (require 'helm-mu nil t)
  96. (dolist (map (list mu4e-headers-mode-map mu4e-main-mode-map mu4e-view-mode-map))
  97. (define-key map "s" 'helm-mu)))
  98. (defvar ambrevar/mu4e-compose-signed-p t)
  99. (defvar ambrevar/mu4e-compose-signed-and-crypted-p nil)
  100. (defun ambrevar/mu4e-compose-maybe-signed-and-crypted ()
  101. "Maybe sign or encrypt+sign message.
  102. Message is signed or encrypted+signed when replying to a signed or encrypted
  103. message, respectively.
  104. Alternatively, message is signed or encrypted+signed if
  105. `ambrevar/mu4e-compose-signed-p' or `ambrevar/mu4e-compose-signed-and-crypted-p' is
  106. non-nil, respectively.
  107. This function is suitable for `mu4e-compose-mode-hook'."
  108. (let ((msg mu4e-compose-parent-message))
  109. (cond
  110. ((or ambrevar/mu4e-compose-signed-and-crypted-p
  111. (and msg (member 'encrypted (mu4e-message-field msg :flags))))
  112. (mml-secure-message-sign-encrypt))
  113. ((or ambrevar/mu4e-compose-signed-p
  114. (and msg (member 'signed (mu4e-message-field msg :flags))))
  115. (mml-secure-message-sign-pgpmime)))))
  116. (add-hook 'mu4e-compose-mode-hook 'ambrevar/mu4e-compose-maybe-signed-and-crypted)
  117. ;;; Org capture
  118. (when (require 'org-mu4e nil t)
  119. (dolist (map (list mu4e-view-mode-map mu4e-headers-mode-map))
  120. ;; Org mode has "C-c C-t" for 'org-todo.
  121. (define-key map (kbd "C-c C-t") 'org-mu4e-store-and-capture))
  122. (setq org-mu4e-link-query-in-headers-mode nil))
  123. ;;; Gmail trash fix.
  124. (defvar ambrevar/mu4e-move-to-trash-patterns nil
  125. "List of regexps to match for moving to trash instead of deleting them.
  126. Matches are done against the :maildir field of the e-mail at
  127. point. See `ambrevar/mu4e-headers-move-to-trash' and
  128. `ambrevar/mu4e-view-move-to-trash'.")
  129. (defun ambrevar/mu4e-headers-move-to-trash ()
  130. (interactive)
  131. (let ((msg-dir (mu4e-message-field (mu4e-message-at-point) :maildir)))
  132. (if (not (seq-filter (lambda (re)
  133. (string-match re msg-dir))
  134. ambrevar/mu4e-move-to-trash-patterns))
  135. (mu4e-headers-mark-for-delete)
  136. (mu4e-mark-set 'move (funcall mu4e-trash-folder (mu4e-message-at-point)))
  137. (mu4e-headers-next))))
  138. (defun ambrevar/mu4e-view-move-to-trash ()
  139. (interactive)
  140. (mu4e~view-in-headers-context
  141. (ambrevar/mu4e-headers-move-to-trash)
  142. (mu4e~headers-move (or n 1))))
  143. ;;; Don't display trashed messages in bookmarks. This is useful for Gmail where
  144. ;;; the "delete" flag is not used.
  145. (defvar ambrevar/mu4e-trash-folders nil
  146. "List of trash folders to filter out from bookmarks.")
  147. (load "~/personal/mail/mu4e.el" t)
  148. ;; Do this after setting `ambrevar/mu4e-trash-folders'.
  149. (dolist (bookmark mu4e-bookmarks)
  150. ;; TODO: Why mu4e-bookmark-query does not work here?
  151. (setf (car bookmark) (concat (mapconcat (lambda (s) (format "NOT maildir:\"%s\" and " s))
  152. ambrevar/mu4e-trash-folders "")
  153. (car bookmark))))
  154. (provide 'init-mu4e)