diff --git a/+mail.el b/+mail.el new file mode 100644 index 0000000..5e2b144 --- /dev/null +++ b/+mail.el @@ -0,0 +1,143 @@ +;;; +mail.el -*- lexical-binding: t; -*- + +(setq +mu4e-personal-addresses '("me@maxschlueter.com" + "maxsc@fsfe.org")) + +(set-email-account! "mailbox.org" + '((mu4e-sent-folder . "/mailbox.org/Sent") + (mu4e-drafts-folder . "/mailbox.org/Drafts") + (mu4e-trash-folder . "/mailbox.org/Trash") + (mu4e-refile-folder . "/mailbox.org/Archive") + (smtpmail-smtp-user . "me@maxschlueter.com") + (mu4e-maildir-shortcuts + (:maildir "/mailbox.org/Inbox" :key ?i) + (:maildir "/mailbox.org/Sent" :key ?s) + (:maildir "/mailbox.org/Drafts" :key ?d) + (:maildir "/mailbox.org/Trash" :key ?t) + (:maildir "/mailbox.org/Archive" :key ?a)) + (mu4e-compose-signature . nil)) + t) + +(after! mu4e + ;; Recommended msmtp config from doom module documentation + (setq sendmail-program (executable-find "msmtp") + send-mail-function #'smtpmail-send-it + message-sendmail-f-is-evil t + message-sendmail-extra-arguments '("--read-envelope-from") + message-send-mail-function #'message-send-mail-with-sendmail) + ;; fix https://github.com/hlissner/doom-emacs/issues/3294 + (setq mu4e-attachment-dir "~/Downloads") + + ;; Sign sent email automatically + ;; (add-hook 'message-send-hook 'mml-secure-message-sign-smime) + + (setq mml-secure-openpgp-encrypt-to-self t) + + ;; Render buttons to verify&decrypt messages + (setq mm-decrypt-option 'always + mm-verify-option 'always + gnus-buttonized-mime-types '("multipart/encrypted" "multipart/signed")) + + (defun max/mu4e-view-import-attachment-calendar (msg attnum) + (let* ((att (mu4e~view-get-attach msg attnum)) + (index (plist-get att :index)) + (docid (mu4e-message-field msg :docid)) + (mtype (plist-get att :mime-type)) + (fname (plist-get att :name)) + (fpath (concat (mu4e~get-attachment-dir fname mtype) "/" fname))) + (if (string= "text/calendar" mtype) + (progn (mu4e~proc-extract 'save docid index mu4e-decryption-policy fpath) + (let ((org-caldav-inbox (max/org-caldav-get-inbox))) + (org-caldav-import-ics-to-org fpath))) + (mu4e-error "Invalid mime-type for a calendar event: `%s'" mtype)))) + ;; XXX + (add-to-list 'mu4e-view-attachment-actions + '("cImport in calendar" . max/mu4e-view-import-attachment-calendar) t) + (add-to-list 'mu4e-bookmarks + (make-mu4e-bookmark + :name "All Inboxes" + :query "maildir:/mailbox.org/Inbox" + :key ?i))) + +;; Autoload this command so that the mbsync service can update the index +(autoload #'mu4e-update-index "mu4e" nil t) + +(defun max/=mu4e () + "Start email client and view all inboxes." + (interactive) + (require 'mu4e) + (+workspace-switch +mu4e-workspace-name t) + (mu4e~start (lambda () (mu4e-headers-search (mu4e-get-bookmark-query ?i))))) + +(map! "" #'max/=mu4e) + +(map! :after mu4e + :map mu4e-headers-mode-map + :vne "l" #'max/capture-msg-to-agenda) + +(setq +org-capture-emails-file (expand-file-name "newgtd/actionable.org" org-directory)) + +;; Modified version of `+mu4e/capture-msg-to-agenda'. +(defun max/capture-msg-to-agenda (arg) + "Refile a message and add a entry in `+org-capture-emails-file'." + (interactive "p") + (let ((sec "^* Actions") + (msg (mu4e-message-at-point))) + (when msg + ;; put the message in the agenda + (with-current-buffer (find-file-noselect + (expand-file-name +org-capture-emails-file org-directory)) + (save-excursion + ;; find header section + (goto-char (point-min)) + (when (re-search-forward sec nil t) + (let (org-M-RET-may-split-line + (lev (org-outline-level)) + (folded-p (invisible-p (point-at-eol))) + (from (plist-get msg :from))) + ;; (when (consp (car from)) ; Occurs when using mu4e 1.8+. + ;; (setq from (car from))) + (unless (keywordp (car from)) ; If using mu4e <= 1.6. + (setq from (list :name (or (caar from) (cdar from))))) + ;; place the subheader + (when folded-p (show-branches)) ; unfold if necessary + (org-end-of-meta-data) ; skip property drawer + (org-insert-heading) ; insert a todo heading + (when (= (org-outline-level) lev) ; demote if necessary + (org-do-demote)) + ;; insert message and add deadline + (insert (concat "NEXT Reply to " + "[[mu4e:msgid:" + (plist-get msg :message-id) "][" + (truncate-string-to-width + (plist-get from :name) 25 nil nil t) + " - " + (truncate-string-to-width + (plist-get msg :subject) 40 nil nil t) + "]] :email:\n")) + (org-time-stamp-inactive '(16)) + + (org-update-parent-todo-statistics) + + ;; refold as necessary + (if folded-p + (progn + (org-up-heading-safe) + (hide-subtree)) + (hide-entry)))))) + ;; refile the message and update + ;; (cond ((eq major-mode 'mu4e-view-mode) + ;; (mu4e-view-mark-for-refile)) + ;; ((eq major-mode 'mu4e-headers-mode) + ;; (mu4e-headers-mark-for-refile))) + (message "Added \"%s\" to the agenda" + (truncate-string-to-width + (plist-get msg :subject) 40 nil nil t))))) + +(use-package! jl-encrypt + :config + (setq mml-secure-insert-signature 'encrypted)) + +(after! mu4e-alert + (when IS-MAC + (mu4e-alert-set-default-style 'notifier))) diff --git a/config.el b/config.el index 5500819..d21378d 100644 --- a/config.el +++ b/config.el @@ -568,157 +568,6 @@ the inbox. Refile to any org-gtd incubate target (see manual)." ;;; (after! org-roam ;;; (advice-add #'display-buffer-pop-up-frame :before #'org-roam-protocol-open-ref)) -;;; Autoload this command so that the mbsync service can update the index -(autoload #'mu4e-update-index "mu4e" nil t) - -(defun max/=mu4e () - "Start email client and view all inboxes." - (interactive) - (require 'mu4e) - (+workspace-switch +mu4e-workspace-name t) - (mu4e~start (lambda () (mu4e-headers-search (mu4e-get-bookmark-query ?i))))) - -(map! "" #'max/=mu4e) - -(after! yasnippet - (setq yas-triggers-in-field t)) - -;; http://pragmaticemacs.com/emacs/email-templates-in-mu4e-with-yasnippet/ -(defun bjm/mu4e-get-names-for-yasnippet () - "Return comma separated string of names for an email" - (interactive) - (let ((email-name "") str email-string email-list email-name2 tmpname) - (save-excursion - (goto-char (point-min)) - ;; first line in email could be some hidden line containing NO to field - (setq str (buffer-substring-no-properties (point-min) (point-max)))) - ;; take name from TO field - match series of names - (when (string-match "^To: \"?\\(.+\\)" str) - (setq email-string (match-string 1 str))) - ;;split to list by comma - (setq email-list (split-string email-string " *, *")) - ;;loop over emails - (dolist (tmpstr email-list) - ;;get first word of email string - (setq tmpname (car (split-string tmpstr " "))) - ;;remove whitespace or "" - (setq tmpname (replace-regexp-in-string "[ \"]" "" tmpname)) - ;;join to string - (setq email-name - (concat email-name ", " tmpname))) - ;;remove initial comma - (setq email-name (replace-regexp-in-string "^, " "" email-name)) - - ;;see if we want to use the name in the FROM field - ;;get name in FROM field if available, but only if there is only - ;;one name in TO field - (if (< (length email-list) 2) - (when (string-match "^\\([^ ,\n]+\\).+writes:$" str) - (progn (setq email-name2 (match-string 1 str)) - ;;prefer name in FROM field if TO field has "@" - (when (string-match "@" email-name) - (setq email-name email-name2)) - ))) - email-name)) - -(setq +org-capture-emails-file (expand-file-name "newgtd/inbox.org" org-directory)) - -(after! mu4e - (map! :map mu4e-headers-mode-map - :vne "l" #'max/capture-msg-to-agenda)) - -(defun max/capture-msg-to-agenda (arg) - "Refile a message and add a entry in `+org-capture-emails-file'." - (interactive "p") - (let ((msg (mu4e-message-at-point))) - (when msg - ;; put the message in the agenda - (with-current-buffer (find-file-noselect - (expand-file-name +org-capture-emails-file org-directory)) - (save-excursion - (goto-char (point-max)) - (outline-back-to-heading) - (org-insert-heading) - (let ((from (plist-get msg :from))) - (insert (concat "Reply to " - "[[mu4e:msgid:" - (plist-get msg :message-id) "][" - (truncate-string-to-width - (or (caar from) (cdar from)) 25 nil nil t) - " - " - (truncate-string-to-width - (plist-get msg :subject) 40 nil nil t) - "]]\n" - )) - (org-time-stamp-inactive '(16))))) - (message "Refiled \"%s\"" - (truncate-string-to-width - (plist-get msg :subject) 40 nil nil t))))) - -(after! mu4e - (setq mu4e-maildir "~/Maildir") - ;; Recommended msmtp config from doom module documentation - (setq sendmail-program (executable-find "msmtp") - send-mail-function #'smtpmail-send-it - message-sendmail-f-is-evil t - message-sendmail-extra-arguments '("--read-envelope-from") - message-send-mail-function #'message-send-mail-with-sendmail) - ;; fix https://github.com/hlissner/doom-emacs/issues/3294 - (setq mu4e-attachment-dir "~/Downloads") - - (defun max/mu4e-view-import-attachment-calendar (msg attnum) - (let* ((att (mu4e~view-get-attach msg attnum)) - (index (plist-get att :index)) - (docid (mu4e-message-field msg :docid)) - (mtype (plist-get att :mime-type)) - (fname (plist-get att :name)) - (fpath (concat (mu4e~get-attachment-dir fname mtype) "/" fname))) - (if (string= "text/calendar" mtype) - (progn (mu4e~proc-extract 'save docid index mu4e-decryption-policy fpath) - (let ((org-caldav-inbox (max/org-caldav-get-inbox))) - (org-caldav-import-ics-to-org fpath))) - (mu4e-error "Invalid mime-type for a calendar event: `%s'" mtype)))) - - (add-to-list 'mu4e-view-attachment-actions - '("cImport in calendar" . max/mu4e-view-import-attachment-calendar) t) - (after! mu4e-alert - (when IS-MAC - (mu4e-alert-set-default-style 'notifier))) - (add-to-list 'mu4e-bookmarks - (make-mu4e-bookmark - :name "All Inboxes" - :query "maildir:/mailbox.org/Inbox OR maildir:/uni-potsdam.de/Inbox" - :key ?i)) -) - -(set-email-account! "mailbox.org" - '((mu4e-sent-folder . "/mailbox.org/Sent") - (mu4e-drafts-folder . "/mailbox.org/Drafts") - (mu4e-trash-folder . "/mailbox.org/Trash") - (mu4e-refile-folder . "/mailbox.org/Archive") - (smtpmail-smtp-user . "me@maxschlueter.com") - (mu4e-maildir-shortcuts - (:maildir "/mailbox.org/Inbox" :key ?i) - (:maildir "/mailbox.org/Sent" :key ?s) - (:maildir "/mailbox.org/Drafts" :key ?d) - (:maildir "/mailbox.org/Trash" :key ?t) - (:maildir "/mailbox.org/Archive" :key ?a)) - (mu4e-compose-signature . nil)) - t) - -(set-email-account! "uni-potsdam.de" - '((mu4e-sent-folder . "/uni-potsdam.de/Sent") - (mu4e-drafts-folder . "/uni-potsdam.de/Drafts") - (mu4e-trash-folder . "/uni-potsdam.de/Trash") - (mu4e-refile-folder . "/uni-potsdam.de/Archive") - (smtpmail-smtp-user . "mschlueter@uni-potsdam.de") - (mu4e-maildir-shortcuts - (:maildir "/uni-potsdam.de/Inbox" :key ?i) - (:maildir "/uni-potsdam.de/Sent" :key ?s) - (:maildir "/uni-potsdam.de/Drafts" :key ?d) - (:maildir "/uni-potsdam.de/Trash" :key ?t) - (:maildir "/uni-potsdam.de/Archive" :key ?a)) - (mu4e-compose-signature . nil))) (setq +latex-viewers '(pdf-tools)) @@ -784,3 +633,6 @@ the inbox. Refile to any org-gtd incubate target (see manual)." ;;; (after! calfw-org ;;; (autoload #'cfw:org-create-file-source "cfw:org-create-file-source")) + +;; load personal modules +(load! "+mail")