mu4e - Email Client¶
The advantage of use Emacs as an email client:
- communication happens at the point where the content is generated. as a statisician/programmer, most likely I need to communicate with numbers, table, graphs, or snippet. I could just copy these results from to email, do a quick editing.
- HTML email with CSS style. I like to format my email use headingline, fonts, and highlight the code, I used to be write a report in Word/LatEx and write an email with only one line, please see the attachment. which I don’t like.
- search properly I use search all the time, and this functionality is not working at all in outlook 2013, it also shows up random info (mail.app in osx did a great job).
Disadvantage and the things it can’t do:
- book Meeting/Appointment I am not aware if you can do it in emacs, and we need an iterative way to do. Outlook Schedule Asistant does a good job, it lists agenda of all attendence, and I could spot one time slot that suit for all or most people.
- don’t expect me to reply immediately this is how it works: 1. download the email from server, 2) index with head, body, attachment, user name etc. 3) Emacs talk to and show in GUI. I usually update the email about 30 minutes. but it helps me out of disrupts.
- calendar I don’t know how to integrate Office 365 calendar with Org-mode calandar yet. even it can, I doubt I can download and see other people’s agenda.
This setting need two programs to work: 1) mu, 2) offlineimap.
to install mu on osx,
brew install mu
;; usage:
;; $ offlineimap
;; $ mu index
;; M-x mu4e
;; from mu's official manual
;;----------------------------------------------------------
(add-to-list 'load-path "~/git/.emacs.d/elpa/mu4e")
(require 'mu4e)
(setq mu4e-mu-binary "/usr/local/bin/mu")
;; default
;; don't save message to Sent Messages, Gmail/IMAP takes care of this
(setq mu4e-sent-messages-behavior 'sent)
;; allow for updating mail using 'U' in the main view:
(setq mu4e-get-mail-command "offlineimap -a JBA")
(setq mu4e-update-interval 300)
;; sending mail -- replace USERNAME with your gmail username
;; also, make sure the gnutls command line utils are installed
;; package 'gnutls-bin' in Debian/Ubuntu
(setq smtpmail-default-smtp-server "smtpserver") ; needs to be specified before the (require)
(require 'smtpmail)
;; don't keep message buffers around
(setq message-kill-buffer-on-exit t)
;; attempt to show images when viewing messages
(setq mu4e-view-show-images t
mu4e-show-images t
mu4e-view-image-max-width 800)
;; (setq mu4e-html2text-command "html2text -utf8 -width 72") ;; nil "Shel command that converts HTML
;; ref: http://emacs.stackexchange.com/questions/3051/how-can-i-use-eww-as-a-renderer-for-mu4e
(defun my-render-html-message ()
(let ((dom (libxml-parse-html-region (point-min) (point-max))))
(erase-buffer)
(shr-insert-document dom)
(goto-char (point-min))))
(setq mu4e-html2text-command 'my-render-html-message)
;; yt
(setq mu4e-view-prefer-html t) ;; try to render
(add-to-list 'mu4e-view-actions
'("ViewInBrowser" . mu4e-action-view-in-browser) t) ;; read in browser
;; mu4e as default email agent in emacs
(setq mail-user-agent 'mu4e-user-agent)
(require 'org-mu4e)
;== M-x org-mu4e-compose-org-mode==
(setq org-mu4e-convert-to-html t) ;; org -> html
; = M-m C-c.=
;; give me ISO(ish) format date-time stamps in the header list
(setq mu4e-headers-date-format "%Y-%m-%d %H:%M")
;; customize the reply-quote-string
;; M-x find-function RET message-citation-line-format for docs
(setq message-citation-line-format "%N @ %Y-%m-%d %H:%M %Z:\n")
(setq message-citation-line-function 'message-insert-formatted-citation-line)
;; the headers to show in the headers list -- a pair of a field
;; and its width, with `nil' meaning 'unlimited'
;; (better only use that for the last field.
;; These are the defaults:
(setq mu4e-headers-fields
'( (:date . 25)
(:flags . 6)
(:from . 22)
(:subject . nil)))
;; don't keep message buffers around
(setq message-kill-buffer-on-exit t)
;; attachments go here
(setq mu4e-attachment-dir "~/Downloads")
;; should mu4e use fancy utf characters? NO. they're ugly.
;;(setq mu4e-use-fancy-chars 't)
use helm-mu to search emails
(global-set-key (kbd "<f9> e") 'helm-mu)
Account¶
set up email account, use office 365 in the office, and iCloud at macbook pro.
(setq mu4e-maildir-shortcuts '(("/JBA/INBOX" . ?j)
("/iCloud/INBOX" . ?i)
("/Gmail/INBOX" . ?g)
("/Sent Items" . ?s)
("/Trash" . ?t)
("/All Mail" . ?a)))
;; (defun yt/email-jba ()
;; (interactive)
;; ;; setup for smtp
;; (setq message-send-mail-function 'smtpmail-send-it
;; smtpmail-stream-type 'starttls
;; smtpmail-default-smtp-server "smtp.office365.com"
;; smtpmail-smtp-server "smtp.office365.com"
;; smtpmail-smtp-service 587
;; smtpmail-smtp-user "yi.tang@jbarisk.com"
;; ;; account info
;; user-mail-address "yi.tang@jbarisk.com"
;; user-full-name "Yi Tang"
;; ;; mu4e
;; mu4e-drafts-folder "/JBA/Drafts"
;; mu4e-sent-folder "/JBA/Sent Items"
;; mu4e-trash-folder "/JBA/Trash"
;; mu4e-maildir-shortcuts '(("/JBA/INBOX" . ?i)
;; ("/Sent Items" . ?s)
;; ("/Trash" . ?t)
;; ("/All Mail" . ?a))
;; mu4e-compose-signature (concat
;; "Yi Tang\n"
;; "Statistician\n"
;; "T: +44 (0) 1756 799919\n")))
(defun yt/email-icloud ()
(setq ;; account info
user-mail-address "yi.tang.uk@me.com"
user-full-name "Yi Tang"
message-send-mail-function 'smtpmail-send-it
smtpmail-stream-type 'starttls
smtpmail-default-smtp-server "smtp.mail.me.com"
smtpmail-smtp-server "smtp.mail.me.com"
smtpmail-smtp-service 587
smtpmail-smtp-user "yi.tang.uk@me.com"
mu4e-maildir "~/Maildir"
mu4e-drafts-folder "/iCloud/Drafts"
mu4e-sent-folder "/iCloud/Sent Messages"
mu4e-trash-folder "/iCloud/Deleted Messages"
mu4e-maildir-shortcuts '(("/iCloud/INBOX" . ?i)
("/Sent Items" . ?s)
("/Trash" . ?t)
("/All Mail" . ?a))
mu4e-compose-signature (concat
"唐毅 (Yi Tang)\n"
"Email: yi.tang.uk@me.com\n"
"\n")))
(defun yt/email-gmail ()
;; sent emails
(setq message-send-mail-function 'smtpmail-send-it
starttls-use-gnutls t
smtpmail-starttls-credentials '(("smtp.gmail.com" 587 nil nil))
;; smtpmail-auth-credentials
;; '(("smtp.gmail.com" 587 "yi.tang.uni@gmail.com" nil))
smtpmail-default-smtp-server "smtp.gmail.com"
smtpmail-smtp-server "smtp.gmail.com"
smtpmail-smtp-service 587
smtpmail-smtp-user "yi.tang.uni@gmail.com")
(setq user-mail-address "yi.tang.uni@gmail.com" )
(setq user-full-name "Yi Tang" )
(setq mu4e-drafts-folder "/Gmail/Drafts" )
(setq mu4e-sent-folder "/Gmail/Sent Items" )
(setq mu4e-trash-folder "/Gmail/Trash" )
(setq mu4e-maildir-shortcuts '(("/Gmail/INBOX" . ?i)
("/Sent Items" . ?s)
("/Trash" . ?t)
("/All Mail" . ?a)))
(setq mu4e-compose-signature (concat
"Yi Tang\n"
"Statistician\n"
"T: 07445510033\n")))
(defun yt/mu4e-jba ()
(interactive)
(yt/email-jba)
(mu4e)
)
(defun yt/mu4e-gmail()
(interactive)
(yt/email-gmail)
(mu4e))
(defun yt/mu4e-icloud()
(interactive)
(yt/email-icloud)
(mu4e))
(defhydra hydra-email (:color blue :hint nil)
"
Mu4e: _g_mail _j_ba _i_Cloud"
("g" yt/mu4e-gmail)
("j" yt/mu4e-jba)
("i" yt/mu4e-icloud))
(global-set-key [f2] 'hydra-email/body)
;; (if (string= WhereAmI "Office")
;; (yt/email-jba)
;; (yt/email-icloud))
(yt/email-icloud)
when I send an email, it will prompt and ask for email address, I only need to type once per Emacs session, also, I can save the password to an .authoty file.
Contacts¶
have problem with BBDB installtion, and use org-contact.el to manage contact. adding contact is very easy. I can use tab to complete contacts, which is really handy.
(require 'org-contacts)
(setq org-contacts-files '("~/git/org/contacts.org"))
;; (setq mu4e-org-contacts-file "~/git/org/contacts.org")
(add-to-list 'mu4e-headers-actions
'("org-contact-add" . mu4e-action-add-org-contact) t)
(add-to-list 'mu4e-view-actions
'("org-contact-add" . mu4e-action-add-org-contact) t)
Workflow¶
I am trying to avoid use C-x m
to write/sent email directy, unless
it is really short. otherwise, if it relates to a project, I will make
an org headline to keep track the project communciation, to do that, I
compose email/message in org mode, then sent the whole subtree by C-c
M-o
.
(require 'org-mime)
(setq org-mime-library 'mml)
(add-hook 'message-mode-hook
(lambda ()
(local-set-key "\C-c\M-o" 'org-mime-htmlize)))
(add-hook 'org-mode-hook
(lambda ()
(local-set-key "\C-c\M-o" 'org-mime-org-buffer-htmlize)))
(add-hook 'org-mime-html-hook
(lambda ()
(insert-file-contents "~/git/.emacs.d/personal/css/office.css")
;; (goto-char 5)
)
t)
(add-hook 'org-mode-hook
(lambda ()
(local-set-key (kbd "C-c M-o") 'org-mime-subtree))
'append)
just in case I didn’t get the format right at the first place and need some quick fix in message mode, save me few seconds in going back to org-mode.
(add-hook 'message-mode-hook 'orgstruct++-mode 'append)
(add-hook 'message-mode-hook 'turn-on-auto-fill 'append)
;; (add-hook 'message-mode-hook 'bbdb-define-all-aliases 'append)
(add-hook 'message-mode-hook 'orgtbl-mode 'append)
(add-hook 'message-mode-hook 'turn-on-flyspell 'append)
;; (add-hook 'message-mode-hook
;; '(lambda () (setq fill-column 270))
;; 'append)