Multiple accounts now working in mu4e. Adding some more spacemacs
layers. Misc spacemacs conf updates.master
parent
842492dd93
commit
97336db31d
@ -0,0 +1,240 @@
|
|||||||
|
;;; mu4e-multi.el --- Multiple account facilities for mu4e
|
||||||
|
|
||||||
|
;; Copyright (C) 2013 Free Software Foundation, Inc.
|
||||||
|
|
||||||
|
;; Authors: Fabián Ezequiel Gallina <fgallina@gnu.org>
|
||||||
|
|
||||||
|
;; This file is NOT part of mu4e.
|
||||||
|
|
||||||
|
;; mu4e-multi.el is free software; you can redistribute it
|
||||||
|
;; and/or modify it under the terms of the GNU General Public License
|
||||||
|
;; as published by the Free Software Foundation; either version 3, or
|
||||||
|
;; (at your option) any later version.
|
||||||
|
|
||||||
|
;; mu4e-multi.el is distributed in the hope that it will be
|
||||||
|
;; useful, but WITHOUT ANY WARRANTY; without even the implied warranty
|
||||||
|
;; of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
;; GNU General Public License for more details.
|
||||||
|
|
||||||
|
;; You should have received a copy of the GNU General Public License
|
||||||
|
;; along with mu4e-multi.el; see the file COPYING. If not,
|
||||||
|
;; write to the Free Software Foundation, Inc., 51 Franklin St, Fifth
|
||||||
|
;; Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
;;; Commentary:
|
||||||
|
|
||||||
|
;; See the README.md file for details on how to install and use this
|
||||||
|
;; package.
|
||||||
|
|
||||||
|
;;; Code:
|
||||||
|
(require 'cl-lib)
|
||||||
|
(require 'message)
|
||||||
|
(require 'mu4e-actions)
|
||||||
|
(require 'mu4e-headers)
|
||||||
|
(require 'thingatpt)
|
||||||
|
|
||||||
|
|
||||||
|
(defvar mu4e-multi-last-read-account ""
|
||||||
|
"Holds the last selected account from minibuffer.
|
||||||
|
This is just for `mu4e-multi-minibuffer-read-account' to prompt
|
||||||
|
always the latest used account as default.")
|
||||||
|
|
||||||
|
(defvar mu4e-multi-account-alist nil
|
||||||
|
"Alist containing all information of email accounts.
|
||||||
|
Here's an example for two accounts:
|
||||||
|
|
||||||
|
'((\"account-1\"
|
||||||
|
(user-mail-address . \"user1@server.com\")
|
||||||
|
(mu4e-sent-folder . \"/account-1/Sent Mail\")
|
||||||
|
(mu4e-drafts-folder . \"/account-1/Drafts\")
|
||||||
|
(mu4e-refile-folder . \"/account-1/Archive\")
|
||||||
|
(mu4e-trash-folder . \"/account-1/Trash\"))
|
||||||
|
(\"account-2\"
|
||||||
|
(user-mail-address . \"user2@server.com\")
|
||||||
|
(mu4e-sent-folder . \"/account-2/Sent Mail\")
|
||||||
|
(mu4e-drafts-folder . \"/account-2/Drafts\")
|
||||||
|
(mu4e-refile-folder . \"/account-2/Archive\")
|
||||||
|
(mu4e-trash-folder . \"/account-2/Trash\")))
|
||||||
|
|
||||||
|
The names \"account-1\" and \"account-2\" are used as identifiers
|
||||||
|
to access an account's data. IMPORTANT: maildirs must match
|
||||||
|
their prefix with the identifier given, as in the example
|
||||||
|
above.")
|
||||||
|
|
||||||
|
(defvar mu4e-multi-standard-folders '(mu4e-drafts-folder
|
||||||
|
mu4e-refile-folder
|
||||||
|
mu4e-sent-folder
|
||||||
|
mu4e-trash-folder)
|
||||||
|
"List of standard mu4e folders.")
|
||||||
|
|
||||||
|
(defun mu4e-multi-account-name-list (&optional account-alist)
|
||||||
|
"Return account names from ACCOUNT-ALIST.
|
||||||
|
When ACCOUNT-ALIST is nil, the value of
|
||||||
|
`mu4e-multi-account-alist' is used."
|
||||||
|
(mapcar #'car (or account-alist mu4e-multi-account-alist)))
|
||||||
|
|
||||||
|
(defun mu4e-multi-minibuffer-read-account ()
|
||||||
|
"Read account name from minibuffer."
|
||||||
|
(let ((account-list (mu4e-multi-account-name-list)))
|
||||||
|
(setq
|
||||||
|
mu4e-multi-last-read-account
|
||||||
|
(completing-read
|
||||||
|
(format "Compose with account: (%s) "
|
||||||
|
(mapconcat
|
||||||
|
#'(lambda (acc)
|
||||||
|
(if (string= acc mu4e-multi-last-read-account)
|
||||||
|
(format "[%s]" acc)
|
||||||
|
acc))
|
||||||
|
account-list "/"))
|
||||||
|
account-list nil t nil nil mu4e-multi-last-read-account))))
|
||||||
|
|
||||||
|
(defun mu4e-multi-get-msg-account (msg &optional account)
|
||||||
|
"Get account from MSG.
|
||||||
|
If no account can be found from MSG then use ACCOUNT as default."
|
||||||
|
(let ((maildir (when msg (mu4e-msg-field msg :maildir)))
|
||||||
|
(account-list (mu4e-multi-account-name-list)))
|
||||||
|
(cond ((and maildir
|
||||||
|
(string-match
|
||||||
|
(concat
|
||||||
|
"/\\("
|
||||||
|
(regexp-opt account-list)
|
||||||
|
"\\)/?")
|
||||||
|
maildir))
|
||||||
|
(match-string-no-properties 1 maildir))
|
||||||
|
((and account (car (member account account-list)))))))
|
||||||
|
|
||||||
|
(defun mu4e-multi-set-folder (folder msg)
|
||||||
|
"Set FOLDER using MSG as detection element."
|
||||||
|
(let ((varval (assoc
|
||||||
|
folder
|
||||||
|
(cdr
|
||||||
|
(assoc (or (mu4e-multi-get-msg-account msg)
|
||||||
|
mu4e-multi-last-read-account)
|
||||||
|
mu4e-multi-account-alist)))))
|
||||||
|
(if varval
|
||||||
|
(set (make-local-variable folder) (cdr varval))
|
||||||
|
(mu4e-error "Cannot set folder %s, account for MSG %s not detected"
|
||||||
|
folder msg))))
|
||||||
|
|
||||||
|
(defmacro mu4e-multi-make-set-folder-fn (folder)
|
||||||
|
"Make a setter for FOLDER.
|
||||||
|
This is just a wrapper over `mu4e-multi-set-folder' and can be
|
||||||
|
used to set you mu4e-*-folder vars. Example:
|
||||||
|
|
||||||
|
(setq mu4e-sent-folder
|
||||||
|
(mu4e-multi-make-folder-fn mu4e-sent-folder))
|
||||||
|
|
||||||
|
Normally used to set `mu4e-sent-folder', `mu4e-drafts-folder',
|
||||||
|
`mu4e-trash-folder' and `mu4e-refile-folder'."
|
||||||
|
`(apply-partially #'mu4e-multi-set-folder ',folder))
|
||||||
|
|
||||||
|
(defmacro mu4e-multi-make-mark-for-command (folder)
|
||||||
|
"Generate command to mark current message to move to FOLDER.
|
||||||
|
The command is named after the prefix \"mu4e-multi-mark-for-\"
|
||||||
|
and what's in between of \"mu4e-\" and \"-folder\" parts of the
|
||||||
|
FOLDER symbol. Here's an example on how to use this:
|
||||||
|
|
||||||
|
(mu4e-multi-make-mark-for-command mu4e-hold-folder)
|
||||||
|
(define-key 'mu4e-headers-mode-map \"h\" 'mu4e-multi-mark-for-hold)
|
||||||
|
|
||||||
|
OR:
|
||||||
|
|
||||||
|
(define-key 'mu4e-headers-mode-map \"h\"
|
||||||
|
(mu4e-multi-make-mark-for-command mu4e-hold-folder))"
|
||||||
|
(let ((name (mapconcat
|
||||||
|
'identity
|
||||||
|
(butlast
|
||||||
|
(cdr (split-string
|
||||||
|
(symbol-name folder) "-")))
|
||||||
|
"-")))
|
||||||
|
`(defun ,(intern (format "mu4e-multi-mark-for-%s" name)) ()
|
||||||
|
,(format "Mark message to be moved to `%s'." ',folder)
|
||||||
|
(interactive)
|
||||||
|
(mu4e-mark-set
|
||||||
|
'move
|
||||||
|
(cdr (assoc ',folder
|
||||||
|
(cdr (assoc (mu4e-multi-get-msg-account
|
||||||
|
(mu4e-message-at-point))
|
||||||
|
mu4e-multi-account-alist)))))
|
||||||
|
(mu4e-headers-next))))
|
||||||
|
|
||||||
|
(defun mu4e-multi-compose-set-account (&optional account)
|
||||||
|
"Set the ACCOUNT for composing.
|
||||||
|
With Optional Argument ACCOUNT, set all variables for that given
|
||||||
|
identifier, else it tries to retrieve the message in context and
|
||||||
|
detect ACCOUNT from it."
|
||||||
|
(interactive)
|
||||||
|
(let* ((msg (or mu4e-compose-parent-message
|
||||||
|
(ignore-errors (mu4e-message-at-point))))
|
||||||
|
(account (or account
|
||||||
|
(mu4e-multi-get-msg-account msg)))
|
||||||
|
(account-vars (cdr (assoc account mu4e-multi-account-alist))))
|
||||||
|
(when account-vars
|
||||||
|
(mapc #'(lambda (var)
|
||||||
|
(set (make-local-variable (car var)) (cdr var)))
|
||||||
|
account-vars))
|
||||||
|
(when (memq major-mode '(mu4e-compose-mode message-mode))
|
||||||
|
(message-remove-header "from")
|
||||||
|
(message-add-header (format "From: %s\n" (message-make-from)))
|
||||||
|
(message "Using account %s" account))))
|
||||||
|
|
||||||
|
;;;###autoload
|
||||||
|
(defun mu4e-multi-compose-new ()
|
||||||
|
"Start writing a new message.
|
||||||
|
This is a simple wrapper over `mu4e-compose-new' that asks for an
|
||||||
|
account to be used to compose the new message."
|
||||||
|
(interactive)
|
||||||
|
(let ((account (mu4e-multi-minibuffer-read-account)))
|
||||||
|
(mu4e-compose-new)
|
||||||
|
(mu4e-multi-compose-set-account account)))
|
||||||
|
|
||||||
|
(defun mu4e-multi-smtpmail-set-msmtp-account ()
|
||||||
|
"Set the account for msmtp.
|
||||||
|
This function is intended to added in the
|
||||||
|
`message-send-mail-hook'. Searches for the account in the
|
||||||
|
`mu4e-multi-account-alist' variable by matching the email given
|
||||||
|
in the \"from\" field. Note that all msmtp accounts should
|
||||||
|
defined in the ~/.msmtprc file and names should be matching the
|
||||||
|
keys of the `mu4e-multi-account-alist'."
|
||||||
|
(setq message-sendmail-extra-arguments
|
||||||
|
(list
|
||||||
|
"-a"
|
||||||
|
(catch 'exit
|
||||||
|
(let* ((from (message-fetch-field "from"))
|
||||||
|
(email (and from
|
||||||
|
(string-match thing-at-point-email-regexp from)
|
||||||
|
(match-string-no-properties 0 from))))
|
||||||
|
(if email
|
||||||
|
(cl-dolist (alist mu4e-multi-account-alist)
|
||||||
|
(when (string= email (cdr (assoc 'user-mail-address (cdr alist))))
|
||||||
|
(throw 'exit (car alist))))
|
||||||
|
(catch 'exit (mu4e-multi-minibuffer-read-account))))))))
|
||||||
|
|
||||||
|
(defun mu4e-multi-enable ()
|
||||||
|
"Enable mu4e multiple account setup."
|
||||||
|
(setq mu4e-sent-folder (mu4e-multi-make-set-folder-fn mu4e-sent-folder)
|
||||||
|
mu4e-drafts-folder (mu4e-multi-make-set-folder-fn mu4e-drafts-folder)
|
||||||
|
mu4e-trash-folder (mu4e-multi-make-set-folder-fn mu4e-trash-folder)
|
||||||
|
mu4e-refile-folder (mu4e-multi-make-set-folder-fn mu4e-refile-folder))
|
||||||
|
(add-hook 'message-mode-hook 'mu4e-multi-compose-set-account))
|
||||||
|
|
||||||
|
(defun mu4e-multi-disable ()
|
||||||
|
"Disable mu4e multiple account setup."
|
||||||
|
(cl-dolist (variable mu4e-multi-standard-folders)
|
||||||
|
(let* ((sv (get variable 'standard-value))
|
||||||
|
(origval (and (consp sv)
|
||||||
|
(condition-case nil
|
||||||
|
(eval (car sv))
|
||||||
|
(error :help-eval-error)))))
|
||||||
|
(when (not (equal (symbol-value variable) origval))
|
||||||
|
(set variable origval))))
|
||||||
|
(remove-hook 'message-mode-hook 'mu4e-multi-compose-set-account))
|
||||||
|
|
||||||
|
(provide 'mu4e-multi)
|
||||||
|
|
||||||
|
;; Local Variables:
|
||||||
|
;; coding: utf-8
|
||||||
|
;; indent-tabs-mode: nil
|
||||||
|
;; End:
|
||||||
|
|
||||||
|
;;; mu4e-multi.el ends here
|
@ -1,51 +1,111 @@
|
|||||||
(eval-after-load 'mu4e
|
(eval-after-load 'mu4e
|
||||||
'(progn
|
'(progn
|
||||||
|
|
||||||
|
(require 'mu4e-multi)
|
||||||
|
(require 'mu4e-contrib)
|
||||||
|
|
||||||
|
(setq mu4e-multi-account-alist
|
||||||
|
'(("Gmail"
|
||||||
|
(user-mail-address . "dustinswan@gmail.com")
|
||||||
|
(mu4e-drafts-folder . "/Gmail/[Gmail].Drafts")
|
||||||
|
(mu4e-refile-folder . "/Gmail/[Gmail].All Mail")
|
||||||
|
(mu4e-sent-folder . "/Gmail/[Gmail].Sent Mail")
|
||||||
|
(mu4e-trash-folder . "/Gmail/[Gmail].Trash"))
|
||||||
|
("IOCOM"
|
||||||
|
(user-mail-address . "dswan@iocom.com")
|
||||||
|
(mu4e-drafts-folder . "/IOCOM/INBOX.Drafts")
|
||||||
|
(mu4e-refile-folder . "/IOCOM/INBOX.Archive")
|
||||||
|
(mu4e-sent-folder . "/IOCOM/INBOX.Sent")
|
||||||
|
(mu4e-trash-folder . "/IOCOM/INBOX.Trash"))))
|
||||||
|
|
||||||
|
(mu4e-multi-enable)
|
||||||
|
|
||||||
|
;; (add-hook 'message-send-mail-hook 'mu4e-multi-smtpmail-set-msmtp-account)
|
||||||
|
|
||||||
(setq
|
(setq
|
||||||
user-mail-address "dustinswan@gmail.com"
|
|
||||||
|
|
||||||
mu4e-maildir "~/Mail" ;; top-level Maildir
|
mu4e-maildir "~/Mail"
|
||||||
mu4e-sent-folder "/Gmail/[Gmail].Sent Mail" ;; folder for sent messages
|
mu4e-user-mail-address-list '("dustinswan@gmail.com"
|
||||||
mu4e-drafts-folder "/Gmail/[Gmail].Drafts" ;; unfinished messages
|
"dswan@iocom.com"
|
||||||
mu4e-trash-folder "/Gmail/[Gmail].Trash" ;; trashed messages
|
"dswan@insors.com"
|
||||||
mu4e-refile-folder "/Gmail/[Gmail].All Mail" ;; saved messages
|
"dustin@dustinswan.com")
|
||||||
mu4e-sent-messages-behavior 'delete
|
|
||||||
|
|
||||||
smtpmail-default-smtp-server "smtp.gmail.com"
|
user-full-name "Dustin Swan"
|
||||||
smtpmail-local-domain "gmail.com" ;; what the fuck is this
|
mu4e-attachment-dir "~/Downloads"
|
||||||
smtpmail-smtp-server "smtp.gmail.com"
|
message-signature "Dustin Swan"
|
||||||
smtpmail-smtp-service 25
|
mu4e-compose-signature "Dustin Swan"
|
||||||
|
mail-host-address "gmail.com"
|
||||||
|
|
||||||
mu4e-get-mail-command "offlineimap -q"
|
mu4e-get-mail-command "offlineimap -q"
|
||||||
mu4e-update-interval 120
|
mu4e-update-interval 120
|
||||||
|
|
||||||
|
;; mu4e-use-fancy-chars t
|
||||||
|
|
||||||
|
;; mu4e-html2text-command "html2text -nobs"
|
||||||
|
;; mu4e-html2text-command "w3m -T text/html"
|
||||||
|
mu4e-html2text-command 'mu4e-shr2text
|
||||||
|
mu4e-view-prefer-html 't ;; sorryboutit
|
||||||
|
mu4e-view-show-images t ;; doesn't work with shr2text
|
||||||
|
|
||||||
|
message-send-mail-function 'message-send-mail-with-sendmail
|
||||||
|
message-sendmail-extra-arguments '("--read-envelope-from")
|
||||||
|
message-sendmail-f-is-evil 't
|
||||||
|
sendmail-program "/usr/local/bin/msmtp"
|
||||||
|
|
||||||
|
;; just Gmail at first
|
||||||
|
;; user-mail-address "dustinswan@gmail.com"
|
||||||
|
;; mu4e-sent-folder "/Gmail/[Gmail].Sent Mail"
|
||||||
|
;; mu4e-drafts-folder "/Gmail/[Gmail].Drafts"
|
||||||
|
;; mu4e-trash-folder "/Gmail/[Gmail].Trash"
|
||||||
|
;; mu4e-refile-folder "/Gmail/[Gmail].All Mail"
|
||||||
|
;; mu4e-sent-messages-behavior 'delete
|
||||||
|
;; mail-host-address "gmail.com"
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
; multiple accounts
|
||||||
;; (defvar my-mu4e-account-alist
|
;; (defvar my-mu4e-account-alist
|
||||||
;; '(("Gmail"
|
;; '(("Gmail"
|
||||||
;; (mu4e-sent-folder "/Account1/Saved Items")
|
;; (user-mail-address "dustinswan@gmail.com")
|
||||||
;; (mu4e-drafts-folder "/Account1/Drafts")
|
;; (mu4e-sent-folder "/Gmail/[Gmail].Sent Mail")
|
||||||
;; (user-mail-address "my.address@account1.tld")
|
;; (mu4e-drafts-folder "/Gmail/[Gmail].Drafts")
|
||||||
;; (smtpmail-default-smtp-server "smtp.account1.tld")
|
;; (mu4e-trash-folder "/Gmail/[Gmail].Trash")
|
||||||
;; (smtpmail-local-domain "account1.tld")
|
;; ;; (mu4e-refile-folder "/Gmail/[Gmail].All Mail")
|
||||||
;; (smtpmail-smtp-user "username1")
|
;; (mu4e-sent-messages-behavior 'delete)
|
||||||
;; (smtpmail-smtp-server "smtp.account1.tld")
|
;; (mail-host-address "gmail.com")
|
||||||
;; (smtpmail-stream-type starttls)
|
|
||||||
;; (smtpmail-smtp-service 25))
|
|
||||||
;; ("IOCOM"
|
;; ("IOCOM"
|
||||||
;; (mu4e-sent-folder "/Account2/Saved Items")
|
;; (user-mail-address "dswan@iocom.com")
|
||||||
;; (mu4e-drafts-folder "/Account2/Drafts")
|
;; (mu4e-sent-folder "/IOCOM/INBOX.Sent")
|
||||||
;; (user-mail-address "my.address@account2.tld")
|
;; (mu4e-drafts-folder "/IOCOM/INBOX.Drafts")
|
||||||
;; (smtpmail-default-smtp-server "smtp.account2.tld")
|
;; (mu4e-trash-folder "/IOCOM/INBOX.Trash")
|
||||||
;; (smtpmail-local-domain "account2.tld")
|
;; ;; (mu4e-refile-folder "/IOCOM/INBOX.Archive")
|
||||||
;; (smtpmail-smtp-user "username2")
|
;; (mu4e-sent-messages-behavior 'sent)
|
||||||
;; (smtpmail-smtp-server "smtp.account2.tld")
|
;; (mail-host-address "iocom.com")))))
|
||||||
;; (smtpmail-stream-type starttls)
|
|
||||||
;; (smtpmail-smtp-service 587))))
|
(add-to-list 'mu4e-bookmarks '("maildir:/IOCOM/INBOX OR maildir:/Gmail/INBOX" "All Inboxes" ?I))
|
||||||
|
(add-to-list 'mu4e-bookmarks '("maildir:/IOCOM/INBOX" "IOCOM Inbox" ?i))
|
||||||
|
(add-to-list 'mu4e-bookmarks '("maildir:/Gmail/INBOX" "Gmail Inbox" ?g))
|
||||||
|
|
||||||
(setq mu4e-attachment-dir "~/Downloads")
|
;; refile
|
||||||
|
;; (setq mu4e-refile-folder
|
||||||
|
;; (lambda (msg)
|
||||||
|
;; (cond
|
||||||
|
;; ((mu4e-message-contact-field-matches msg :to "dustinswan@gmail.com")
|
||||||
|
;; "/Gmail/[Gmail].All Mail")
|
||||||
|
;; ((mu4e-message-contact-field-matches msg :to "dswan@iocom.com")
|
||||||
|
;; "/IOCOM/INBOX.Archive")
|
||||||
|
;; ;; messages sent by me go to the sent folder
|
||||||
|
;; ;; ((find-if
|
||||||
|
;; ;; (lambda (addr)
|
||||||
|
;; ;; (mu4e-message-contact-field-matches msg :from addr))
|
||||||
|
;; ;; mu4e-user-mail-address-list)
|
||||||
|
;; ;; mu4e-sent-folder)
|
||||||
|
;; (t "/Gmail/[Gmail].All Mail"))))
|
||||||
|
|
||||||
(setq mu4e-view-show-images t) ;; enable inline images
|
(add-to-list 'mu4e-view-actions '("ViewInBrowser" . mu4e-action-view-in-browser) t)
|
||||||
|
|
||||||
;; use imagemagick, if available
|
;; use imagemagick, if available
|
||||||
(when (fboundp 'imagemagick-register-types)
|
(when (fboundp 'imagemagick-register-types)
|
||||||
(imagemagick-register-types))))
|
(imagemagick-register-types))))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue