diff options
Diffstat (limited to '_spacemacs.d/config/my-mu4e.el')
-rw-r--r-- | _spacemacs.d/config/my-mu4e.el | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/_spacemacs.d/config/my-mu4e.el b/_spacemacs.d/config/my-mu4e.el new file mode 100644 index 0000000..6aa2f0d --- /dev/null +++ b/_spacemacs.d/config/my-mu4e.el @@ -0,0 +1,353 @@ +;;; my-mu4e.el --- mu4e (mu for Emacs) configurations +;; -*- mode: emacs-lisp -*- +;; vim: set ts=8 sw=2 tw=0 fenc=utf-8 ft=lisp: +;; +;; Aaron LI +;; Created: 2016-02-21 +;; Updated: 2016-09-03 +;; + +;;; Commentary: +;; mu4e (mu for Emacs) configurations for spacemacs. +;; mu (maildir indexer/searcher): https://github.com/djcb/mu +;; + +;;; Code: + +;; maildir location +(setq mu4e-maildir "~/mail") + +;; turn on debug: log debug information to the *mu4e-log* buffer +(setq mu4e-debug t) + +(with-eval-after-load 'mu4e + ;; speed up indexing + (setq mu4e-index-cleanup nil) ; don't do a full cleanup check + (setq mu4e-index-lazy-check t) ; don't consider up-to-date directories + + ;; multiple email accounts: contexts (require mu4e >= 0.9.16) + (setq mu4e-contexts + `( ,(make-mu4e-context + :name "Outlook-aly" + :enter-func (lambda () + (mu4e-message "Switched to context: outlook-aly")) + ;; `leave-func' not defined + ;; `match-func' is invoked just before `mu4e-compose-pre-hook' + :match-func (lambda (msg) + (when msg + (mu4e-message-contact-field-matches msg + :to "aaronly.me@outlook.com"))) + :vars '((user-mail-address . "aaronly.me@outlook.com") + (user-full-name . "Aaron LI") + (mu4e-sent-folder . "/outlook-aly/sent") + (mu4e-drafts-folder . "/outlook-aly/drafts") + (mu4e-trash-folder . "/outlook-aly/trash") + (mu4e-refile-folder . "/outlook-aly/archive") + (mu4e-compose-signature . "Aly") + (mu4e-sent-messages-behavior . delete))) + ,(make-mu4e-context + :name "Gmail-aly" + :enter-func (lambda () + (mu4e-message "Switched to context: gmail-aly")) + ;; `leave-func' not defined + :match-func (lambda (msg) + (when msg + (mu4e-message-contact-field-matches msg + :to "aaronly.me@gmail.com"))) + :vars '((user-mail-address . "aaronly.me@gmail.com") + (user-full-name . "Aaron LI") + ;; special folders + (mu4e-sent-folder . "/sent") + (mu4e-drafts-folder . "/gmail-aly/drafts") + (mu4e-trash-folder . "/gmail-aly/trash") + (mu4e-refile-folder . "/gmail-aly/archive") + (mu4e-compose-signature . "Aly") + ;; do NOT save message to 'sent-folder' + (mu4e-sent-messages-behavior . delete))) + ,(make-mu4e-context + :name "outlook-li" + :enter-func (lambda () + (mu4e-message "Switched to context: outlook-li")) + ;; `leave-func' not defined + :match-func (lambda (msg) + (when msg + (mu4e-message-contact-field-matches msg + :to '("liweitianux@live.com" + "liweitianux@outlook.com")))) + :vars '((user-mail-address . "liweitianux@live.com") + (user-full-name . "Weitian LI") + (mu4e-sent-folder . "/outlook-li/sent") + (mu4e-drafts-folder . "/outlook-li/drafts") + (mu4e-trash-folder . "/outlook-li/trash") + (mu4e-refile-folder . "/outlook-li/archive") + (mu4e-compose-signature . "Weitian") + (mu4e-sent-messages-behavior . delete))) + ,(make-mu4e-context + :name "gmail-li" + :enter-func (lambda () + (mu4e-message "Switched to context: gmail-li")) + ;; `leave-func' not defined + :match-func (lambda (msg) + (when msg + (mu4e-message-contact-field-matches msg + :to "liweitianux@gmail.com"))) + :vars '((user-mail-address . "liweitianux@gmail.com") + (user-full-name . "Weitian LI") + (mu4e-sent-folder . "/sent") + (mu4e-drafts-folder . "/gmail-li/drafts") + (mu4e-trash-folder . "/gmail-li/trash") + (mu4e-refile-folder . "/gmail-li/archive") + (mu4e-compose-signature . "Weitian") + (mu4e-sent-messages-behavior . delete))) + ,(make-mu4e-context + :name "sjtu" + :enter-func (lambda () + (mu4e-message "Switched to context: sjtu")) + ;; `leave-func' not defined + :match-func (lambda (msg) + (when msg + (mu4e-message-contact-field-matches msg + :to "liweitianux@sjtu.edu.cn"))) + :vars '((user-mail-address . "liweitianux@sjtu.edu.cn") + (user-full-name . "Weitian LI") + (mu4e-sent-folder . "/sjtu/sent") + (mu4e-drafts-folder . "/sjtu/drafts") + (mu4e-trash-folder . "/sjtu/trash") + (mu4e-refile-folder . "/sjtu/archive") + (mu4e-compose-signature . + (concat "Weitian LI\n" + "Shanghai Jiao Tong University")) + ;; copy message to sent folder + (mu4e-sent-messages-behavior . sent))) + ,(make-mu4e-context + :name "autistici" + :enter-func (lambda () + (mu4e-message "Switched to context: autistici")) + ;; `leave-func' not defined + :match-func (lambda (msg) + (when msg + (mu4e-message-contact-field-matches msg + :to "liweitianux@autistici.org"))) + :vars '((user-mail-address . "liweitianux@autistici.org") + (user-full-name . "Weitian LI") + (mu4e-sent-folder . "/autistici/sent") + (mu4e-drafts-folder . "/autistici/drafts") + (mu4e-trash-folder . "/autistici/trash") + (mu4e-refile-folder . "/autistici/archive") + (mu4e-compose-signature . "Weitian") + ;; copy message to sent folder + (mu4e-sent-messages-behavior . sent))) + ,(make-mu4e-context + :name "foxmail" + :enter-func (lambda () + (mu4e-message "Switched to context: foxmail")) + ;; `leave-func' not defined + :match-func (lambda (msg) + (when msg + (mu4e-message-contact-field-matches msg + :to '("liweitianux@foxmail.com" + "527922216@qq.com")))) + :vars '((user-mail-address . "liweitianux@foxmail.com") + (user-full-name . "Weitian LI") + (mu4e-sent-folder . "/foxmail/sent") + (mu4e-drafts-folder . "/foxmail/drafts") + (mu4e-trash-folder . "/foxmail/trash") + (mu4e-refile-folder . "/foxmail/archive") + (mu4e-compose-signature . "Weitian") + (mu4e-sent-messages-behavior . delete))))) + + ;; start with the first (default) context + ;; default: `ask-if-none' (ask when there's no context yet, and none match) + (setq mu4e-context-policy 'pick-first) + ;; compose with the current context if no context matches + ;; default: `ask' + ;(setq mu4e-compose-context-policy nil) + + ;; auto construct addresses list by extracting addresses from contexts + (setq mu4e-user-mail-address-list + (delq nil + (mapcar (lambda (context) + (when (mu4e-context-vars context) + (cdr (assq 'user-mail-address + (mu4e-context-vars context))))) + mu4e-contexts))) + + ;; send mail using `msmtp' + (setq message-send-mail-function 'message-send-mail-with-sendmail + message-sendmail-f-is-evil t + ;; choose the account according to the `From' header + message-sendmail-extra-arguments '("--read-envelope-from") + sendmail-program "msmtp") + + ;; allow for fetch mail and update index using 'U' in the main view + (setq mu4e-get-mail-command "mbsync -a") + ;; get mail and update index periodically in the background (unit: seconds) + (setq mu4e-update-interval 900) + + ;; frequent mail folders, with shortcuts + ;; NOTE: do not use shortcut `o' as it is used for `[o]ther' + ;(setq mu4e-maildir-shortcuts + ; '(("/important" . ?i) + ; ("/archive" . ?a) + ; ("/gmail-aly/archive" . ?G) + ; ("/gmail-li/archive" . ?g) + ; ("/outlook-aly/inbox" . ?l) + ; ("/outlook-li/inbox" . ?L) + ; ("/sjtu/inbox" . ?s))) + + ;; do not keep message buffers around + (setq message-kill-buffer-on-exit t) + + ;; enable inline images + (setq mu4e-view-show-images t) + ;; use imagemagick if available + (when (fboundp 'imagemagick-register-types) + (imagemagick-register-types)) + + ;; display rich-text messages + (require 'mu4e-contrib) + ;; use `shr' html renderer; reqiure emacs >= 24.4 + (require 'shr) + (setq mu4e-html2text-command 'mu4e-shr2text) + (add-hook 'mu4e-view-mode-hook + (lambda () + ;; try to emulate some of the `eww' key-bindings + (local-set-key (kbd "<tab>") 'shr-next-link) + (local-set-key (kbd "<backtab>") 'shr-previous-link))) + ;; change the luminosity form dark theme + (setq shr-color-visible-luminance-min 70) + + ;; customize bookmarks + (setq mu4e-bookmarks + '(("flag:unread AND NOT flag:trashed" "Unread messages" ?u) + ("date:today..now" "Today's messages" ?T) + ("date:7d..now" "Last 7 days" ?w) + ("date:1m..now" "Last month" ?m) + ("flag:flagged" "Flagged messages" ?f) + ("tag:todo OR tag:task" "TODO / Task" ?t) + ("tag:work" "Work" ?W) + ("tag:astro" "Astro" ?a) + ("tag:arxiv OR from:arxiv.org" "arXiv" ?x) + ("tag:SMS" "SMS" ?S) + ("flag:trashed OR tag:\\\\Trash" "Deleted" ?d) + ("mime:image/*" "Messages with images" ?p))) + + ;; headers list appearance + (setq mu4e-headers-date-format "%Y-%m-%d %H:%M" + mu4e-headers-fields '((:date . 18) ;; also :human-date + (:flags . 5) + (:from-or-to . 22) + (:subject . nil))) ;; also :thread-subject + + ;; header fields to be shown in the view buffer + (add-to-list 'mu4e-view-fields :size t) + (add-to-list 'mu4e-view-fields :user-agent t) + + ;; use fancy non-ascii characters in various places + ;(setq mu4e-use-fancy-chars t) + + ;; show full addresses instead of just names when view message + (setq mu4e-view-show-addresses t) + + ;; also include messages related to the searched messages + (setq mu4e-headers-include-related t) + ;; exclude the duplicate messages with the same `Message-ID' + ;(setq mu4e-headers-skip-duplicates t) + + ;; compose messages in a separate frame + (setq mu4e-compose-in-new-frame t) + + ;; confirm before sending + (add-hook 'message-send-hook + (lambda () + (unless (yes-or-no-p "Sure you want to send this?") + (signal 'quit nil)))) + + ;; custom actions + ;; retag action + (setq mu4e-action-tags-header "X-Keywords") + (add-to-list 'mu4e-headers-actions + '("tRetag message" . mu4e-action-retag-message) t) + (add-to-list 'mu4e-view-actions + '("tRetag message" . mu4e-action-retag-message) t) + ;; view in browser + (add-to-list 'mu4e-view-actions + '("bView in browser" . mu4e-action-view-in-browser) t) + ;; search for messages by the sender of the opened message + (defun search-for-sender (msg) + "Search for messages sent by the sender of the message at point." + (mu4e-headers-search + (concat "from:" (cdar (mu4e-message-field msg :from))))) + (add-to-list 'mu4e-view-actions + '("xSearch for sender" . search-for-sender) t) + + ;; set `mu4e' as emacs' default email program + (setq mail-user-agent 'mu4e-user-agent) + + ;; END: with-eval-after-load 'mu4e + ) + + +;;; Key bindings for Evil +;; Credits: +;; https://github.com/philc/emacs-config - .emacs.d/elisp/mu4e-mode-personal.el + +(dolist (mode '(mu4e-mode + mu4e-main-mode + mu4e-headers-mode + mu4e-view-mode + mu4e-compose-mode)) + (evil-set-initial-state mode 'normal)) + +(with-eval-after-load 'mu4e + (evil-make-overriding-map mu4e-main-mode-map 'normal t) + (evil-define-key 'normal mu4e-main-mode-map + "J" 'mu4e~headers-jump-to-maildir + "j" 'evil-next-line + "k" 'evil-previous-line) + (evil-make-overriding-map mu4e-headers-mode-map 'normal t) + (evil-define-key 'normal mu4e-headers-mode-map + "gg" 'evil-goto-first-line + "J" 'mu4e~headers-jump-to-maildir + "j" 'mu4e-headers-next + "k" 'mu4e-headers-prev + "]" 'mu4e-headers-next-unread + "[" 'mu4e-headers-prev-unread + "C" 'mu4e-compose-new + "E" 'mu4e-compose-edit + "F" 'mu4e-compose-forward + "R" 'mu4e-compose-reply) + (evil-leader/set-key-for-mode 'mu4e-headers-mode + "u" '(lambda () (interactive) (mu4e-update-mail-and-index t))) + ;; + (evil-make-overriding-map mu4e-view-mode-map 'normal t) + (evil-define-key 'normal mu4e-view-mode-map + "gg" 'evil-goto-first-line + "j" 'evil-next-line + "k" 'evil-previous-line + "\C-j" 'mu4e-view-headers-next + "\C-k" 'mu4e-view-headers-prev + "\C-]" 'mu4e-view-headers-next-unread + "\C-[" 'mu4e-view-headers-prev-unread + "C" 'mu4e-compose-new + "E" 'mu4e-compose-edit + "F" 'mu4e-compose-forward + "R" 'mu4e-compose-reply) + (evil-leader/set-key-for-mode 'mu4e-view-mode + "u" '(lambda () (interactive) (mu4e-update-mail-and-index t)) + "x" '(lambda () (interactive) (helm-M-x)) + "s" 'mu4e-view-raw-message) + ;; + (evil-make-overriding-map mu4e-compose-mode-map 'normal t) + (evil-leader/set-key-for-mode 'mu4e-compose-mode + "," 'message-send-and-exit + "c" 'message-send-and-exit + "d" 'message-dont-send + "k" 'mu4e-message-kill-buffer + "a" 'mml-attach-file) + ) ;; with-eval-after-load 'mu4e + + +(provide 'my-mu4e) + +;;; my-mu4e.el ends here |