Add email/{wanderlust,mu4e,notmuch} modules
Removed app/{email,notmuch}
This commit is contained in:
parent
45266213a5
commit
84c5da844b
16 changed files with 178 additions and 89 deletions
|
@ -30,7 +30,9 @@
|
|||
(hideshow (:editor fold)))
|
||||
(:ui (doom-modeline (:ui modeline))
|
||||
(fci (:ui fill-column))
|
||||
(evil-goggles (:ui ophints))))
|
||||
(evil-goggles (:ui ophints)))
|
||||
(:app (email (:email mu4e))
|
||||
(notmuch (:email notmuch))))
|
||||
"A tree alist that maps deprecated modules to their replacement(s).
|
||||
|
||||
Each entry is a three-level tree. For example:
|
||||
|
|
|
@ -143,13 +143,17 @@
|
|||
;;web ; the tubes
|
||||
;;vala ; GObjective-C
|
||||
|
||||
:email
|
||||
(mu4e +gmail) ; WIP
|
||||
notmuch ; WIP
|
||||
(wanderlust +gmail) ; WIP
|
||||
|
||||
;; Applications are complex and opinionated modules that transform Emacs
|
||||
;; toward a specific purpose. They may have additional dependencies and
|
||||
;; should be loaded late.
|
||||
:app
|
||||
;;(email +gmail) ; emacs as an email client
|
||||
;;irc ; how neckbeards socialize
|
||||
;;(rss +org) ; emacs as an RSS reader
|
||||
;;rss +org ; emacs as an RSS reader
|
||||
;;twitter ; twitter client https://twitter.com/vnought
|
||||
;;(write ; emacs as a word processor (latex + org + markdown)
|
||||
;; +wordnut ; wordnet (wn) search
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
- [[#emacs][:emacs]]
|
||||
- [[#tools][:tools]]
|
||||
- [[#lang][:lang]]
|
||||
- [[#email][:email]]
|
||||
- [[#app][:app]]
|
||||
- [[#collab][:collab]]
|
||||
- [[#config][:config]]
|
||||
|
@ -145,12 +146,16 @@ Modules that bring support for a language or group of languages to Emacs.
|
|||
+ web =+lsp=:
|
||||
+ vala:
|
||||
|
||||
* :email
|
||||
+ [[file:email/mu4e/README.org][mu4e]] =+gmail=:
|
||||
+ notmuch:
|
||||
+ wanderlust =+gmail=:
|
||||
|
||||
* :app
|
||||
Large, opinionated modules that transform and take over Emacs, i.e.
|
||||
Doom-specific porcelains.
|
||||
|
||||
+ calendar:
|
||||
+ [[file:app/email/README.org][email]] =+gmail=:
|
||||
+ [[file:app/irc/README.org][irc]]:
|
||||
+ rss =+org=:
|
||||
+ twitter:
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
;;; app/email/+gmail.el -*- lexical-binding: t; -*-
|
||||
|
||||
(after! mu4e
|
||||
;; don't save message to Sent Messages, Gmail/IMAP takes care of this
|
||||
(setq mu4e-sent-messages-behavior 'delete
|
||||
|
||||
;; 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)
|
||||
|
||||
;; 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 `+email|gmail-fix-flags'.
|
||||
;;
|
||||
;; Gmail will handle the rest.
|
||||
(defun +email--mark-seen (docid msg target)
|
||||
(mu4e~proc-move docid (mu4e~mark-check-target target) "+S-u-N"))
|
||||
|
||||
(delq (assq 'delete mu4e-marks) mu4e-marks)
|
||||
(setf (alist-get 'trash mu4e-marks)
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (_target msg) (mu4e-get-trash-folder msg))
|
||||
:action #'+email--mark-seen)
|
||||
;; Refile will be my "archive" function.
|
||||
(alist-get 'refile mu4e-marks)
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (_target msg) (mu4e-get-trash-folder msg))
|
||||
:action #'+email--mark-seen))
|
||||
|
||||
;; 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.
|
||||
(defun +email|gmail-fix-flags (mark msg)
|
||||
(pcase mark
|
||||
(`trash (mu4e-action-retag-message msg "-\\Inbox,+\\Trash,-\\Draft"))
|
||||
(`refile (mu4e-action-retag-message msg "-\\Inbox"))
|
||||
(`flag (mu4e-action-retag-message msg "+\\Starred"))
|
||||
(`unflag (mu4e-action-retag-message msg "-\\Starred"))))
|
||||
(add-hook 'mu4e-mark-execute-pre-hook #'+email|gmail-fix-flags))
|
|
@ -209,10 +209,10 @@
|
|||
:desc "Add cursor w/mouse" "<mouse-1>" #'mc/add-cursor-on-click))
|
||||
|
||||
;; APPs
|
||||
(:when (featurep! :app email)
|
||||
(:prefix ("M" . "email")
|
||||
:desc "Open email app" "M" #'=email
|
||||
:desc "Compose email" "c" #'+email/compose))
|
||||
(:when (featurep! :email mu4e)
|
||||
(:prefix ("M" . "mu4e")
|
||||
:desc "Open email app" "M" #'=mu4e
|
||||
:desc "Compose email" "c" #'+mu4e/compose))
|
||||
|
||||
(:when (featurep! :app irc)
|
||||
(:prefix ("I" . "irc")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#+TITLE: app/email
|
||||
#+TITLE: email/mu4e
|
||||
#+DATE: April 8, 2017
|
||||
#+SINCE: v2.0
|
||||
#+STARTUP: inlineimages
|
||||
|
@ -59,10 +59,10 @@ sudo pacman -S offlineimap
|
|||
|
||||
* Configuration
|
||||
** offlineimap
|
||||
This module uses =mbsync= by default. To change this, change ~+email-backend~:
|
||||
This module uses =mbsync= by default. To change this, change ~+mu4e-backend~:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp
|
||||
(setq +email-backend 'offlineimap)
|
||||
(setq +mu4e-backend 'offlineimap)
|
||||
#+END_SRC
|
||||
|
||||
Then you must set up offlineimap and index your mail:
|
||||
|
@ -76,7 +76,7 @@ Then you must set up offlineimap and index your mail:
|
|||
Then configure Emacs to use your email address:
|
||||
|
||||
#+BEGIN_SRC emacs-lisp :tangle no
|
||||
;; Each path is relative to `+email-mu4e-mail-path', which is ~/.mail by default
|
||||
;; Each path is relative to `+mu4e-mu4e-mail-path', which is ~/.mail by default
|
||||
(set-email-account! "Lissner.net"
|
||||
'((mu4e-sent-folder . "/Lissner.net/Sent Mail")
|
||||
(mu4e-drafts-folder . "/Lissner.net/Drafts")
|
|
@ -1,4 +1,4 @@
|
|||
;;; app/email/autoload/email.el -*- lexical-binding: t; -*-
|
||||
;;; email/mu4e/autoload/email.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autodef
|
||||
(defun set-email-account! (label letvars &optional default-p)
|
||||
|
@ -42,24 +42,24 @@ default/fallback account."
|
|||
|
||||
|
||||
|
||||
(defvar +email-workspace-name "*mu4e*"
|
||||
(defvar +mu4e-workspace-name "*mu4e*"
|
||||
"TODO")
|
||||
|
||||
(add-hook 'mu4e-main-mode-hook #'+email|init)
|
||||
(add-hook 'mu4e-main-mode-hook #'+mu4e|init)
|
||||
|
||||
;;;###autoload
|
||||
(defun =email ()
|
||||
(defun =mu4e ()
|
||||
"Start email client."
|
||||
(interactive)
|
||||
(require 'mu4e)
|
||||
(+workspace-switch +email-workspace-name t)
|
||||
(+workspace-switch +mu4e-workspace-name t)
|
||||
(mu4e~start 'mu4e~main-view)
|
||||
;; (save-selected-window
|
||||
;; (prolusion-mail-show))
|
||||
)
|
||||
|
||||
;;;###autoload
|
||||
(defun +email/compose ()
|
||||
(defun +mu4e/compose ()
|
||||
"Compose a new email."
|
||||
(interactive)
|
||||
;; TODO Interactively select email account
|
||||
|
@ -69,11 +69,10 @@ default/fallback account."
|
|||
;;
|
||||
;; Hooks
|
||||
|
||||
(defun +email|init ()
|
||||
(add-hook 'kill-buffer-hook #'+email|kill-mu4e nil t))
|
||||
(defun +mu4e|init ()
|
||||
(add-hook 'kill-buffer-hook #'+mu4e|kill-mu4e nil t))
|
||||
|
||||
(defun +email|kill-mu4e ()
|
||||
(defun +mu4e|kill-mu4e ()
|
||||
;; (prolusion-mail-hide)
|
||||
(when (+workspace-exists-p +email-workspace-name)
|
||||
(+workspace/delete +email-workspace-name)))
|
||||
|
||||
(when (+workspace-exists-p +mu4e-workspace-name)
|
||||
(+workspace/delete +mu4e-workspace-name)))
|
|
@ -1,8 +1,8 @@
|
|||
;; app/email/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;; email/mu4e/autoload/evil.el -*- lexical-binding: t; -*-
|
||||
;;;###if (featurep! :editor evil)
|
||||
|
||||
;;;###autoload
|
||||
(defun +email/mark (&optional beg end)
|
||||
(defun +mu4e/mark (&optional beg end)
|
||||
"Mark all messages within the current selection in mu4e's header view. Uses
|
||||
`this-command-keys' to see what flag you mean."
|
||||
(interactive)
|
|
@ -1,15 +1,11 @@
|
|||
;;; app/email/config.el -*- lexical-binding: t; -*-
|
||||
;;; email/mu4e/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; I want to live in Emacs. Living is incomplete without email, so Emacs needs
|
||||
;; to give me the ability to read, search, write and send my email. It does so
|
||||
;; with `mu4e', and requires `offlineimap' and `mu' to be installed.
|
||||
|
||||
(defvar +email-backend 'mbsync
|
||||
(defvar +mu4e-backend 'mbsync
|
||||
"Which backend to use. Can either be offlineimap, mbsync or nil (manual).")
|
||||
|
||||
|
||||
;;
|
||||
;; Packages
|
||||
;;; Packages
|
||||
|
||||
(add-to-list 'auto-mode-alist '("\\.\\(?:offlineimap\\|mbsync\\)rc\\'" . conf-mode))
|
||||
|
||||
|
@ -22,7 +18,7 @@
|
|||
mu4e-attachment-dir "~/.mail/.attachments"
|
||||
mu4e-user-mail-address-list nil)
|
||||
:config
|
||||
(pcase +email-backend
|
||||
(pcase +mu4e-backend
|
||||
(`mbsync
|
||||
(setq mu4e-get-mail-command "mbsync -a"
|
||||
mu4e-change-filenames-when-moving t))
|
||||
|
@ -93,8 +89,8 @@
|
|||
(format "%s" (substring maildir 1 (string-match-p "/" maildir 1)))))))
|
||||
|
||||
;; Refresh the current view after marks are executed
|
||||
(defun +email*refresh (&rest _) (mu4e-headers-rerun-search))
|
||||
(advice-add #'mu4e-mark-execute-all :after #'+email*refresh)
|
||||
(defun +mu4e*refresh (&rest _) (mu4e-headers-rerun-search))
|
||||
(advice-add #'mu4e-mark-execute-all :after #'+mu4e*refresh)
|
||||
|
||||
(when (featurep! :tools flyspell)
|
||||
(add-hook 'mu4e-compose-mode-hook #'flyspell-mode))
|
||||
|
@ -134,6 +130,49 @@
|
|||
|
||||
|
||||
;;
|
||||
;; Sub-modules
|
||||
;;; Gmail integration
|
||||
|
||||
(if (featurep! +gmail) (load! "+gmail"))
|
||||
(when (featurep! +gmail)
|
||||
(after! mu4e
|
||||
;; don't save message to Sent Messages, Gmail/IMAP takes care of this
|
||||
(setq mu4e-sent-messages-behavior 'delete
|
||||
|
||||
;; 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)
|
||||
|
||||
;; 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"))
|
||||
|
||||
(delq (assq 'delete mu4e-marks) mu4e-marks)
|
||||
(setf (alist-get 'trash mu4e-marks)
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (_target msg) (mu4e-get-trash-folder msg))
|
||||
:action #'+mu4e--mark-seen)
|
||||
;; Refile will be my "archive" function.
|
||||
(alist-get 'refile mu4e-marks)
|
||||
(list :char '("d" . "▼")
|
||||
:prompt "dtrash"
|
||||
:dyn-target (lambda (_target msg) (mu4e-get-trash-folder msg))
|
||||
:action #'+mu4e--mark-seen))
|
||||
|
||||
;; 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.
|
||||
(defun +mu4e|gmail-fix-flags (mark msg)
|
||||
(pcase mark
|
||||
(`trash (mu4e-action-retag-message msg "-\\Inbox,+\\Trash,-\\Draft"))
|
||||
(`refile (mu4e-action-retag-message msg "-\\Inbox"))
|
||||
(`flag (mu4e-action-retag-message msg "+\\Starred"))
|
||||
(`unflag (mu4e-action-retag-message msg "-\\Starred"))))
|
||||
(add-hook 'mu4e-mark-execute-pre-hook #'+mu4e|gmail-fix-flags)))
|
|
@ -1,5 +1,4 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/email/packages.el
|
||||
;;; email/mu4e/packages.el
|
||||
|
||||
(package! mu4e-maildirs-extension)
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
;;; app/notmuch/autoload.el -*- lexical-binding: t; -*-
|
||||
;;; email/notmuch/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defun =notmuch ()
|
|
@ -1,4 +1,4 @@
|
|||
;;; app/notmuch/config.el -*- lexical-binding: t; -*-
|
||||
;;; email/notmuch/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
;; FIXME This module is a WIP!
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/notmuch/packages.el
|
||||
;;; email/notmuch/packages.el
|
||||
|
||||
(package! notmuch)
|
||||
(package! org-mime)
|
4
modules/email/wanderlust/autoload.el
Normal file
4
modules/email/wanderlust/autoload.el
Normal file
|
@ -0,0 +1,4 @@
|
|||
;;; email/wanderlust/autoload.el -*- lexical-binding: t; -*-
|
||||
|
||||
;;;###autoload
|
||||
(defalias '=wanderlust #'wl)
|
78
modules/email/wanderlust/config.el
Normal file
78
modules/email/wanderlust/config.el
Normal file
|
@ -0,0 +1,78 @@
|
|||
;;; app/wanderlust/config.el -*- lexical-binding: t; -*-
|
||||
|
||||
(def-package! wl
|
||||
:defer t
|
||||
:config
|
||||
(setq mail-user-agent 'wl-user-agent
|
||||
pgg-scheme 'gpg
|
||||
mime-edit-split-message nil)
|
||||
|
||||
(when (fboundp 'define-mail-user-agent)
|
||||
(define-mail-user-agent
|
||||
'wl-user-agent
|
||||
'wl-user-agent-compose
|
||||
'wl-draft-send
|
||||
'wl-draft-kill
|
||||
'mail-send-hook))
|
||||
|
||||
(setq wl-init-file (expand-file-name "wl.el" doom-private-dir))
|
||||
|
||||
(setq wl-demo nil
|
||||
wl-interactive-exit t
|
||||
wl-interactive-send t
|
||||
wl-stay-folder-window t
|
||||
wl-folders-file (expand-file-name "folders.wl" doom-private-dir)
|
||||
wl-x-face-file (expand-file-name "xface" doom-private-dir)
|
||||
wl-draft-folder "%INBOX.drafts"
|
||||
wl-fcc "%INBOX.Sent")
|
||||
|
||||
(setq wl-message-truncate-lines t
|
||||
wl-summary-width 120
|
||||
wl-from (format "%s <%s>" user-full-name user-mail-address)
|
||||
;; wl-organization "Secret Conspiracy"
|
||||
wl-local-domain (cadr (split-string user-mail-address "@"))
|
||||
wl-message-ignored-field-list
|
||||
'(".*Received:"
|
||||
".*Path:"
|
||||
".*Id:"
|
||||
"^References:"
|
||||
"^Replied:"
|
||||
"^Errors-To:"
|
||||
"^Lines:"
|
||||
"^Sender:"
|
||||
".*Host:"
|
||||
"^Xref:"
|
||||
"^Content-Type:"
|
||||
"^Precedence:"
|
||||
"^Status:"
|
||||
"^X.*:"
|
||||
"^MIME.*:"
|
||||
"^In-Reply-To:"
|
||||
"^Content-Transfer-Encoding:"
|
||||
"^List-.*:"))
|
||||
|
||||
(setq wl-message-visible-field-list '("^Message-Id:" "^User-Agent:" "^X-Mailer:" "^X-Face:"))
|
||||
|
||||
(when (featurep! +gmail)
|
||||
(setq elmo-imap4-default-server "imap.gmail.com"
|
||||
elmo-imap4-default-port 993
|
||||
elmo-imap4-default-authenticate-type 'clear ; CRAM-MD5
|
||||
elmo-imap4-default-user ""
|
||||
elmo-imap4-default-stream-type 'ssl
|
||||
elmo-imap4-set-seen-flag-explicitly t)
|
||||
|
||||
(setq wl-smtp-connection-type 'starttls
|
||||
wl-smtp-posting-port 587
|
||||
wl-smtp-authenticate-type "plain"
|
||||
wl-smtp-posting-user ""
|
||||
wl-smtp-posting-server "smtp.gmail.com"))
|
||||
|
||||
(setq wl-message-id-domain wl-local-domain)
|
||||
|
||||
(when (featurep! :editor evil)
|
||||
;; Neither wl-folder-mode or wl-summary-mode are correctly defined as major
|
||||
;; modes, so `evil-set-initial-state' won't work here.
|
||||
(add-hook! '(wl-folder-mode-hook wl-summary-mode)
|
||||
#'evil-emacs-state))
|
||||
|
||||
(add-hook 'mime-edit-mode-hook #'auto-fill-mode))
|
4
modules/email/wanderlust/packages.el
Normal file
4
modules/email/wanderlust/packages.el
Normal file
|
@ -0,0 +1,4 @@
|
|||
;; -*- no-byte-compile: t; -*-
|
||||
;;; app/wanderlust/packages.el
|
||||
|
||||
(package! wanderlust)
|
Loading…
Add table
Add a link
Reference in a new issue