2019-05-05 14:11:59 -04:00
|
|
|
|
;;; email/mu4e/config.el -*- lexical-binding: t; -*-
|
2017-04-08 01:31:20 -04:00
|
|
|
|
|
2019-05-05 14:11:59 -04:00
|
|
|
|
(defvar +mu4e-backend 'mbsync
|
2018-01-24 15:08:43 -05:00
|
|
|
|
"Which backend to use. Can either be offlineimap, mbsync or nil (manual).")
|
2017-04-08 01:31:20 -04:00
|
|
|
|
|
2020-10-16 10:48:41 +08:00
|
|
|
|
(defvar +mu4e-personal-addresses 'nil
|
|
|
|
|
"Alternative to mu4e-personal-addresses that can be set for each account (mu4e context).")
|
2020-10-13 16:49:09 +02:00
|
|
|
|
|
2017-04-08 01:31:20 -04:00
|
|
|
|
|
|
|
|
|
;;
|
2019-05-05 14:11:59 -04:00
|
|
|
|
;;; Packages
|
2017-04-08 01:31:20 -04:00
|
|
|
|
|
2019-07-23 12:44:03 +02:00
|
|
|
|
(use-package! mu4e
|
2019-07-23 12:30:47 +02:00
|
|
|
|
:commands mu4e mu4e-compose-new
|
2018-01-24 15:08:43 -05:00
|
|
|
|
:init
|
2018-04-04 18:22:13 -04:00
|
|
|
|
(provide 'html2text) ; disable obsolete package
|
2020-04-27 14:08:36 -04:00
|
|
|
|
(when (or (not (require 'mu4e-meta nil t))
|
|
|
|
|
(version< mu4e-mu-version "1.4"))
|
2020-04-22 23:38:07 +02:00
|
|
|
|
(setq mu4e-maildir "~/.mail"
|
|
|
|
|
mu4e-user-mail-address-list nil))
|
2020-05-25 02:26:38 -04:00
|
|
|
|
(setq mu4e-attachment-dir
|
2020-05-26 13:23:02 -04:00
|
|
|
|
(lambda (&rest _)
|
|
|
|
|
(expand-file-name ".attachments" (mu4e-root-maildir))))
|
2017-04-08 01:31:20 -04:00
|
|
|
|
:config
|
2019-05-05 14:11:59 -04:00
|
|
|
|
(pcase +mu4e-backend
|
2018-01-24 15:08:43 -05:00
|
|
|
|
(`mbsync
|
|
|
|
|
(setq mu4e-get-mail-command "mbsync -a"
|
|
|
|
|
mu4e-change-filenames-when-moving t))
|
|
|
|
|
(`offlineimap
|
|
|
|
|
(setq mu4e-get-mail-command "offlineimap -o -q")))
|
|
|
|
|
|
|
|
|
|
(setq mu4e-update-interval nil
|
2017-04-08 01:31:20 -04:00
|
|
|
|
mu4e-compose-format-flowed t ; visual-line-mode + auto-fill upon sending
|
|
|
|
|
mu4e-view-show-addresses t
|
2018-01-24 15:08:43 -05:00
|
|
|
|
mu4e-sent-messages-behavior 'sent
|
|
|
|
|
mu4e-hide-index-messages t
|
2017-04-08 01:31:20 -04:00
|
|
|
|
;; try to show images
|
|
|
|
|
mu4e-view-show-images t
|
|
|
|
|
mu4e-view-image-max-width 800
|
2020-09-23 00:22:04 +08:00
|
|
|
|
mu4e-view-use-gnus t ; the way of the future: https://github.com/djcb/mu/pull/1442#issuecomment-591695814
|
2017-04-08 01:31:20 -04:00
|
|
|
|
;; configuration for sending mail
|
2017-04-17 02:17:10 -04:00
|
|
|
|
message-send-mail-function #'smtpmail-send-it
|
2017-04-08 01:31:20 -04:00
|
|
|
|
smtpmail-stream-type 'starttls
|
2018-01-24 15:08:43 -05:00
|
|
|
|
message-kill-buffer-on-exit t ; close after sending
|
2017-04-08 01:31:20 -04:00
|
|
|
|
;; start with the first (default) context;
|
|
|
|
|
mu4e-context-policy 'pick-first
|
|
|
|
|
;; compose with the current context, or ask
|
|
|
|
|
mu4e-compose-context-policy 'ask-if-none
|
2021-07-09 20:16:11 +03:00
|
|
|
|
;; use helm/ivy/vertico
|
2018-01-24 15:08:43 -05:00
|
|
|
|
mu4e-completing-read-function
|
2021-07-09 20:16:11 +03:00
|
|
|
|
(cond ((featurep! :completion ivy) #'ivy-completing-read)
|
|
|
|
|
((featurep! :completion helm) #'completing-read)
|
|
|
|
|
((featurep! :completion vertico) #'completing-read)
|
2018-01-24 15:08:43 -05:00
|
|
|
|
(t #'ido-completing-read))
|
2017-04-08 01:31:20 -04:00
|
|
|
|
;; no need to ask
|
2018-10-03 09:05:36 +13:00
|
|
|
|
mu4e-confirm-quit nil
|
2020-10-01 18:23:28 +08:00
|
|
|
|
mu4e-headers-thread-single-orphan-prefix '("─>" . "─▶")
|
|
|
|
|
mu4e-headers-thread-orphan-prefix '("┬>" . "┬▶ ")
|
|
|
|
|
mu4e-headers-thread-last-child-prefix '("└>" . "╰▶")
|
|
|
|
|
mu4e-headers-thread-child-prefix '("├>" . "├▶")
|
|
|
|
|
mu4e-headers-thread-connection-prefix '("│" . "│ ")
|
2017-04-09 17:42:17 -04:00
|
|
|
|
;; remove 'lists' column
|
2017-04-14 02:36:36 -04:00
|
|
|
|
mu4e-headers-fields
|
2020-10-14 17:28:10 +08:00
|
|
|
|
'((:account-stripe . 1)
|
2020-10-01 18:23:28 +08:00
|
|
|
|
(:human-date . 8)
|
|
|
|
|
(:flags . 6) ; 3 icon flags
|
2020-10-14 17:28:10 +08:00
|
|
|
|
(:from-or-to . 25)
|
2018-01-24 15:08:43 -05:00
|
|
|
|
(:subject)))
|
|
|
|
|
|
2019-01-21 16:10:27 -08:00
|
|
|
|
;; set mail user agent
|
2020-10-01 18:23:28 +08:00
|
|
|
|
(setq mail-user-agent 'mu4e-user-agent
|
|
|
|
|
message-mail-user-agent 'mu4e-user-agent)
|
2019-01-21 16:10:27 -08:00
|
|
|
|
|
2020-10-14 17:21:20 +08:00
|
|
|
|
;; Make reply coloring consistant, and striped for readability
|
2020-10-10 03:20:59 +08:00
|
|
|
|
(custom-set-faces!
|
|
|
|
|
'(gnus-cite-2 :foreground nil :inherit gnus-cite-10)
|
|
|
|
|
'(gnus-cite-3 :foreground nil :inherit gnus-cite-7)
|
|
|
|
|
'(message-cited-text-1 :foreground nil :inherit gnus-cite-1)
|
|
|
|
|
'(message-cited-text-2 :foreground nil :inherit gnus-cite-2)
|
|
|
|
|
'(message-cited-text-3 :foreground nil :inherit gnus-cite-3)
|
|
|
|
|
'(message-cited-text-4 :foreground nil :inherit gnus-cite-4))
|
|
|
|
|
|
2020-09-23 00:23:01 +08:00
|
|
|
|
;; Set the icons only when a graphical frame has been created
|
|
|
|
|
(if (display-graphic-p)
|
2020-10-13 16:41:33 +08:00
|
|
|
|
(+mu4e-initialise-icons)
|
2020-09-23 00:23:01 +08:00
|
|
|
|
;; When it's the server, wait till the first graphical frame
|
2020-10-15 22:30:46 +08:00
|
|
|
|
(add-hook
|
|
|
|
|
'server-after-make-frame-hook
|
|
|
|
|
(defun +mu4e-initialise-icons-hook ()
|
|
|
|
|
(when (display-graphic-p)
|
|
|
|
|
(+mu4e-initialise-icons)
|
|
|
|
|
(remove-hook 'server-after-make-frame-hook
|
|
|
|
|
#'+mu4e-initialise-icons-hook)))))
|
2017-04-18 21:04:25 -04:00
|
|
|
|
|
2020-09-25 16:37:11 +08:00
|
|
|
|
(plist-put (cdr (assoc :flags mu4e-header-info)) :shortname " Flags") ; default=Flgs
|
2020-10-01 18:23:28 +08:00
|
|
|
|
(add-to-list 'mu4e-bookmarks
|
2020-10-04 01:03:26 +08:00
|
|
|
|
'(:name "Flagged messages" :query "flag:flagged" :key ?f) t)
|
2020-09-23 01:02:40 +08:00
|
|
|
|
|
2020-10-14 17:28:10 +08:00
|
|
|
|
(setq +mu4e-header-colorized-faces
|
|
|
|
|
'(all-the-icons-green
|
|
|
|
|
all-the-icons-lblue
|
|
|
|
|
all-the-icons-purple-alt
|
|
|
|
|
all-the-icons-blue-alt
|
|
|
|
|
all-the-icons-purple
|
|
|
|
|
all-the-icons-yellow))
|
2020-10-04 01:00:01 +08:00
|
|
|
|
|
2020-10-14 17:28:10 +08:00
|
|
|
|
;; Add a column to display what email account the email belongs to,
|
|
|
|
|
;; and an account color stripe column
|
|
|
|
|
(defvar +mu4e-header--maildir-colors nil)
|
2020-09-23 01:22:29 +08:00
|
|
|
|
(setq mu4e-header-info-custom
|
|
|
|
|
'((:account .
|
2020-10-14 17:28:10 +08:00
|
|
|
|
(:name "Account"
|
|
|
|
|
:shortname "Account"
|
2020-10-22 00:23:25 +08:00
|
|
|
|
:help "which account/maildir this email belongs to"
|
2020-09-23 01:22:29 +08:00
|
|
|
|
:function
|
|
|
|
|
(lambda (msg)
|
2020-10-22 00:23:25 +08:00
|
|
|
|
(let ((maildir (replace-regexp-in-string
|
|
|
|
|
"\\`/?\\([^/]+\\)/.*\\'" "\\1"
|
|
|
|
|
(mu4e-message-field msg :maildir)))))
|
2020-10-14 17:28:10 +08:00
|
|
|
|
(+mu4e-colorize-str
|
|
|
|
|
(replace-regexp-in-string
|
|
|
|
|
"^gmail"
|
|
|
|
|
(propertize "g" 'face 'bold-italic)
|
2020-10-22 00:23:25 +08:00
|
|
|
|
maildir)
|
2020-10-14 17:28:10 +08:00
|
|
|
|
'+mu4e-header--maildir-colors
|
2020-10-22 00:23:25 +08:00
|
|
|
|
maildir))))
|
2020-10-14 17:28:10 +08:00
|
|
|
|
(:account-stripe .
|
|
|
|
|
(:name "Account"
|
|
|
|
|
:shortname "▐"
|
2020-10-22 00:23:25 +08:00
|
|
|
|
:help "Which account/maildir this email belongs to"
|
2020-10-14 17:28:10 +08:00
|
|
|
|
:function
|
|
|
|
|
(lambda (msg)
|
|
|
|
|
(let ((account
|
|
|
|
|
(replace-regexp-in-string
|
|
|
|
|
"\\`/?\\([^/]+\\)/.*\\'" "\\1"
|
|
|
|
|
(mu4e-message-field msg :maildir))))
|
|
|
|
|
(propertize
|
|
|
|
|
(+mu4e-colorize-str "▌" '+mu4e-header--maildir-colors account)
|
|
|
|
|
'help-echo account)))))
|
2020-09-23 01:22:29 +08:00
|
|
|
|
(:recipnum .
|
|
|
|
|
(:name "Number of recipients"
|
|
|
|
|
:shortname " ⭷"
|
|
|
|
|
:help "Number of recipients for this message"
|
|
|
|
|
:function
|
|
|
|
|
(lambda (msg)
|
|
|
|
|
(propertize (format "%2d"
|
|
|
|
|
(+ (length (mu4e-message-field msg :to))
|
|
|
|
|
(length (mu4e-message-field msg :cc))))
|
2020-09-25 16:37:11 +08:00
|
|
|
|
'face 'mu4e-footer-face))))))
|
2020-09-23 01:32:18 +08:00
|
|
|
|
|
|
|
|
|
;; Marks usually affect the current view
|
2019-07-23 17:24:56 +02:00
|
|
|
|
(defadvice! +mu4e--refresh-current-view-a (&rest _)
|
|
|
|
|
:after #'mu4e-mark-execute-all (mu4e-headers-rerun-search))
|
2017-04-18 21:04:25 -04:00
|
|
|
|
|
2017-04-09 22:10:41 -04:00
|
|
|
|
;; Wrap text in messages
|
2018-10-24 01:09:17 -04:00
|
|
|
|
(setq-hook! 'mu4e-view-mode-hook truncate-lines nil)
|
2017-04-08 01:31:20 -04:00
|
|
|
|
|
2020-05-03 18:05:31 +02:00
|
|
|
|
;; Html mails might be better rendered in a browser
|
|
|
|
|
(add-to-list 'mu4e-view-actions '("View in browser" . mu4e-action-view-in-browser))
|
2020-10-22 00:24:26 +08:00
|
|
|
|
(when (fboundp 'make-xwidget)
|
|
|
|
|
(add-to-list 'mu4e-view-actions '("xwidgets view" . mu4e-action-view-with-xwidget)))
|
2020-05-03 18:05:31 +02:00
|
|
|
|
|
2020-09-23 01:32:18 +08:00
|
|
|
|
;; The header view needs a certain amount of horizontal space to
|
|
|
|
|
;; actually show you all the information you want to see
|
|
|
|
|
;; so if the header view is entered from a narrow frame,
|
|
|
|
|
;; it's probably worth trying to expand it
|
2020-10-15 22:30:23 +08:00
|
|
|
|
(defvar +mu4e-min-header-frame-width 120
|
2020-09-23 01:32:18 +08:00
|
|
|
|
"Minimum reasonable with for the header view.")
|
|
|
|
|
(defun mu4e-widen-frame-maybe ()
|
2020-10-15 22:30:23 +08:00
|
|
|
|
"Expand the frame with if it's less than `+mu4e-min-header-frame-width'."
|
|
|
|
|
(when (< (frame-width) +mu4e-min-header-frame-width)
|
|
|
|
|
(set-frame-width (selected-frame) +mu4e-min-header-frame-width)))
|
2020-09-23 01:32:18 +08:00
|
|
|
|
(add-hook 'mu4e-headers-mode-hook #'mu4e-widen-frame-maybe)
|
|
|
|
|
|
2017-04-08 01:31:20 -04:00
|
|
|
|
(when (fboundp 'imagemagick-register-types)
|
2017-04-19 13:18:03 -04:00
|
|
|
|
(imagemagick-register-types))
|
2020-09-23 01:52:38 +08:00
|
|
|
|
|
2020-10-04 01:03:26 +08:00
|
|
|
|
(map! :map mu4e-main-mode-map
|
|
|
|
|
:ne "h" #'+workspace/other)
|
|
|
|
|
|
2020-09-23 01:52:38 +08:00
|
|
|
|
(map! :map mu4e-headers-mode-map
|
2020-10-31 19:04:29 +08:00
|
|
|
|
:vne "l" #'+mu4e/capture-msg-to-agenda)
|
2020-09-23 01:52:38 +08:00
|
|
|
|
|
2019-10-21 02:01:37 +02:00
|
|
|
|
(map! :localleader
|
|
|
|
|
:map mu4e-compose-mode-map
|
|
|
|
|
:desc "send and exit" "s" #'message-send-and-exit
|
|
|
|
|
:desc "kill buffer" "d" #'message-kill-buffer
|
|
|
|
|
:desc "save draft" "S" #'message-dont-send
|
2020-09-23 01:35:59 +08:00
|
|
|
|
:desc "attach" "a" #'mail-add-attachment)
|
2020-09-23 13:00:33 +08:00
|
|
|
|
|
2020-09-23 01:35:59 +08:00
|
|
|
|
;; Due to evil, none of the marking commands work when making a visual selection in
|
|
|
|
|
;; the headers view of mu4e. Without overriding any evil commands we may actually
|
|
|
|
|
;; want to use in and evil selection, this can be easily fixed.
|
|
|
|
|
(when (featurep! :editor evil)
|
|
|
|
|
(map! :map mu4e-headers-mode-map
|
|
|
|
|
:v "*" #'mu4e-headers-mark-for-something
|
|
|
|
|
:v "!" #'mu4e-headers-mark-for-read
|
|
|
|
|
:v "?" #'mu4e-headers-mark-for-unread
|
2020-10-14 14:15:24 +08:00
|
|
|
|
:v "u" #'mu4e-headers-mark-for-unmark))
|
2020-09-23 01:53:19 +08:00
|
|
|
|
|
2020-10-14 15:37:15 +08:00
|
|
|
|
(add-hook 'mu4e-compose-pre-hook '+mu4e-set-from-address-h)
|
2020-09-23 01:55:37 +08:00
|
|
|
|
|
2020-10-14 15:37:15 +08:00
|
|
|
|
(advice-add #'mu4e~main-action-str :override #'+mu4e~main-action-str-prettier-a)
|
2020-10-04 01:03:26 +08:00
|
|
|
|
(when (featurep! :editor evil)
|
2020-10-13 16:41:33 +08:00
|
|
|
|
;; As +mu4e~main-action-str-prettier replaces [k]ey with key q]uit should become quit
|
2020-10-13 17:21:52 +08:00
|
|
|
|
(setq evil-collection-mu4e-end-region-misc "quit"))
|
|
|
|
|
|
|
|
|
|
;; process lock control
|
|
|
|
|
(when IS-WINDOWS
|
2020-10-14 15:00:57 +08:00
|
|
|
|
(setq
|
|
|
|
|
+mu4e-lock-file (expand-file-name "~/AppData/Local/Temp/mu4e_lock")
|
|
|
|
|
+mu4e-lock-request-file (expand-file-name "~/AppData/Local/Temp/mu4e_lock_request")))
|
2020-10-13 17:21:52 +08:00
|
|
|
|
|
|
|
|
|
(add-hook 'kill-emacs-hook #'+mu4e-lock-file-delete-maybe)
|
|
|
|
|
(advice-add 'mu4e~start :around #'+mu4e-lock-start)
|
|
|
|
|
(advice-add 'mu4e-quit :after #'+mu4e-lock-file-delete-maybe))
|
2017-04-08 01:31:20 -04:00
|
|
|
|
|
2020-10-31 19:12:40 +08:00
|
|
|
|
(unless (featurep! +org)
|
|
|
|
|
(after! mu4e
|
|
|
|
|
(defun org-msg-mode (&optional _)
|
|
|
|
|
"Dummy function."
|
|
|
|
|
(message "Enable the +org mu4e flag to use org-msg-mode."))))
|
|
|
|
|
|
2020-10-01 01:56:45 +08:00
|
|
|
|
(use-package! org-msg
|
2020-10-01 16:38:55 +08:00
|
|
|
|
:after mu4e
|
2020-10-14 13:01:46 +08:00
|
|
|
|
:when (featurep! +org)
|
2020-10-01 01:56:45 +08:00
|
|
|
|
:config
|
2020-10-13 14:52:31 +08:00
|
|
|
|
(setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil tex:dvipng"
|
2020-10-01 01:56:45 +08:00
|
|
|
|
org-msg-startup "hidestars indent inlineimages"
|
|
|
|
|
org-msg-greeting-name-limit 3
|
|
|
|
|
org-msg-text-plain-alternative t)
|
2017-04-16 21:24:18 -04:00
|
|
|
|
|
2020-10-13 16:41:33 +08:00
|
|
|
|
(defvar +org-msg-currently-exporting nil
|
2020-10-01 01:56:45 +08:00
|
|
|
|
"Helper variable to indicate whether org-msg is currently exporting the org buffer to HTML.
|
2020-09-23 13:08:57 +08:00
|
|
|
|
Usefull for affecting HTML export config.")
|
2020-10-13 16:41:33 +08:00
|
|
|
|
(defadvice! +org-msg--now-exporting (&rest _)
|
2020-10-01 01:56:45 +08:00
|
|
|
|
:before #'org-msg-org-to-xml
|
2020-10-13 16:41:33 +08:00
|
|
|
|
(setq +org-msg-currently-exporting t))
|
|
|
|
|
(defadvice! +org-msg--not-exporting (&rest _)
|
2020-10-01 01:56:45 +08:00
|
|
|
|
:after #'org-msg-org-to-xml
|
2020-10-13 16:41:33 +08:00
|
|
|
|
(setq +org-msg-currently-exporting nil))
|
2020-09-23 13:08:57 +08:00
|
|
|
|
|
2020-10-14 15:37:15 +08:00
|
|
|
|
(advice-add #'org-html-latex-fragment :override #'+org-html-latex-fragment-scaled-a)
|
|
|
|
|
(advice-add #'org-html-latex-environment :override #'+org-html-latex-environment-scaled-a)
|
2020-10-01 01:52:58 +08:00
|
|
|
|
|
2020-10-13 16:41:33 +08:00
|
|
|
|
(defvar +mu4e-compose-org-msg-toggle-next t ; t to initialise org-msg
|
2020-10-01 01:56:45 +08:00
|
|
|
|
"Whether to toggle ")
|
|
|
|
|
(defun mu4e-compose-org-msg-handle-toggle (toggle-p)
|
2020-10-13 16:41:33 +08:00
|
|
|
|
(when (xor toggle-p +mu4e-compose-org-msg-toggle-next)
|
2020-10-01 01:56:45 +08:00
|
|
|
|
(org-msg-mode (if org-msg-mode -1 1))
|
2020-10-13 16:41:33 +08:00
|
|
|
|
(setq +mu4e-compose-org-msg-toggle-next
|
|
|
|
|
(not +mu4e-compose-org-msg-toggle-next))))
|
2020-10-01 01:52:58 +08:00
|
|
|
|
|
2020-10-31 19:09:45 +08:00
|
|
|
|
(defadvice! mu4e-maybe-toggle-org-msg (orig-fn &optional toggle-p)
|
2020-10-01 01:56:45 +08:00
|
|
|
|
:around #'mu4e-compose-new
|
|
|
|
|
:around #'mu4e-compose-reply
|
2020-10-31 19:11:57 +08:00
|
|
|
|
:around #'mu4e-compose-forward
|
|
|
|
|
:around #'mu4e-compose-resend
|
2020-10-01 01:56:45 +08:00
|
|
|
|
(interactive "p")
|
2020-10-31 19:09:45 +08:00
|
|
|
|
(mu4e-compose-org-msg-handle-toggle (/= 1 (or toggle-p 0)))
|
2020-10-01 01:56:45 +08:00
|
|
|
|
(funcall orig-fn))
|
2020-10-01 01:52:58 +08:00
|
|
|
|
|
2020-10-01 01:56:45 +08:00
|
|
|
|
(defvar +org-msg-accent-color "#c01c28"
|
|
|
|
|
"Accent color to use in org-msg's generated CSS.
|
2020-10-01 01:52:58 +08:00
|
|
|
|
Must be set before org-msg is loaded to take effect.")
|
2020-10-01 01:56:45 +08:00
|
|
|
|
(setq org-msg-enforce-css
|
|
|
|
|
(let* ((font-family '(font-family . "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell,\
|
2020-09-23 13:08:57 +08:00
|
|
|
|
\"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";"))
|
2020-10-01 01:56:45 +08:00
|
|
|
|
(monospace-font '(font-family . "SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;"))
|
|
|
|
|
(font-size '(font-size . "11pt"))
|
|
|
|
|
(font `(,font-family ,font-size))
|
|
|
|
|
(line-height '(line-height . "1.2"))
|
|
|
|
|
(theme-color +org-msg-accent-color)
|
|
|
|
|
(bold '(font-weight . "bold"))
|
|
|
|
|
(color `(color . ,theme-color))
|
|
|
|
|
(table `((margin-top . "6px") (margin-bottom . "6px")
|
|
|
|
|
(border-left . "none") (border-right . "none")
|
|
|
|
|
(border-top . "2px solid #222222")
|
|
|
|
|
(border-bottom . "2px solid #222222")
|
|
|
|
|
))
|
|
|
|
|
(ftl-number `(,color ,bold (text-align . "left")))
|
|
|
|
|
(inline-modes '(asl c c++ conf cpp csv diff ditaa emacs-lisp
|
|
|
|
|
fundamental ini json makefile man org plantuml
|
|
|
|
|
python sh xml))
|
|
|
|
|
(inline-src `((background-color . "rgba(27,31,35,.05)")
|
|
|
|
|
(border-radius . "3px")
|
|
|
|
|
(padding . ".2em .4em")
|
|
|
|
|
(font-size . "90%") ,monospace-font
|
|
|
|
|
(margin . 0)))
|
|
|
|
|
(code-src
|
|
|
|
|
(mapcar (lambda (mode)
|
|
|
|
|
`(code ,(intern (concat "src src-" (symbol-name mode)))
|
|
|
|
|
,inline-src))
|
|
|
|
|
inline-modes)))
|
|
|
|
|
`((del nil ((color . "grey") (border-left . "none")
|
|
|
|
|
(text-decoration . "line-through") (margin-bottom . "0px")
|
|
|
|
|
(margin-top . "10px") (line-height . "11pt")))
|
|
|
|
|
(a nil (,color))
|
|
|
|
|
(a reply-header ((color . "black") (text-decoration . "none")))
|
|
|
|
|
(div reply-header ((padding . "3.0pt 0in 0in 0in")
|
|
|
|
|
(border-top . "solid #e1e1e1 1.0pt")
|
|
|
|
|
(margin-bottom . "20px")))
|
|
|
|
|
(span underline ((text-decoration . "underline")))
|
|
|
|
|
(li nil (,line-height (margin-bottom . "0px")
|
|
|
|
|
(margin-top . "2px")))
|
|
|
|
|
(nil org-ul ((list-style-type . "square")))
|
|
|
|
|
(nil org-ol (,@font ,line-height (margin-bottom . "0px")
|
|
|
|
|
(margin-top . "0px") (margin-left . "30px")
|
|
|
|
|
(padding-top . "0px") (padding-left . "5px")))
|
|
|
|
|
(nil signature (,@font (margin-bottom . "20px")))
|
|
|
|
|
(blockquote nil ((padding . "2px 12px") (margin-left . "10px")
|
|
|
|
|
(margin-top . "10px") (margin-bottom . "0")
|
|
|
|
|
(border-left . "3px solid #ccc")
|
|
|
|
|
(font-style . "italic")
|
|
|
|
|
(background . "#f9f9f9")))
|
|
|
|
|
(p blockquote ((margin . "0") (padding . "4px 0")))
|
|
|
|
|
(code nil (,font-size ,monospace-font (background . "#f9f9f9")))
|
|
|
|
|
,@code-src
|
|
|
|
|
(nil linenr ((padding-right . "1em")
|
|
|
|
|
(color . "black")
|
|
|
|
|
(background-color . "#aaaaaa")))
|
|
|
|
|
(pre nil ((line-height . "1.2")
|
|
|
|
|
(color . ,(doom-color 'fg))
|
|
|
|
|
(background-color . ,(doom-color 'bg))
|
|
|
|
|
(margin . "4px 0px 8px 0px")
|
|
|
|
|
(padding . "8px 12px")
|
2020-10-13 14:55:02 +08:00
|
|
|
|
(width . "max-content")
|
|
|
|
|
(min-width . "80ch")
|
2020-10-01 01:56:45 +08:00
|
|
|
|
(border-radius . "5px")
|
|
|
|
|
(font-weight . "500")
|
|
|
|
|
,monospace-font))
|
|
|
|
|
(div org-src-container ((margin-top . "10px")))
|
|
|
|
|
(nil figure-number ,ftl-number)
|
|
|
|
|
(nil table-number)
|
|
|
|
|
(caption nil ((text-align . "left")
|
|
|
|
|
(background . ,theme-color)
|
|
|
|
|
(color . "white")
|
|
|
|
|
,bold))
|
|
|
|
|
(nil t-above ((caption-side . "top")))
|
|
|
|
|
(nil t-bottom ((caption-side . "bottom")))
|
|
|
|
|
(nil listing-number ,ftl-number)
|
|
|
|
|
(nil figure ,ftl-number)
|
|
|
|
|
(nil org-src-name ,ftl-number)
|
|
|
|
|
(img nil ((vertical-align . "middle")
|
|
|
|
|
(max-width . "100%")))
|
|
|
|
|
(img latex-fragment-inline ((margin . "0 0.1em")))
|
|
|
|
|
(table nil (,@table ,line-height (border-collapse . "collapse")))
|
|
|
|
|
(th nil ((border . "none") (border-bottom . "1px solid #222222")
|
|
|
|
|
(background-color . "#EDEDED") (font-weight . "500")
|
|
|
|
|
(padding . "3px 10px")))
|
|
|
|
|
(td nil (,@table (padding . "1px 10px")
|
|
|
|
|
(background-color . "#f9f9f9") (border . "none")))
|
|
|
|
|
(td org-left ((text-align . "left")))
|
|
|
|
|
(td org-right ((text-align . "right")))
|
|
|
|
|
(td org-center ((text-align . "center")))
|
|
|
|
|
(kbd nil ((border . "1px solid #d1d5da") (border-radius . "3px")
|
|
|
|
|
(box-shadow . "inset 0 -1px 0 #d1d5da")
|
|
|
|
|
(background-color . "#fafbfc") (color . "#444d56")
|
|
|
|
|
(padding . "3px 5px") (display . "inline-block")))
|
|
|
|
|
(div outline-text-4 ((margin-left . "15px")))
|
|
|
|
|
(div outline-4 ((margin-left . "10px")))
|
|
|
|
|
(h4 nil ((margin-bottom . "0px") (font-size . "11pt")))
|
|
|
|
|
(h3 nil ((margin-bottom . "0px")
|
|
|
|
|
,color (font-size . "14pt")))
|
|
|
|
|
(h2 nil ((margin-top . "20px") (margin-bottom . "20px")
|
|
|
|
|
,color (font-size . "18pt")))
|
|
|
|
|
(h1 nil ((margin-top . "20px") (margin-bottom . "0px")
|
|
|
|
|
,color (font-size . "24pt")))
|
2020-10-13 14:55:02 +08:00
|
|
|
|
(p nil ((text-decoration . "none") (line-height . "1.4")
|
2020-10-01 01:56:45 +08:00
|
|
|
|
(margin-top . "10px") (margin-bottom . "0px")
|
2020-10-13 14:55:02 +08:00
|
|
|
|
,font-size (max-width . "90ch")))
|
2020-10-01 01:56:45 +08:00
|
|
|
|
(b nil ((font-weight . "500") (color . ,theme-color)))
|
|
|
|
|
(div nil (,@font (line-height . "12pt")))))))
|
2017-04-08 01:31:20 -04:00
|
|
|
|
|
2018-01-24 15:08:43 -05:00
|
|
|
|
|
|
|
|
|
;;
|
2019-05-05 14:11:59 -04:00
|
|
|
|
;;; Gmail integration
|
|
|
|
|
|
|
|
|
|
(when (featurep! +gmail)
|
|
|
|
|
(after! mu4e
|
2020-10-13 23:36:55 +08:00
|
|
|
|
(defvar +mu4e-gmail-addresses nil
|
|
|
|
|
"A list of email addresses which, despite not:
|
|
|
|
|
- having '@gmail.com' in them, or
|
|
|
|
|
- being in a maildir where the name includes 'gmail'
|
|
|
|
|
|
|
|
|
|
Should be treated as a gmail address.")
|
|
|
|
|
|
2019-05-05 14:11:59 -04:00
|
|
|
|
;; don't save message to Sent Messages, Gmail/IMAP takes care of this
|
2020-10-01 19:16:33 +08:00
|
|
|
|
(setq mu4e-sent-messages-behavior
|
2020-10-13 16:41:33 +08:00
|
|
|
|
(lambda () ;; TODO make use +mu4e-msg-gmail-p
|
2020-10-13 23:36:55 +08:00
|
|
|
|
(if (or (string-match-p "@gmail.com\\'" (message-sendmail-envelope-from))
|
|
|
|
|
(member (message-sendmail-envelope-from) +mu4e-gmail-addresses))
|
2020-10-01 19:16:33 +08:00
|
|
|
|
'delete 'sent))
|
2019-05-05 14:11:59 -04:00
|
|
|
|
|
|
|
|
|
;; don't need to run cleanup after indexing for gmail
|
|
|
|
|
mu4e-index-cleanup nil
|
|
|
|
|
|
|
|
|
|
;; because gmail uses labels as folders we can use lazy check since
|
|
|
|
|
;; messages don't really "move"
|
|
|
|
|
mu4e-index-lazy-check t)
|
|
|
|
|
|
2020-10-01 19:16:33 +08:00
|
|
|
|
(defun +mu4e-msg-gmail-p (msg)
|
|
|
|
|
(or
|
2020-10-13 16:30:54 +08:00
|
|
|
|
(string-match-p "@gmail.com"
|
2020-10-01 19:16:33 +08:00
|
|
|
|
(cond
|
|
|
|
|
((member (mu4e-message-field msg :to)
|
2020-10-13 23:36:55 +08:00
|
|
|
|
(append (mu4e-personal-addresses)
|
|
|
|
|
+mu4e-gmail-addresses))
|
2020-10-01 19:16:33 +08:00
|
|
|
|
(mu4e-message-field msg :to))
|
|
|
|
|
((member (mu4e-message-field msg :from)
|
2020-10-13 23:36:55 +08:00
|
|
|
|
(append (mu4e-personal-addresses)
|
|
|
|
|
+mu4e-gmail-addresses))
|
2020-10-01 19:16:33 +08:00
|
|
|
|
(mu4e-message-field msg :from))
|
|
|
|
|
(t "")))
|
|
|
|
|
(string-match-p "gmail" (mu4e-message-field msg :maildir))))
|
|
|
|
|
|
2019-05-05 14:11:59 -04:00
|
|
|
|
;; In my workflow, emails won't be moved at all. Only their flags/labels are
|
|
|
|
|
;; changed. Se we redefine the trash and refile marks not to do any moving.
|
|
|
|
|
;; However, the real magic happens in `+mu4e|gmail-fix-flags'.
|
|
|
|
|
;;
|
|
|
|
|
;; Gmail will handle the rest.
|
|
|
|
|
(defun +mu4e--mark-seen (docid _msg target)
|
|
|
|
|
(mu4e~proc-move docid (mu4e~mark-check-target target) "+S-u-N"))
|
|
|
|
|
|
2020-10-01 19:16:33 +08:00
|
|
|
|
(defvar +mu4e--last-invalid-gmail-action 0)
|
|
|
|
|
|
2019-07-23 12:30:47 +02:00
|
|
|
|
(delq! 'delete mu4e-marks #'assq)
|
2020-10-01 19:16:33 +08:00
|
|
|
|
(setf (alist-get 'delete mu4e-marks)
|
|
|
|
|
(list
|
|
|
|
|
:char '("D" . "✘")
|
|
|
|
|
:prompt "Delete"
|
2020-10-31 19:12:24 +08:00
|
|
|
|
:show-target (lambda (_target) "delete")
|
2020-10-01 19:16:33 +08:00
|
|
|
|
:action (lambda (docid msg target)
|
|
|
|
|
(if (+mu4e-msg-gmail-p msg)
|
2020-10-02 11:53:58 +08:00
|
|
|
|
(progn (message "The delete operation is invalid for Gmail accounts. Trashing instead.")
|
|
|
|
|
(+mu4e--mark-seen docid msg target)
|
2020-10-01 19:16:33 +08:00
|
|
|
|
(when (< 2 (- (float-time) +mu4e--last-invalid-gmail-action))
|
|
|
|
|
(sit-for 1))
|
|
|
|
|
(setq +mu4e--last-invalid-gmail-action (float-time)))
|
|
|
|
|
(mu4e~proc-remove docid))))
|
|
|
|
|
(alist-get 'trash mu4e-marks)
|
2019-05-05 14:11:59 -04:00
|
|
|
|
(list :char '("d" . "▼")
|
|
|
|
|
:prompt "dtrash"
|
|
|
|
|
:dyn-target (lambda (_target msg) (mu4e-get-trash-folder msg))
|
2020-10-01 19:16:33 +08:00
|
|
|
|
:action (lambda (docid msg target)
|
|
|
|
|
(if (+mu4e-msg-gmail-p msg)
|
|
|
|
|
(+mu4e--mark-seen docid msg target)
|
|
|
|
|
(mu4e~proc-move docid (mu4e~mark-check-target target) "+T-N"))))
|
2019-05-05 14:11:59 -04:00
|
|
|
|
;; Refile will be my "archive" function.
|
|
|
|
|
(alist-get 'refile mu4e-marks)
|
2019-11-30 22:26:27 +08:00
|
|
|
|
(list :char '("r" . "▼")
|
|
|
|
|
:prompt "rrefile"
|
|
|
|
|
:dyn-target (lambda (_target msg) (mu4e-get-refile-folder msg))
|
2020-10-01 19:16:33 +08:00
|
|
|
|
:action (lambda (docid msg target)
|
|
|
|
|
(if (+mu4e-msg-gmail-p msg)
|
|
|
|
|
(+mu4e--mark-seen docid msg target)
|
|
|
|
|
(mu4e~proc-move docid (mu4e~mark-check-target target) "-N")))
|
|
|
|
|
#'+mu4e--mark-seen))
|
2019-05-05 14:11:59 -04:00
|
|
|
|
|
|
|
|
|
;; This hook correctly modifies gmail flags on emails when they are marked.
|
|
|
|
|
;; Without it, refiling (archiving), trashing, and flagging (starring) email
|
|
|
|
|
;; won't properly result in the corresponding gmail action, since the marks
|
|
|
|
|
;; are ineffectual otherwise.
|
2019-07-26 19:57:13 +02:00
|
|
|
|
(add-hook! 'mu4e-mark-execute-pre-hook
|
2019-07-23 12:30:47 +02:00
|
|
|
|
(defun +mu4e-gmail-fix-flags-h (mark msg)
|
2020-10-01 19:16:33 +08:00
|
|
|
|
(when (+mu4e-msg-gmail-p msg)
|
|
|
|
|
(pcase mark
|
|
|
|
|
(`trash (mu4e-action-retag-message msg "-\\Inbox,+\\Trash,-\\Draft"))
|
2020-10-02 11:53:58 +08:00
|
|
|
|
(`delete (mu4e-action-retag-message msg "-\\Inbox,+\\Trash,-\\Draft"))
|
2020-10-01 19:16:33 +08:00
|
|
|
|
(`refile (mu4e-action-retag-message msg "-\\Inbox"))
|
|
|
|
|
(`flag (mu4e-action-retag-message msg "+\\Starred"))
|
|
|
|
|
(`unflag (mu4e-action-retag-message msg "-\\Starred"))))))))
|
2020-10-10 03:28:58 +08:00
|
|
|
|
|
|
|
|
|
;;
|
|
|
|
|
;;; Alerts
|
|
|
|
|
|
|
|
|
|
(use-package! mu4e-alert
|
|
|
|
|
:after mu4e
|
|
|
|
|
:config
|
|
|
|
|
(setq doom-modeline-mu4e t)
|
|
|
|
|
|
|
|
|
|
(mu4e-alert-enable-mode-line-display)
|
|
|
|
|
(mu4e-alert-enable-notifications)
|
|
|
|
|
|
|
|
|
|
(when IS-LINUX
|
|
|
|
|
(mu4e-alert-set-default-style 'libnotify)
|
|
|
|
|
|
|
|
|
|
(setq mu4e-alert-email-notification-types '(subjects))
|
2020-10-31 19:12:24 +08:00
|
|
|
|
(defun +mu4e-alert-grouped-mail-notification-formatter-with-bell (mail-group _all-mails)
|
2020-10-10 03:28:58 +08:00
|
|
|
|
"Default function to format MAIL-GROUP for notification.
|
|
|
|
|
ALL-MAILS are the all the unread emails"
|
|
|
|
|
(shell-command "paplay /usr/share/sounds/freedesktop/stereo/message.oga")
|
|
|
|
|
(if (> (length mail-group) 1)
|
|
|
|
|
(let* ((mail-count (length mail-group))
|
|
|
|
|
(first-mail (car mail-group))
|
|
|
|
|
(title-prefix (format "You have %d unread emails"
|
|
|
|
|
mail-count))
|
|
|
|
|
(field-value (mu4e-alert--get-group first-mail))
|
|
|
|
|
(title-suffix (format (pcase mu4e-alert-group-by
|
|
|
|
|
(`:from "from %s:")
|
|
|
|
|
(`:to "to %s:")
|
|
|
|
|
(`:maildir "in %s:")
|
|
|
|
|
(`:priority "with %s priority:")
|
|
|
|
|
(`:flags "with %s flags:"))
|
|
|
|
|
field-value))
|
|
|
|
|
(title (format "%s %s" title-prefix title-suffix)))
|
|
|
|
|
(list :title title
|
|
|
|
|
:body (s-join "\n"
|
|
|
|
|
(mapcar (lambda (mail)
|
|
|
|
|
(format "%s<b>%s</b> • %s"
|
|
|
|
|
(cond
|
|
|
|
|
((plist-get mail :in-reply-to) "⮩ ")
|
|
|
|
|
((string-match-p "\\`Fwd:"
|
|
|
|
|
(plist-get mail :subject)) " ⮯ ")
|
|
|
|
|
(t " "))
|
|
|
|
|
(truncate-string-to-width (caar (plist-get mail :from))
|
|
|
|
|
20 nil nil t)
|
|
|
|
|
(truncate-string-to-width
|
|
|
|
|
(replace-regexp-in-string "\\`Re: \\|\\`Fwd: " ""
|
|
|
|
|
(plist-get mail :subject))
|
|
|
|
|
40 nil nil t)))
|
|
|
|
|
mail-group))))
|
|
|
|
|
(let* ((new-mail (car mail-group))
|
|
|
|
|
(subject (plist-get new-mail :subject))
|
|
|
|
|
(sender (caar (plist-get new-mail :from))))
|
|
|
|
|
(list :title sender :body subject))))
|
2020-10-13 16:41:33 +08:00
|
|
|
|
(setq mu4e-alert-grouped-mail-notification-formatter #'+mu4e-alert-grouped-mail-notification-formatter-with-bell))
|
2020-10-10 03:28:58 +08:00
|
|
|
|
|
|
|
|
|
(mu4e-alert-enable-mode-line-display))
|