From 0f7800b9d132ee457e9323e1ecc5c148bb846553 Mon Sep 17 00:00:00 2001 From: "Itai Y. Efrat" Date: Mon, 28 Jun 2021 18:07:00 +0300 Subject: [PATCH 001/119] Bump org-msg jeremy-compostella/org-msg@557d490 -> jeremy-compostella/org-msg@2db6725 Reverts the version of org-msg to what it was in the beginning of the mu4e pr. Also reverts back to using `org-msg-text-plain-alternative` due to this. --- modules/email/mu4e/config.el | 2 +- modules/email/mu4e/packages.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index bf7e46cd4..f5ee2f240 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -111,7 +111,7 @@ :config (setq org-msg-startup "inlineimages" org-msg-greeting-name-limit 3 - org-msg-default-alternatives '(html text))) + org-msg-text-plain-alternative t)) diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index bcb8a4a2a..61c1ffa1b 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -1,4 +1,4 @@ ;; -*- no-byte-compile: t; -*- ;;; email/mu4e/packages.el -(package! org-msg :pin "b0765b2d0bc06cdd1fd78836ef958eb81e603dd1") +(package! org-msg :pin "2db6725c4a4f4342a9c61895b7c3c82795b01fee") From a29704a194b8b74538a2b1df9362452123907be4 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 00:00:39 +0800 Subject: [PATCH 002/119] Mu4e: Feature gate org-msg package --- modules/email/mu4e/config.el | 14 +++++++------- modules/email/mu4e/packages.el | 3 ++- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index f5ee2f240..1a87d7f8a 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -105,13 +105,13 @@ :desc "save draft" "S" #'message-dont-send :desc "attach" "a" #'mail-add-attachment)) - -(use-package! org-msg - :hook (mu4e-compose-pre . org-msg-mode) - :config - (setq org-msg-startup "inlineimages" - org-msg-greeting-name-limit 3 - org-msg-text-plain-alternative t)) +(when (featurep! :lang org) + (use-package! org-msg + :hook (org-load . org-msg-mode) + :config + (setq org-msg-startup "inlineimages" + org-msg-greeting-name-limit 3 + org-msg-text-plain-alternative t))) diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index 61c1ffa1b..2be20229a 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -1,4 +1,5 @@ ;; -*- no-byte-compile: t; -*- ;;; email/mu4e/packages.el -(package! org-msg :pin "2db6725c4a4f4342a9c61895b7c3c82795b01fee") +(when (featurep! :lang org) + (package! org-msg :pin "2db6725c4a4f4342a9c61895b7c3c82795b01fee")) From 3f765787213145b461e012566c294962f28176c0 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 00:22:04 +0800 Subject: [PATCH 003/119] Mu4e: Use Gnus HTML rendering --- modules/email/mu4e/config.el | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 1a87d7f8a..669bf6574 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -34,6 +34,7 @@ ;; try to show images mu4e-view-show-images t mu4e-view-image-max-width 800 + mu4e-view-use-gnus t ; the way of the future: https://github.com/djcb/mu/pull/1442#issuecomment-591695814 ;; configuration for sending mail message-send-mail-function #'smtpmail-send-it smtpmail-stream-type 'starttls From 9f044717bdbc6205897c5e3e37a7279bacef0375 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 00:23:01 +0800 Subject: [PATCH 004/119] Mu4e: Revamp the header view icons --- modules/email/mu4e/config.el | 70 +++++++++++++++++++++++++++++------- 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 669bf6574..c48b48699 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -62,19 +62,63 @@ ;; set mail user agent (setq mail-user-agent 'mu4e-user-agent) - ;; Use fancy icons - (setq mu4e-use-fancy-chars t - mu4e-headers-draft-mark '("D" . "") - mu4e-headers-flagged-mark '("F" . "") - mu4e-headers-new-mark '("N" . "") - mu4e-headers-passed-mark '("P" . "") - mu4e-headers-replied-mark '("R" . "") - mu4e-headers-seen-mark '("S" . "") - mu4e-headers-trashed-mark '("T" . "") - mu4e-headers-attach-mark '("a" . "") - mu4e-headers-encrypted-mark '("x" . "") - mu4e-headers-signed-mark '("s" . "") - mu4e-headers-unread-mark '("u" . "")) + ;;---------------- + ;; Icons + ;;---------------- + + ;; Icons need a bit of work + ;; Spacing needs to be determined and adjucted + + (defun +get-string-width (str) + "Return the width in pixels of a string in the current +window's default font. If the font is mono-spaced, this +will also be the width of all other printable characters." + (let ((window (selected-window)) + (remapping face-remapping-alist)) + (with-temp-buffer + (make-local-variable 'face-remapping-alist) + (setq face-remapping-alist remapping) + (set-window-buffer window (current-buffer)) + (insert str) + (car (window-text-pixel-size))))) + + (cl-defun mu4e~normalised-icon (name &key set colour height v-adjust) + "Convert :icon declaration to icon" + (let* ((icon-set (intern (concat "all-the-icons-" (or set "faicon")))) + (v-adjust (or v-adjust 0.02)) + (height (or height 0.8)) + (icon (if colour + (apply icon-set `(,name :face ,(intern (concat "all-the-icons-" colour)) :height ,height :v-adjust ,v-adjust)) + (apply icon-set `(,name :height ,height :v-adjust ,v-adjust)))) + (icon-width (+get-string-width icon)) + (space-width (+get-string-width " ")) + (space-factor (- 2 (/ (float icon-width) space-width)))) + (concat (propertize " " 'display `(space . (:width ,space-factor))) icon))) + + ;; Set up all the fancy icons + (defun mu4e~initialise-icons () + (setq mu4e-use-fancy-chars t + mu4e-headers-draft-mark (cons "D" (mu4e~normalised-icon "pencil")) + mu4e-headers-flagged-mark (cons "F" (mu4e~normalised-icon "flag")) + mu4e-headers-new-mark (cons "N" (mu4e~normalised-icon "sync" :set "material" :height 0.8 :v-adjust -0.10)) + mu4e-headers-passed-mark (cons "P" (mu4e~normalised-icon "arrow-right")) + mu4e-headers-replied-mark (cons "R" (mu4e~normalised-icon "arrow-right")) + mu4e-headers-seen-mark (cons "S" "") ;(mu4e~normalised-icon "eye" :height 0.6 :v-adjust 0.07 :colour "dsilver")) + mu4e-headers-trashed-mark (cons "T" (mu4e~normalised-icon "trash")) + mu4e-headers-attach-mark (cons "a" (mu4e~normalised-icon "file-text-o" :colour "silver")) + mu4e-headers-encrypted-mark (cons "x" (mu4e~normalised-icon "lock")) + mu4e-headers-signed-mark (cons "s" (mu4e~normalised-icon "certificate" :height 0.7 :colour "dpurple")) + mu4e-headers-unread-mark (cons "u" (mu4e~normalised-icon "eye-slash" :v-adjust 0.05)))) + + ;; Set the icons only when a graphical frame has been created + (if (display-graphic-p) + (mu4e~initialise-icons) + ;; When it's the server, wait till the first graphical frame + (add-hook! 'server-after-make-frame-hook + (defun mu4e~initialise-icons-hook () + (when (display-graphic-p) + (mu4e~initialise-icons) + (remove-hook #'mu4e~initialise-icons-hook))))) ;; Add a column to display what email account the email belongs to. (add-to-list 'mu4e-header-info-custom From 65d743926bd519284dd8744ef3333ee7fb9aa218 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 01:02:40 +0800 Subject: [PATCH 005/119] Mu4e: Set header fields to opinionated set - account is useful if you have multiple accounts ... which is most people as far as I can tell - the date is pretty important IMO - flags 2-wide due to the extra space, so 6 fits 3 flags - hey, the subject - that could be of interest Oh, and since :flags is 6 wide there's no good reason to abbreviate it The initial space is to make the icon alignment work nicer visually --- modules/email/mu4e/config.el | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index c48b48699..93c7f8d45 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -120,6 +120,15 @@ will also be the width of all other printable characters." (mu4e~initialise-icons) (remove-hook #'mu4e~initialise-icons-hook))))) + (setq mu4e-headers-fields + '((:account . 12) + (:human-date . 8) + (:flags . 6) ; 3 icon flags + (:from . 25) + (:subject)) + + (plist-put (cdr (assoc :flags mu4e-header-info)) :shortname " Flags") ; default=Flgs + ;; Add a column to display what email account the email belongs to. (add-to-list 'mu4e-header-info-custom '(:account From 9b9f64d9121bb989087b492ec8208b91f2a01077 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 01:22:29 +0800 Subject: [PATCH 006/119] Mu4e: Fancify headers Add accounts name colourisation (with a colourisation function + var of colours) and change the :recipnum header display while I'm at it. It doesn't deserve the default amount of space/attention. --- modules/email/mu4e/config.el | 57 +++++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 10 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 93c7f8d45..c19a4f728 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -120,6 +120,10 @@ will also be the width of all other printable characters." (mu4e~initialise-icons) (remove-hook #'mu4e~initialise-icons-hook))))) + ;;---------------- + ;; Header view + ;;---------------- + (setq mu4e-headers-fields '((:account . 12) (:human-date . 8) @@ -129,17 +133,50 @@ will also be the width of all other printable characters." (plist-put (cdr (assoc :flags mu4e-header-info)) :shortname " Flags") ; default=Flgs - ;; Add a column to display what email account the email belongs to. - (add-to-list 'mu4e-header-info-custom - '(:account - :name "Account" - :shortname "Account" - :help "Which account this email belongs to" - :function - (lambda (msg) - (let ((maildir (mu4e-message-field msg :maildir))) - (format "%s" (substring maildir 1 (string-match-p "/" maildir 1))))))) + ;; A header colourisation function/variable could be handy + (defun mu4e~header-colourise (str) + (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) + (colour (nth (% str-sum (length mu4e-header-colourised-faces)) + mu4e-header-colourised-faces))) + (put-text-property 0 (length str) 'face colour str) + str)) + (defvar mu4e~header-colourised-faces + '(all-the-icons-lblue + all-the-icons-purple + all-the-icons-blue-alt + all-the-icons-green + all-the-icons-maroon + all-the-icons-yellow + all-the-icons-orange)) + + ;; Add a column to display what email account the email belongs to. + (setq mu4e-header-info-custom + '((:account . + (:name "account" + :shortname "account" + :help "which account this email belongs to" + :function + (lambda (msg) + (let ((maildir + (mu4e-message-field msg :maildir))) + (mu4e-header-colourise + (replace-regexp-in-string + "^gmail" + (propertize "g" 'face 'bold-italic) + (format "%s" + (substring maildir 1 + (string-match-p "/" maildir 1))))))))) + (:recipnum . + (:name "Number of recipients" + :shortname " ⭷" + :help "Number of recipients for this message" + :function + (lambda (msg) + (propertize (format "%2d" + (+ (length (mu4e-message-field msg :to)) + (length (mu4e-message-field msg :cc)))) + 'face 'mu4e-footer-face))))))) (defadvice! +mu4e--refresh-current-view-a (&rest _) :after #'mu4e-mark-execute-all (mu4e-headers-rerun-search)) From 0f9765c600a27dcbd2f19868b04325136458f8a8 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 01:32:18 +0800 Subject: [PATCH 007/119] Mu4e: Expand frame to minimum size on header view --- modules/email/mu4e/config.el | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index c19a4f728..76c44b18e 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -177,6 +177,8 @@ will also be the width of all other printable characters." (+ (length (mu4e-message-field msg :to)) (length (mu4e-message-field msg :cc)))) 'face 'mu4e-footer-face))))))) + + ;; Marks usually affect the current view (defadvice! +mu4e--refresh-current-view-a (&rest _) :after #'mu4e-mark-execute-all (mu4e-headers-rerun-search)) @@ -186,6 +188,18 @@ will also be the width of all other printable characters." ;; Html mails might be better rendered in a browser (add-to-list 'mu4e-view-actions '("View in browser" . mu4e-action-view-in-browser)) + ;; The header view needs a certain amount of horizontal space to + ;; actually show you all the information you want to see + ;; so if the header view is entered from a narrow frame, + ;; it's probably worth trying to expand it + (defvar mu4e-min-header-frame-width 120 + "Minimum reasonable with for the header view.") + (defun mu4e-widen-frame-maybe () + "Expand the frame with if it's less than `mu4e-min-header-frame-width'." + (when (< (frame-width) mu4e-min-header-frame-width) + (set-frame-width (selected-frame) mu4e-min-header-frame-width))) + (add-hook 'mu4e-headers-mode-hook #'mu4e-widen-frame-maybe) + (when (fboundp 'imagemagick-register-types) (imagemagick-register-types)) From 74411c87b8367f9fc784a933eb24de2dd879c72f Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 01:35:59 +0800 Subject: [PATCH 008/119] Mu4e: Reduce unnecessary mu action masking by evil --- modules/email/mu4e/config.el | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 76c44b18e..f57f544ad 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -208,7 +208,16 @@ will also be the width of all other printable characters." :desc "send and exit" "s" #'message-send-and-exit :desc "kill buffer" "d" #'message-kill-buffer :desc "save draft" "S" #'message-dont-send - :desc "attach" "a" #'mail-add-attachment)) + :desc "attach" "a" #'mail-add-attachment) + ;; Due to evil, none of the marking commands work when making a visual selection in + ;; the headers view of mu4e. Without overriding any evil commands we may actually + ;; want to use in and evil selection, this can be easily fixed. + (when (featurep! :editor evil) + (map! :map mu4e-headers-mode-map + :v "*" #'mu4e-headers-mark-for-something + :v "!" #'mu4e-headers-mark-for-read + :v "?" #'mu4e-headers-mark-for-unread + :v "u" #'mu4e-headers-mark-for-unmark))) (when (featurep! :lang org) (use-package! org-msg From 66557c9fe48b74f0fd593edeee7935848968d0e0 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 01:52:38 +0800 Subject: [PATCH 009/119] Mu4e: add function for filing email to agenda --- modules/email/mu4e/config.el | 67 ++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index f57f544ad..60e8a26f0 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -203,6 +203,73 @@ will also be the width of all other printable characters." (when (fboundp 'imagemagick-register-types) (imagemagick-register-types)) + ;; Adding emails to the agenda + ;; Perfect for when you see an email you want to reply to + ;; later, but don't want to forget about + + (defun mu4e-msg-to-agenda (arg) + "Refile a message and add a entry in the agenda file with a +deadline. Default deadline is today. With one prefix, deadline +is tomorrow. With two prefixes, select the deadline." + (interactive "p") + (let ((file (car org-agenda-files)) + (sec "^* Email") + (msg (mu4e-message-at-point))) + (when msg + ;; put the message in the agenda + (with-current-buffer (find-file-noselect file) + (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)))) + ;; place the subheader + (when folded-p (show-branches)) ; unfold if necessary + (org-end-of-meta-data) ; skip property drawer + (org-insert-todo-heading 1) ; insert a todo heading + (when (= (org-outline-level) lev) ; demote if necessary + (org-do-demote)) + ;; insert message and add deadline + (insert (concat " Respond to " + "[[mu4e:msgid:" + (plist-get msg :message-id) "][" + (truncate-string-to-width + (caar (plist-get msg :from)) 25 nil nil t) + " - " + (truncate-string-to-width + (plist-get msg :subject) 40 nil nil t) + "]] ")) + (org-deadline nil + (cond ((= arg 1) (format-time-string "%Y-%m-%d")) + ((= arg 4) "+1d"))) + + (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 "Refiled \"%s\" and added to the agenda for %s" + (truncate-string-to-width + (plist-get msg :subject) 40 nil nil t) + (cond ((= arg 1) "today") + ((= arg 4) "tomorrow") + (t "later")))))) + + (map! :map mu4e-headers-mode-map + :e "l" #'mu4e-msg-to-agenda) + + ;; General keybindings + (map! :localleader :map mu4e-compose-mode-map :desc "send and exit" "s" #'message-send-and-exit From c73e903c0dee957bab977a01f83d1585d3aded9d Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 01:53:19 +0800 Subject: [PATCH 010/119] Mu4e: Use unicode to prettify the main view --- modules/email/mu4e/config.el | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 60e8a26f0..fee176fd7 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -284,7 +284,39 @@ is tomorrow. With two prefixes, select the deadline." :v "*" #'mu4e-headers-mark-for-something :v "!" #'mu4e-headers-mark-for-read :v "?" #'mu4e-headers-mark-for-unread - :v "u" #'mu4e-headers-mark-for-unmark))) + :v "u" #'mu4e-headers-mark-for-unmark + :vn "l" #'mu4e-msg-to-agenda)) + + ;;---------------- + ;; Prettifying mu4e:main + ;;---------------- + + (defadvice! mu4e~main-action-prettier-str (str &optional func-or-shortcut) + "Highlight the first occurrence of [.] in STR. +If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it +when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is +a string, execute the corresponding keyboard action when it is +clicked." + :override #'mu4e~main-action-str + (let ((newstr + (replace-regexp-in-string + "\\[\\(..?\\)\\]" + (lambda(m) + (format "%s" + (propertize (match-string 1 m) 'face '(mode-line-emphasis bold)))) + (replace-regexp-in-string "\t\\*" "\t⚫" str))) + (map (make-sparse-keymap)) + (func (if (functionp func-or-shortcut) + func-or-shortcut + (if (stringp func-or-shortcut) + (lambda()(interactive) + (execute-kbd-macro func-or-shortcut)))))) + (define-key map [mouse-2] func) + (define-key map (kbd "RET") func) + (put-text-property 0 (length newstr) 'keymap map newstr) + (put-text-property (string-match "[A-Za-z].+$" newstr) + (- (length newstr) 1) 'mouse-face 'highlight newstr) + newstr))) (when (featurep! :lang org) (use-package! org-msg From e3a926946e8a1bef0a315225240dfec0452a6bfe Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 01:55:37 +0800 Subject: [PATCH 011/119] Mu4e: try to be pick a good account to send from --- modules/email/mu4e/config.el | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index fee176fd7..b45084b9c 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -287,6 +287,26 @@ is tomorrow. With two prefixes, select the deadline." :v "u" #'mu4e-headers-mark-for-unmark :vn "l" #'mu4e-msg-to-agenda)) + ;;---------------- + ;; Sending mail + ;;---------------- + + (defun my-mu4e-set-account () + "Set the account for composing a message. If a 'To' header is present, +and correspands to an email account, this account will be selected. +Otherwise, the user is prompted for the accound they wish to use." + (unless (and mu4e-compose-parent-message + (let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to)))) + (from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from))))) + (if (member to (plist-get mu4e~server-props :personal-addresses)) + (setq user-mail-address to) + (if (member from (plist-get mu4e~server-props :personal-addresses)) + (setq user-mail-address from) + nil)))) + (ivy-read "Account: " (plist-get mu4e~server-props :personal-addresses) :action (lambda (candidate) (setq user-mail-address candidate))))) + + (add-hook 'mu4e-compose-pre-hook 'my-mu4e-set-account) + ;;---------------- ;; Prettifying mu4e:main ;;---------------- From b386ea1f53b05be8fea3cc63b258101bc52c5dee Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 13:00:33 +0800 Subject: [PATCH 012/119] Mu4e: Oh, there's an autoload file I can use? --- modules/email/mu4e/autoload/email.el | 158 ++++++++++++++++++++++++ modules/email/mu4e/config.el | 172 +-------------------------- 2 files changed, 160 insertions(+), 170 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index f413207df..c54bfcb8c 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -71,6 +71,164 @@ default/fallback account." ;; TODO Interactively select email account (call-interactively #'mu4e-compose-new)) +;; Icons need a bit of work +;; Spacing needs to be determined and adjucted +;;;###autoload +(defun +get-string-width (str) + "Return the width in pixels of a string in the current +window's default font. If the font is mono-spaced, this +will also be the width of all other printable characters." + (let ((window (selected-window)) + (remapping face-remapping-alist)) + (with-temp-buffer + (make-local-variable 'face-remapping-alist) + (setq face-remapping-alist remapping) + (set-window-buffer window (current-buffer)) + (insert str) + (car (window-text-pixel-size))))) + +;;;###autoload +(cl-defun mu4e~normalised-icon (name &key set colour height v-adjust) + "Convert :icon declaration to icon" + (let* ((icon-set (intern (concat "all-the-icons-" (or set "faicon")))) + (v-adjust (or v-adjust 0.02)) + (height (or height 0.8)) + (icon (if colour + (apply icon-set `(,name :face ,(intern (concat "all-the-icons-" colour)) :height ,height :v-adjust ,v-adjust)) + (apply icon-set `(,name :height ,height :v-adjust ,v-adjust)))) + (icon-width (+get-string-width icon)) + (space-width (+get-string-width " ")) + (space-factor (- 2 (/ (float icon-width) space-width)))) + (concat (propertize " " 'display `(space . (:width ,space-factor))) icon))) + +;; Set up all the fancy icons +;;;###autoload +(defun mu4e~initialise-icons () + (setq mu4e-use-fancy-chars t + mu4e-headers-draft-mark (cons "D" (mu4e~normalised-icon "pencil")) + mu4e-headers-flagged-mark (cons "F" (mu4e~normalised-icon "flag")) + mu4e-headers-new-mark (cons "N" (mu4e~normalised-icon "sync" :set "material" :height 0.8 :v-adjust -0.10)) + mu4e-headers-passed-mark (cons "P" (mu4e~normalised-icon "arrow-right")) + mu4e-headers-replied-mark (cons "R" (mu4e~normalised-icon "arrow-right")) + mu4e-headers-seen-mark (cons "S" "") ;(mu4e~normalised-icon "eye" :height 0.6 :v-adjust 0.07 :colour "dsilver")) + mu4e-headers-trashed-mark (cons "T" (mu4e~normalised-icon "trash")) + mu4e-headers-attach-mark (cons "a" (mu4e~normalised-icon "file-text-o" :colour "silver")) + mu4e-headers-encrypted-mark (cons "x" (mu4e~normalised-icon "lock")) + mu4e-headers-signed-mark (cons "s" (mu4e~normalised-icon "certificate" :height 0.7 :colour "dpurple")) + mu4e-headers-unread-mark (cons "u" (mu4e~normalised-icon "eye-slash" :v-adjust 0.05)))) + +;;;###autoload +(defun mu4e~header-colourise (str) + (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) + (colour (nth (% str-sum (length mu4e-header-colourised-faces)) + mu4e-header-colourised-faces))) + (put-text-property 0 (length str) 'face colour str) + str)) + +;; Adding emails to the agenda +;; Perfect for when you see an email you want to reply to +;; later, but don't want to forget about +;;;###autoload +(defun mu4e-msg-to-agenda (arg) + "Refile a message and add a entry in the agenda file with a +deadline. Default deadline is today. With one prefix, deadline +is tomorrow. With two prefixes, select the deadline." + (interactive "p") + (let ((file (car org-agenda-files)) + (sec "^* Email") + (msg (mu4e-message-at-point))) + (when msg + ;; put the message in the agenda + (with-current-buffer (find-file-noselect file) + (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)))) + ;; place the subheader + (when folded-p (show-branches)) ; unfold if necessary + (org-end-of-meta-data) ; skip property drawer + (org-insert-todo-heading 1) ; insert a todo heading + (when (= (org-outline-level) lev) ; demote if necessary + (org-do-demote)) + ;; insert message and add deadline + (insert (concat " Respond to " + "[[mu4e:msgid:" + (plist-get msg :message-id) "][" + (truncate-string-to-width + (caar (plist-get msg :from)) 25 nil nil t) + " - " + (truncate-string-to-width + (plist-get msg :subject) 40 nil nil t) + "]] ")) + (org-deadline nil + (cond ((= arg 1) (format-time-string "%Y-%m-%d")) + ((= arg 4) "+1d"))) + + (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 "Refiled \"%s\" and added to the agenda for %s" + (truncate-string-to-width + (plist-get msg :subject) 40 nil nil t) + (cond ((= arg 1) "today") + ((= arg 4) "tomorrow") + (t "later")))))) + +;;;###autoload +(defun my-mu4e-set-account () + "Set the account for composing a message. If a 'To' header is present, +and correspands to an email account, this account will be selected. +Otherwise, the user is prompted for the account they wish to use." + (unless (and mu4e-compose-parent-message + (let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to)))) + (from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from))))) + (if (member to (plist-get mu4e~server-props :personal-addresses)) + (setq user-mail-address to) + (if (member from (plist-get mu4e~server-props :personal-addresses)) + (setq user-mail-address from) + nil)))) + (ivy-read "Account: " (plist-get mu4e~server-props :personal-addresses) :action (lambda (candidate) (setq user-mail-address candidate))))) + +;;;###autoload +(defun mu4e~main-action-prettier-str (str &optional func-or-shortcut) + "Highlight the first occurrence of [.] in STR. +If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it +when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is +a string, execute the corresponding keyboard action when it is +clicked." + :override #'mu4e~main-action-str + (let ((newstr + (replace-regexp-in-string + "\\[\\(..?\\)\\]" + (lambda(m) + (format "%s" + (propertize (match-string 1 m) 'face '(mode-line-emphasis bold)))) + (replace-regexp-in-string "\t\\*" "\t⚫" str))) + (map (make-sparse-keymap)) + (func (if (functionp func-or-shortcut) + func-or-shortcut + (if (stringp func-or-shortcut) + (lambda()(interactive) + (execute-kbd-macro func-or-shortcut)))))) + (define-key map [mouse-2] func) + (define-key map (kbd "RET") func) + (put-text-property 0 (length newstr) 'keymap map newstr) + (put-text-property (string-match "[A-Za-z].+$" newstr) + (- (length newstr) 1) 'mouse-face 'highlight newstr) + newstr)) ;; ;; Hooks diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index b45084b9c..1165a8c53 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -62,54 +62,6 @@ ;; set mail user agent (setq mail-user-agent 'mu4e-user-agent) - ;;---------------- - ;; Icons - ;;---------------- - - ;; Icons need a bit of work - ;; Spacing needs to be determined and adjucted - - (defun +get-string-width (str) - "Return the width in pixels of a string in the current -window's default font. If the font is mono-spaced, this -will also be the width of all other printable characters." - (let ((window (selected-window)) - (remapping face-remapping-alist)) - (with-temp-buffer - (make-local-variable 'face-remapping-alist) - (setq face-remapping-alist remapping) - (set-window-buffer window (current-buffer)) - (insert str) - (car (window-text-pixel-size))))) - - (cl-defun mu4e~normalised-icon (name &key set colour height v-adjust) - "Convert :icon declaration to icon" - (let* ((icon-set (intern (concat "all-the-icons-" (or set "faicon")))) - (v-adjust (or v-adjust 0.02)) - (height (or height 0.8)) - (icon (if colour - (apply icon-set `(,name :face ,(intern (concat "all-the-icons-" colour)) :height ,height :v-adjust ,v-adjust)) - (apply icon-set `(,name :height ,height :v-adjust ,v-adjust)))) - (icon-width (+get-string-width icon)) - (space-width (+get-string-width " ")) - (space-factor (- 2 (/ (float icon-width) space-width)))) - (concat (propertize " " 'display `(space . (:width ,space-factor))) icon))) - - ;; Set up all the fancy icons - (defun mu4e~initialise-icons () - (setq mu4e-use-fancy-chars t - mu4e-headers-draft-mark (cons "D" (mu4e~normalised-icon "pencil")) - mu4e-headers-flagged-mark (cons "F" (mu4e~normalised-icon "flag")) - mu4e-headers-new-mark (cons "N" (mu4e~normalised-icon "sync" :set "material" :height 0.8 :v-adjust -0.10)) - mu4e-headers-passed-mark (cons "P" (mu4e~normalised-icon "arrow-right")) - mu4e-headers-replied-mark (cons "R" (mu4e~normalised-icon "arrow-right")) - mu4e-headers-seen-mark (cons "S" "") ;(mu4e~normalised-icon "eye" :height 0.6 :v-adjust 0.07 :colour "dsilver")) - mu4e-headers-trashed-mark (cons "T" (mu4e~normalised-icon "trash")) - mu4e-headers-attach-mark (cons "a" (mu4e~normalised-icon "file-text-o" :colour "silver")) - mu4e-headers-encrypted-mark (cons "x" (mu4e~normalised-icon "lock")) - mu4e-headers-signed-mark (cons "s" (mu4e~normalised-icon "certificate" :height 0.7 :colour "dpurple")) - mu4e-headers-unread-mark (cons "u" (mu4e~normalised-icon "eye-slash" :v-adjust 0.05)))) - ;; Set the icons only when a graphical frame has been created (if (display-graphic-p) (mu4e~initialise-icons) @@ -120,9 +72,7 @@ will also be the width of all other printable characters." (mu4e~initialise-icons) (remove-hook #'mu4e~initialise-icons-hook))))) - ;;---------------- ;; Header view - ;;---------------- (setq mu4e-headers-fields '((:account . 12) @@ -133,14 +83,6 @@ will also be the width of all other printable characters." (plist-put (cdr (assoc :flags mu4e-header-info)) :shortname " Flags") ; default=Flgs - ;; A header colourisation function/variable could be handy - (defun mu4e~header-colourise (str) - (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) - (colour (nth (% str-sum (length mu4e-header-colourised-faces)) - mu4e-header-colourised-faces))) - (put-text-property 0 (length str) 'face colour str) - str)) - (defvar mu4e~header-colourised-faces '(all-the-icons-lblue all-the-icons-purple @@ -203,79 +145,16 @@ will also be the width of all other printable characters." (when (fboundp 'imagemagick-register-types) (imagemagick-register-types)) - ;; Adding emails to the agenda - ;; Perfect for when you see an email you want to reply to - ;; later, but don't want to forget about - - (defun mu4e-msg-to-agenda (arg) - "Refile a message and add a entry in the agenda file with a -deadline. Default deadline is today. With one prefix, deadline -is tomorrow. With two prefixes, select the deadline." - (interactive "p") - (let ((file (car org-agenda-files)) - (sec "^* Email") - (msg (mu4e-message-at-point))) - (when msg - ;; put the message in the agenda - (with-current-buffer (find-file-noselect file) - (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)))) - ;; place the subheader - (when folded-p (show-branches)) ; unfold if necessary - (org-end-of-meta-data) ; skip property drawer - (org-insert-todo-heading 1) ; insert a todo heading - (when (= (org-outline-level) lev) ; demote if necessary - (org-do-demote)) - ;; insert message and add deadline - (insert (concat " Respond to " - "[[mu4e:msgid:" - (plist-get msg :message-id) "][" - (truncate-string-to-width - (caar (plist-get msg :from)) 25 nil nil t) - " - " - (truncate-string-to-width - (plist-get msg :subject) 40 nil nil t) - "]] ")) - (org-deadline nil - (cond ((= arg 1) (format-time-string "%Y-%m-%d")) - ((= arg 4) "+1d"))) - - (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 "Refiled \"%s\" and added to the agenda for %s" - (truncate-string-to-width - (plist-get msg :subject) 40 nil nil t) - (cond ((= arg 1) "today") - ((= arg 4) "tomorrow") - (t "later")))))) - (map! :map mu4e-headers-mode-map :e "l" #'mu4e-msg-to-agenda) - ;; General keybindings - (map! :localleader :map mu4e-compose-mode-map :desc "send and exit" "s" #'message-send-and-exit :desc "kill buffer" "d" #'message-kill-buffer :desc "save draft" "S" #'message-dont-send :desc "attach" "a" #'mail-add-attachment) + ;; Due to evil, none of the marking commands work when making a visual selection in ;; the headers view of mu4e. Without overriding any evil commands we may actually ;; want to use in and evil selection, this can be easily fixed. @@ -287,56 +166,9 @@ is tomorrow. With two prefixes, select the deadline." :v "u" #'mu4e-headers-mark-for-unmark :vn "l" #'mu4e-msg-to-agenda)) - ;;---------------- - ;; Sending mail - ;;---------------- - - (defun my-mu4e-set-account () - "Set the account for composing a message. If a 'To' header is present, -and correspands to an email account, this account will be selected. -Otherwise, the user is prompted for the accound they wish to use." - (unless (and mu4e-compose-parent-message - (let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to)))) - (from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from))))) - (if (member to (plist-get mu4e~server-props :personal-addresses)) - (setq user-mail-address to) - (if (member from (plist-get mu4e~server-props :personal-addresses)) - (setq user-mail-address from) - nil)))) - (ivy-read "Account: " (plist-get mu4e~server-props :personal-addresses) :action (lambda (candidate) (setq user-mail-address candidate))))) - (add-hook 'mu4e-compose-pre-hook 'my-mu4e-set-account) - ;;---------------- - ;; Prettifying mu4e:main - ;;---------------- - - (defadvice! mu4e~main-action-prettier-str (str &optional func-or-shortcut) - "Highlight the first occurrence of [.] in STR. -If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it -when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is -a string, execute the corresponding keyboard action when it is -clicked." - :override #'mu4e~main-action-str - (let ((newstr - (replace-regexp-in-string - "\\[\\(..?\\)\\]" - (lambda(m) - (format "%s" - (propertize (match-string 1 m) 'face '(mode-line-emphasis bold)))) - (replace-regexp-in-string "\t\\*" "\t⚫" str))) - (map (make-sparse-keymap)) - (func (if (functionp func-or-shortcut) - func-or-shortcut - (if (stringp func-or-shortcut) - (lambda()(interactive) - (execute-kbd-macro func-or-shortcut)))))) - (define-key map [mouse-2] func) - (define-key map (kbd "RET") func) - (put-text-property 0 (length newstr) 'keymap map newstr) - (put-text-property (string-match "[A-Za-z].+$" newstr) - (- (length newstr) 1) 'mouse-face 'highlight newstr) - newstr))) + (advice-add #'mu4e~main-action-str :override #'mu4e~main-action-prettier-str)) (when (featurep! :lang org) (use-package! org-msg From 2a79ff22800625f2003cc932d41b130f23d7b6f7 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 23 Sep 2020 13:08:57 +0800 Subject: [PATCH 013/119] Mu4e: Restyle org-msg, with the odd config tweak --- modules/email/mu4e/config.el | 122 ++++++++++++++++++++++++++++++++++- 1 file changed, 120 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 1165a8c53..626e164e3 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -174,10 +174,128 @@ (use-package! org-msg :hook (org-load . org-msg-mode) :config - (setq org-msg-startup "inlineimages" + (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng" + org-msg-startup "hidestars indent inlineimages" + org-msg-greeting-fmt "\nHi %s,\n\n" org-msg-greeting-name-limit 3 - org-msg-text-plain-alternative t))) + org-msg-text-plain-alternative t) + (defvar org-msg-currently-exporting nil + "Helper variable to indicate whether org-msg is currently exporting the org buffer to HTML. +Usefull for affecting HTML export config.") + (defadvice! org-msg--now-exporting (&rest _) + :before #'org-msg-org-to-xml + (setq org-msg-currently-exporting t)) + (defadvice! org-msg--not-exporting (&rest _) + :after #'org-msg-org-to-xml + (setq org-msg-currently-exporting nil)) + + (setq org-msg-enforce-css + (let* ((font-family '(font-family . "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell,\ + \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";")) + (monospace-font '(font-family . "SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;")) + (font-size '(font-size . "11pt")) + (font `(,font-family ,font-size)) + (line-height '(line-height . "1.2")) + (theme-color "#8a0400") + (bold '(font-weight . "bold")) + (color `(color . ,theme-color)) + (table `((margin-top . "6px") (margin-bottom . "6px") + (border-left . "none") (border-right . "none") + (border-top . "2px solid #222222") (border-bottom . "2px solid #222222") + )) + (ftl-number `(,color ,bold (text-align . "left"))) + (inline-modes '(asl c c++ conf cpp csv diff ditaa emacs-lisp + fundamental ini json makefile man org plantuml + python sh xml)) + (inline-src `((background-color . "rgba(27,31,35,.05)") + (border-radius . "3px") + (padding . ".2em .4em") + (font-size . "90%") ,monospace-font + (margin . 0))) + (code-src + (mapcar (lambda (mode) + `(code ,(intern (concat "src src-" (symbol-name mode))) + ,inline-src)) + inline-modes))) + `((del nil ((color . "grey") (border-left . "none") + (text-decoration . "line-through") (margin-bottom . "0px") + (margin-top . "10px") (line-height . "11pt"))) + (a nil (,color)) + (a reply-header ((color . "black") (text-decoration . "none"))) + (div reply-header ((padding . "3.0pt 0in 0in 0in") + (border-top . "solid #e1e1e1 1.0pt") + (margin-bottom . "20px"))) + (span underline ((text-decoration . "underline"))) + (li nil (,line-height (margin-bottom . "0px") + (margin-top . "2px"))) + (nil org-ul ((list-style-type . "square"))) + (nil org-ol (,@font ,line-height (margin-bottom . "0px") + (margin-top . "0px") (margin-left . "30px") + (padding-top . "0px") (padding-left . "5px"))) + (nil signature (,@font (margin-bottom . "20px"))) + (blockquote nil ((padding . "0px 10px") (margin-left . "10px") + (margin-top . "20px") (margin-bottom . "0") + (border-left . "3px solid #ccc") (font-style . "italic") + (background . "#f9f9f9"))) + (code nil (,font-size ,monospace-font (background . "#f9f9f9"))) + ,@code-src + (nil linenr ((padding-right . "1em") + (color . "black") + (background-color . "#aaaaaa"))) + (pre nil ((line-height . "1.2") + (color . ,(doom-color 'fg)) + (background-color . ,(doom-color 'bg)) + (margin . "4px 0px 8px 0px") + (padding . "8px 12px") + (width . "95%") + (border-radius . "5px") + (font-weight . "500") + ,monospace-font)) + (div org-src-container ((margin-top . "10px"))) + (nil figure-number ,ftl-number) + (nil table-number) + (caption nil ((text-align . "left") + (background . ,theme-color) + (color . "white") + ,bold)) + (nil t-above ((caption-side . "top"))) + (nil t-bottom ((caption-side . "bottom"))) + (nil listing-number ,ftl-number) + (nil figure ,ftl-number) + (nil org-src-name ,ftl-number) + (img nil ((vertical-align . "middle") + (max-width . "100%"))) + (img latex-fragment-inline ((transform . ,(format "translateY(-1px) scale(%.3f)" + (/ 1.0 (if (boundp 'preview-scale) + preview-scale 1.4)))) + (margin . "0 -0.35em"))) + (table nil (,@table ,line-height (border-collapse . "collapse"))) + (th nil ((border . "none") (border-bottom . "1px solid #222222") + (background-color . "#EDEDED") (font-weight . "500") + (padding . "3px 10px"))) + (td nil (,@table (padding . "1px 10px") + (background-color . "#f9f9f9") (border . "none"))) + (td org-left ((text-align . "left"))) + (td org-right ((text-align . "right"))) + (td org-center ((text-align . "center"))) + (kbd nil ((border . "1px solid #d1d5da") (border-radius . "3px") + (box-shadow . "inset 0 -1px 0 #d1d5da") (background-color . "#fafbfc") + (color . "#444d56") (padding . "3px 5px") (display . "inline-block"))) + (div outline-text-4 ((margin-left . "15px"))) + (div outline-4 ((margin-left . "10px"))) + (h4 nil ((margin-bottom . "0px") (font-size . "11pt"))) + (h3 nil ((margin-bottom . "0px") + ,color (font-size . "14pt"))) + (h2 nil ((margin-top . "20px") (margin-bottom . "20px") + ,color (font-size . "18pt"))) + (h1 nil ((margin-top . "20px") + (margin-bottom . "0px") ,color (font-size . "24pt"))) + (p nil ((text-decoration . "none") (margin-bottom . "0px") + (margin-top . "10px") (line-height . "11pt") ,font-size + (max-width . "100ch"))) + (b nil ((font-weight . "500") (color . ,theme-color))) + (div nil (,@font (line-height . "12pt")))))))) ;; From aecdbb17b2869812dd1c74a888917fccd36876d0 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 25 Sep 2020 16:37:11 +0800 Subject: [PATCH 014/119] Mu4e: Fix misplaced close paren --- modules/email/mu4e/config.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 626e164e3..a462a8e04 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -79,9 +79,9 @@ (:human-date . 8) (:flags . 6) ; 3 icon flags (:from . 25) - (:subject)) + (:subject))) - (plist-put (cdr (assoc :flags mu4e-header-info)) :shortname " Flags") ; default=Flgs + (plist-put (cdr (assoc :flags mu4e-header-info)) :shortname " Flags") ; default=Flgs (defvar mu4e~header-colourised-faces '(all-the-icons-lblue @@ -118,7 +118,7 @@ (propertize (format "%2d" (+ (length (mu4e-message-field msg :to)) (length (mu4e-message-field msg :cc)))) - 'face 'mu4e-footer-face))))))) + 'face 'mu4e-footer-face)))))) ;; Marks usually affect the current view (defadvice! +mu4e--refresh-current-view-a (&rest _) From a974db04c4b08166cd8c7ecb4656314f72b31790 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 1 Oct 2020 01:52:58 +0800 Subject: [PATCH 015/119] Mu4e: further improve org-msg - stylistic tweaks - make accent colour easily user-settable - scale LaTeX fragments appropriately - make it easy to toggle org-msg-mode for one-off messages --- modules/email/mu4e/README.org | 10 +++ modules/email/mu4e/autoload/email.el | 108 ++++++++++++++++++++++++--- modules/email/mu4e/config.el | 56 +++++++++----- 3 files changed, 147 insertions(+), 27 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 4fa541360..a7b831243 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -18,6 +18,7 @@ - [[#offlineimap][offlineimap]] - [[#mbsync][mbsync]] - [[#mu-and-mu4e][mu and mu4e]] + - [[#orgmsg][OrgMsg]] - [[#troubleshooting][Troubleshooting]] - [[#no-such-file-or-directory-mu4e][=No such file or directory, mu4e=]] - [[#void-function-org-time-add-error-on-gentoo][~(void-function org-time-add)~ error on Gentoo]] @@ -168,6 +169,15 @@ Then configure Emacs to use your email address: (mu4e-compose-signature . "---\nHenrik Lissner")) t) #+END_SRC +** OrgMsg +By default, ~org-msg-mode~ is enabled before composing the first message. +To disable ~org-msg-mode~ by default, simply +#+BEGIN_SRC emacs-lisp :tangle no +(setq mu4e-compose--org-msg-toggle-next nil) +#+END_SRC + +To toggle org-msg for a single message, just apply the universal argument to the +compose or reply command (=SPC u= with ~evil~, =C-u= otherwise). * Troubleshooting ** =No such file or directory, mu4e= diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index c54bfcb8c..bb076d934 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -189,18 +189,18 @@ is tomorrow. With two prefixes, select the deadline." ;;;###autoload (defun my-mu4e-set-account () - "Set the account for composing a message. If a 'To' header is present, + "Set the account for composing a message. If a 'To' header is present, and correspands to an email account, this account will be selected. Otherwise, the user is prompted for the account they wish to use." - (unless (and mu4e-compose-parent-message - (let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to)))) - (from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from))))) - (if (member to (plist-get mu4e~server-props :personal-addresses)) - (setq user-mail-address to) - (if (member from (plist-get mu4e~server-props :personal-addresses)) - (setq user-mail-address from) - nil)))) - (ivy-read "Account: " (plist-get mu4e~server-props :personal-addresses) :action (lambda (candidate) (setq user-mail-address candidate))))) + (unless (and mu4e-compose-parent-message + (let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to)))) + (from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from))))) + (if (member to (plist-get mu4e~server-props :personal-addresses)) + (setq user-mail-address to) + (if (member from (plist-get mu4e~server-props :personal-addresses)) + (setq user-mail-address from) + nil)))) + (ivy-read "Account: " (plist-get mu4e~server-props :personal-addresses) :action (lambda (candidate) (setq user-mail-address candidate))))) ;;;###autoload (defun mu4e~main-action-prettier-str (str &optional func-or-shortcut) @@ -245,3 +245,91 @@ clicked." (+mu4e--old-wconf (set-window-configuration +mu4e--old-wconf) (setq +mu4e--old-wconf nil)))) + +;; org-msg hooks + +;;;###autoload +(defun +org-msg-img-scale-css (img-uri) + "For a given IMG-URI, use imagemagik to find its width." + (if org-msg-currently-exporting + (list :width + (format "%.1fpx" + (/ (string-to-number + (shell-command-to-string + (format "identify -format %%w %s" + (substring img-uri 7)))) ; 7=(length "file://") + (plist-get org-format-latex-options :scale)))) + (list :style (format "transform: scale(%.3f)" + (/ 1.0 (plist-get org-format-latex-options :scale)))))) + +(defun org-html-latex-fragment-scaled (latex-fragment _contents info) + "Transcode a LATEX-FRAGMENT object from Org to HTML. +CONTENTS is nil. INFO is a plist holding contextual information. + +This differs from `org-html-latex-fragment' in that it uses the LaTeX fragment +as a meaningful alt value, applies a class to indicate what sort of fragment it is +(latex-fragment-inline or latex-fragment-block), and (on Linux) scales the image to +account for the value of :scale in `org-format-latex-options'." + (let ((latex-frag (org-element-property :value latex-fragment)) + (processing-type (plist-get info :with-latex))) + (cond + ((memq processing-type '(t mathjax)) + (org-html-format-latex latex-frag 'mathjax info)) + ((memq processing-type '(t html)) + (org-html-format-latex latex-frag 'html info)) + ((assq processing-type org-preview-latex-process-alist) + (let ((formula-link + (org-html-format-latex latex-frag processing-type info))) + (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) + (let ((source (org-export-file-uri (match-string 1 formula-link))) + (attributes (list :alt latex-frag + :class (concat "latex-fragment-" + (if (equal "\\(" (substring latex-frag 0 2)) + "inline" "block"))))) + (when (and (memq processing-type '(dvipng convert)) IS-LINUX) + (apply #'plist-put attributes (+org-msg-img-scale-css source))) + (org-html--format-image source attributes info))))) + (t latex-frag)))) + +(defun org-html-latex-environment-scaled (latex-environment _contents info) + "Transcode a LATEX-ENVIRONMENT element from Org to HTML. +CONTENTS is nil. INFO is a plist holding contextual information. + +This differs from `org-html-latex-environment' in that (on Linux) it +scales the image to account for the value of :scale in `org-format-latex-options'." + (let ((processing-type (plist-get info :with-latex)) + (latex-frag (org-remove-indentation + (org-element-property :value latex-environment))) + (attributes (org-export-read-attribute :attr_html latex-environment)) + (label (and (org-element-property :name latex-environment) + (org-export-get-reference latex-environment info))) + (caption (and (org-html--latex-environment-numbered-p latex-environment) + (number-to-string + (org-export-get-ordinal + latex-environment info nil + (lambda (l _) + (and (org-html--math-environment-p l) + (org-html--latex-environment-numbered-p l)))))))) + (plist-put attributes :class "latex-environment") + (cond + ((memq processing-type '(t mathjax)) + (org-html-format-latex + (if (org-string-nw-p label) + (replace-regexp-in-string "\\`.*" + (format "\\&\n\\\\label{%s}" label) + latex-frag) + latex-frag) + 'mathjax info)) + ((assq processing-type org-preview-latex-process-alist) + (let ((formula-link + (org-html-format-latex + (org-html--unlabel-latex-environment latex-frag) + processing-type info))) + (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) + (let ((source (org-export-file-uri (match-string 1 formula-link)))) + (when (and (memq processing-type '(dvipng convert)) IS-LINUX) + (apply #'plist-put attributes (+org-msg-img-scale-css source))) + (org-html--wrap-latex-environment + (org-html--format-image source attributes info) + info caption label))))) + (t (org-html--wrap-latex-environment latex-frag info caption label))))) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index a462a8e04..18fb94a6f 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -172,7 +172,7 @@ (when (featurep! :lang org) (use-package! org-msg - :hook (org-load . org-msg-mode) + :after (mu4e org) :config (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng" org-msg-startup "hidestars indent inlineimages" @@ -190,6 +190,27 @@ Usefull for affecting HTML export config.") :after #'org-msg-org-to-xml (setq org-msg-currently-exporting nil)) + (advice-add #'org-html-latex-fragment :override #'org-html-latex-fragment-scaled) + (advice-add #'org-html-latex-environment :override #'org-html-latex-environment-scaled) + + (defvar mu4e-compose--org-msg-toggle-next t ; t to initialise org-msg + "Whether to toggle ") + (defun mu4e-compose-org-msg-handle-toggle (toggle-p) + (when (xor toggle-p mu4e-compose--org-msg-toggle-next) + (org-msg-mode (if org-msg-mode -1 1)) + (setq mu4e-compose--org-msg-toggle-next + (not mu4e-compose--org-msg-toggle-next)))) + + (defadvice! mu4e-maybe-toggle-org-msg (orig-fn toggle-p) + :around #'mu4e-compose-new + :around #'mu4e-compose-reply + (interactive "p") + (mu4e-compose-org-msg-handle-toggle (/= 1 toggle-p)) + (funcall orig-fn)) + + (defvar +org-msg-accent-color "#c01c28" + "Accent color to use in org-msg's generated CSS. +Must be set before org-msg is loaded to take effect.") (setq org-msg-enforce-css (let* ((font-family '(font-family . "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell,\ \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";")) @@ -197,12 +218,13 @@ Usefull for affecting HTML export config.") (font-size '(font-size . "11pt")) (font `(,font-family ,font-size)) (line-height '(line-height . "1.2")) - (theme-color "#8a0400") + (theme-color +org-msg-accent-color) (bold '(font-weight . "bold")) (color `(color . ,theme-color)) (table `((margin-top . "6px") (margin-bottom . "6px") (border-left . "none") (border-right . "none") - (border-top . "2px solid #222222") (border-bottom . "2px solid #222222") + (border-top . "2px solid #222222") + (border-bottom . "2px solid #222222") )) (ftl-number `(,color ,bold (text-align . "left"))) (inline-modes '(asl c c++ conf cpp csv diff ditaa emacs-lisp @@ -234,10 +256,12 @@ Usefull for affecting HTML export config.") (margin-top . "0px") (margin-left . "30px") (padding-top . "0px") (padding-left . "5px"))) (nil signature (,@font (margin-bottom . "20px"))) - (blockquote nil ((padding . "0px 10px") (margin-left . "10px") - (margin-top . "20px") (margin-bottom . "0") - (border-left . "3px solid #ccc") (font-style . "italic") + (blockquote nil ((padding . "2px 12px") (margin-left . "10px") + (margin-top . "10px") (margin-bottom . "0") + (border-left . "3px solid #ccc") + (font-style . "italic") (background . "#f9f9f9"))) + (p blockquote ((margin . "0") (padding . "4px 0"))) (code nil (,font-size ,monospace-font (background . "#f9f9f9"))) ,@code-src (nil linenr ((padding-right . "1em") @@ -266,10 +290,7 @@ Usefull for affecting HTML export config.") (nil org-src-name ,ftl-number) (img nil ((vertical-align . "middle") (max-width . "100%"))) - (img latex-fragment-inline ((transform . ,(format "translateY(-1px) scale(%.3f)" - (/ 1.0 (if (boundp 'preview-scale) - preview-scale 1.4)))) - (margin . "0 -0.35em"))) + (img latex-fragment-inline ((margin . "0 0.1em"))) (table nil (,@table ,line-height (border-collapse . "collapse"))) (th nil ((border . "none") (border-bottom . "1px solid #222222") (background-color . "#EDEDED") (font-weight . "500") @@ -280,8 +301,9 @@ Usefull for affecting HTML export config.") (td org-right ((text-align . "right"))) (td org-center ((text-align . "center"))) (kbd nil ((border . "1px solid #d1d5da") (border-radius . "3px") - (box-shadow . "inset 0 -1px 0 #d1d5da") (background-color . "#fafbfc") - (color . "#444d56") (padding . "3px 5px") (display . "inline-block"))) + (box-shadow . "inset 0 -1px 0 #d1d5da") + (background-color . "#fafbfc") (color . "#444d56") + (padding . "3px 5px") (display . "inline-block"))) (div outline-text-4 ((margin-left . "15px"))) (div outline-4 ((margin-left . "10px"))) (h4 nil ((margin-bottom . "0px") (font-size . "11pt"))) @@ -289,11 +311,11 @@ Usefull for affecting HTML export config.") ,color (font-size . "14pt"))) (h2 nil ((margin-top . "20px") (margin-bottom . "20px") ,color (font-size . "18pt"))) - (h1 nil ((margin-top . "20px") - (margin-bottom . "0px") ,color (font-size . "24pt"))) - (p nil ((text-decoration . "none") (margin-bottom . "0px") - (margin-top . "10px") (line-height . "11pt") ,font-size - (max-width . "100ch"))) + (h1 nil ((margin-top . "20px") (margin-bottom . "0px") + ,color (font-size . "24pt"))) + (p nil ((text-decoration . "none") (line-height . "11pt") + (margin-top . "10px") (margin-bottom . "0px") + ,font-size (max-width . "100ch"))) (b nil ((font-weight . "500") (color . ,theme-color))) (div nil (,@font (line-height . "12pt")))))))) From d4c5c6245f77c3764cca28a61213acc1d3d4b6f3 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 1 Oct 2020 01:56:45 +0800 Subject: [PATCH 016/119] Mu4e: Tidy up org-msg use-package statement reduce unnecessary nesting --- modules/email/mu4e/config.el | 280 +++++++++++++++++------------------ 1 file changed, 140 insertions(+), 140 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 18fb94a6f..7e60705d5 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -170,154 +170,154 @@ (advice-add #'mu4e~main-action-str :override #'mu4e~main-action-prettier-str)) -(when (featurep! :lang org) - (use-package! org-msg - :after (mu4e org) - :config - (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng" - org-msg-startup "hidestars indent inlineimages" - org-msg-greeting-fmt "\nHi %s,\n\n" - org-msg-greeting-name-limit 3 - org-msg-text-plain-alternative t) +(use-package! org-msg + :after (mu4e org) + :when (featurep! :lang org) + :config + (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng" + org-msg-startup "hidestars indent inlineimages" + org-msg-greeting-fmt "\nHi %s,\n\n" + org-msg-greeting-name-limit 3 + org-msg-text-plain-alternative t) - (defvar org-msg-currently-exporting nil - "Helper variable to indicate whether org-msg is currently exporting the org buffer to HTML. + (defvar org-msg-currently-exporting nil + "Helper variable to indicate whether org-msg is currently exporting the org buffer to HTML. Usefull for affecting HTML export config.") - (defadvice! org-msg--now-exporting (&rest _) - :before #'org-msg-org-to-xml - (setq org-msg-currently-exporting t)) - (defadvice! org-msg--not-exporting (&rest _) - :after #'org-msg-org-to-xml - (setq org-msg-currently-exporting nil)) + (defadvice! org-msg--now-exporting (&rest _) + :before #'org-msg-org-to-xml + (setq org-msg-currently-exporting t)) + (defadvice! org-msg--not-exporting (&rest _) + :after #'org-msg-org-to-xml + (setq org-msg-currently-exporting nil)) - (advice-add #'org-html-latex-fragment :override #'org-html-latex-fragment-scaled) - (advice-add #'org-html-latex-environment :override #'org-html-latex-environment-scaled) + (advice-add #'org-html-latex-fragment :override #'org-html-latex-fragment-scaled) + (advice-add #'org-html-latex-environment :override #'org-html-latex-environment-scaled) - (defvar mu4e-compose--org-msg-toggle-next t ; t to initialise org-msg - "Whether to toggle ") - (defun mu4e-compose-org-msg-handle-toggle (toggle-p) - (when (xor toggle-p mu4e-compose--org-msg-toggle-next) - (org-msg-mode (if org-msg-mode -1 1)) - (setq mu4e-compose--org-msg-toggle-next - (not mu4e-compose--org-msg-toggle-next)))) + (defvar mu4e-compose--org-msg-toggle-next t ; t to initialise org-msg + "Whether to toggle ") + (defun mu4e-compose-org-msg-handle-toggle (toggle-p) + (when (xor toggle-p mu4e-compose--org-msg-toggle-next) + (org-msg-mode (if org-msg-mode -1 1)) + (setq mu4e-compose--org-msg-toggle-next + (not mu4e-compose--org-msg-toggle-next)))) - (defadvice! mu4e-maybe-toggle-org-msg (orig-fn toggle-p) - :around #'mu4e-compose-new - :around #'mu4e-compose-reply - (interactive "p") - (mu4e-compose-org-msg-handle-toggle (/= 1 toggle-p)) - (funcall orig-fn)) + (defadvice! mu4e-maybe-toggle-org-msg (orig-fn toggle-p) + :around #'mu4e-compose-new + :around #'mu4e-compose-reply + (interactive "p") + (mu4e-compose-org-msg-handle-toggle (/= 1 toggle-p)) + (funcall orig-fn)) - (defvar +org-msg-accent-color "#c01c28" - "Accent color to use in org-msg's generated CSS. + (defvar +org-msg-accent-color "#c01c28" + "Accent color to use in org-msg's generated CSS. Must be set before org-msg is loaded to take effect.") - (setq org-msg-enforce-css - (let* ((font-family '(font-family . "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell,\ + (setq org-msg-enforce-css + (let* ((font-family '(font-family . "-apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Oxygen, Ubuntu, Cantarell,\ \"Fira Sans\", \"Droid Sans\", \"Helvetica Neue\", Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\";")) - (monospace-font '(font-family . "SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;")) - (font-size '(font-size . "11pt")) - (font `(,font-family ,font-size)) - (line-height '(line-height . "1.2")) - (theme-color +org-msg-accent-color) - (bold '(font-weight . "bold")) - (color `(color . ,theme-color)) - (table `((margin-top . "6px") (margin-bottom . "6px") - (border-left . "none") (border-right . "none") - (border-top . "2px solid #222222") - (border-bottom . "2px solid #222222") - )) - (ftl-number `(,color ,bold (text-align . "left"))) - (inline-modes '(asl c c++ conf cpp csv diff ditaa emacs-lisp - fundamental ini json makefile man org plantuml - python sh xml)) - (inline-src `((background-color . "rgba(27,31,35,.05)") - (border-radius . "3px") - (padding . ".2em .4em") - (font-size . "90%") ,monospace-font - (margin . 0))) - (code-src - (mapcar (lambda (mode) - `(code ,(intern (concat "src src-" (symbol-name mode))) - ,inline-src)) - inline-modes))) - `((del nil ((color . "grey") (border-left . "none") - (text-decoration . "line-through") (margin-bottom . "0px") - (margin-top . "10px") (line-height . "11pt"))) - (a nil (,color)) - (a reply-header ((color . "black") (text-decoration . "none"))) - (div reply-header ((padding . "3.0pt 0in 0in 0in") - (border-top . "solid #e1e1e1 1.0pt") - (margin-bottom . "20px"))) - (span underline ((text-decoration . "underline"))) - (li nil (,line-height (margin-bottom . "0px") - (margin-top . "2px"))) - (nil org-ul ((list-style-type . "square"))) - (nil org-ol (,@font ,line-height (margin-bottom . "0px") - (margin-top . "0px") (margin-left . "30px") - (padding-top . "0px") (padding-left . "5px"))) - (nil signature (,@font (margin-bottom . "20px"))) - (blockquote nil ((padding . "2px 12px") (margin-left . "10px") - (margin-top . "10px") (margin-bottom . "0") - (border-left . "3px solid #ccc") - (font-style . "italic") - (background . "#f9f9f9"))) - (p blockquote ((margin . "0") (padding . "4px 0"))) - (code nil (,font-size ,monospace-font (background . "#f9f9f9"))) - ,@code-src - (nil linenr ((padding-right . "1em") - (color . "black") - (background-color . "#aaaaaa"))) - (pre nil ((line-height . "1.2") - (color . ,(doom-color 'fg)) - (background-color . ,(doom-color 'bg)) - (margin . "4px 0px 8px 0px") - (padding . "8px 12px") - (width . "95%") - (border-radius . "5px") - (font-weight . "500") - ,monospace-font)) - (div org-src-container ((margin-top . "10px"))) - (nil figure-number ,ftl-number) - (nil table-number) - (caption nil ((text-align . "left") - (background . ,theme-color) - (color . "white") - ,bold)) - (nil t-above ((caption-side . "top"))) - (nil t-bottom ((caption-side . "bottom"))) - (nil listing-number ,ftl-number) - (nil figure ,ftl-number) - (nil org-src-name ,ftl-number) - (img nil ((vertical-align . "middle") - (max-width . "100%"))) - (img latex-fragment-inline ((margin . "0 0.1em"))) - (table nil (,@table ,line-height (border-collapse . "collapse"))) - (th nil ((border . "none") (border-bottom . "1px solid #222222") - (background-color . "#EDEDED") (font-weight . "500") - (padding . "3px 10px"))) - (td nil (,@table (padding . "1px 10px") - (background-color . "#f9f9f9") (border . "none"))) - (td org-left ((text-align . "left"))) - (td org-right ((text-align . "right"))) - (td org-center ((text-align . "center"))) - (kbd nil ((border . "1px solid #d1d5da") (border-radius . "3px") - (box-shadow . "inset 0 -1px 0 #d1d5da") - (background-color . "#fafbfc") (color . "#444d56") - (padding . "3px 5px") (display . "inline-block"))) - (div outline-text-4 ((margin-left . "15px"))) - (div outline-4 ((margin-left . "10px"))) - (h4 nil ((margin-bottom . "0px") (font-size . "11pt"))) - (h3 nil ((margin-bottom . "0px") - ,color (font-size . "14pt"))) - (h2 nil ((margin-top . "20px") (margin-bottom . "20px") - ,color (font-size . "18pt"))) - (h1 nil ((margin-top . "20px") (margin-bottom . "0px") - ,color (font-size . "24pt"))) - (p nil ((text-decoration . "none") (line-height . "11pt") - (margin-top . "10px") (margin-bottom . "0px") - ,font-size (max-width . "100ch"))) - (b nil ((font-weight . "500") (color . ,theme-color))) - (div nil (,@font (line-height . "12pt")))))))) + (monospace-font '(font-family . "SFMono-Regular, Menlo, Monaco, Consolas, \"Liberation Mono\", \"Courier New\", monospace;")) + (font-size '(font-size . "11pt")) + (font `(,font-family ,font-size)) + (line-height '(line-height . "1.2")) + (theme-color +org-msg-accent-color) + (bold '(font-weight . "bold")) + (color `(color . ,theme-color)) + (table `((margin-top . "6px") (margin-bottom . "6px") + (border-left . "none") (border-right . "none") + (border-top . "2px solid #222222") + (border-bottom . "2px solid #222222") + )) + (ftl-number `(,color ,bold (text-align . "left"))) + (inline-modes '(asl c c++ conf cpp csv diff ditaa emacs-lisp + fundamental ini json makefile man org plantuml + python sh xml)) + (inline-src `((background-color . "rgba(27,31,35,.05)") + (border-radius . "3px") + (padding . ".2em .4em") + (font-size . "90%") ,monospace-font + (margin . 0))) + (code-src + (mapcar (lambda (mode) + `(code ,(intern (concat "src src-" (symbol-name mode))) + ,inline-src)) + inline-modes))) + `((del nil ((color . "grey") (border-left . "none") + (text-decoration . "line-through") (margin-bottom . "0px") + (margin-top . "10px") (line-height . "11pt"))) + (a nil (,color)) + (a reply-header ((color . "black") (text-decoration . "none"))) + (div reply-header ((padding . "3.0pt 0in 0in 0in") + (border-top . "solid #e1e1e1 1.0pt") + (margin-bottom . "20px"))) + (span underline ((text-decoration . "underline"))) + (li nil (,line-height (margin-bottom . "0px") + (margin-top . "2px"))) + (nil org-ul ((list-style-type . "square"))) + (nil org-ol (,@font ,line-height (margin-bottom . "0px") + (margin-top . "0px") (margin-left . "30px") + (padding-top . "0px") (padding-left . "5px"))) + (nil signature (,@font (margin-bottom . "20px"))) + (blockquote nil ((padding . "2px 12px") (margin-left . "10px") + (margin-top . "10px") (margin-bottom . "0") + (border-left . "3px solid #ccc") + (font-style . "italic") + (background . "#f9f9f9"))) + (p blockquote ((margin . "0") (padding . "4px 0"))) + (code nil (,font-size ,monospace-font (background . "#f9f9f9"))) + ,@code-src + (nil linenr ((padding-right . "1em") + (color . "black") + (background-color . "#aaaaaa"))) + (pre nil ((line-height . "1.2") + (color . ,(doom-color 'fg)) + (background-color . ,(doom-color 'bg)) + (margin . "4px 0px 8px 0px") + (padding . "8px 12px") + (width . "95%") + (border-radius . "5px") + (font-weight . "500") + ,monospace-font)) + (div org-src-container ((margin-top . "10px"))) + (nil figure-number ,ftl-number) + (nil table-number) + (caption nil ((text-align . "left") + (background . ,theme-color) + (color . "white") + ,bold)) + (nil t-above ((caption-side . "top"))) + (nil t-bottom ((caption-side . "bottom"))) + (nil listing-number ,ftl-number) + (nil figure ,ftl-number) + (nil org-src-name ,ftl-number) + (img nil ((vertical-align . "middle") + (max-width . "100%"))) + (img latex-fragment-inline ((margin . "0 0.1em"))) + (table nil (,@table ,line-height (border-collapse . "collapse"))) + (th nil ((border . "none") (border-bottom . "1px solid #222222") + (background-color . "#EDEDED") (font-weight . "500") + (padding . "3px 10px"))) + (td nil (,@table (padding . "1px 10px") + (background-color . "#f9f9f9") (border . "none"))) + (td org-left ((text-align . "left"))) + (td org-right ((text-align . "right"))) + (td org-center ((text-align . "center"))) + (kbd nil ((border . "1px solid #d1d5da") (border-radius . "3px") + (box-shadow . "inset 0 -1px 0 #d1d5da") + (background-color . "#fafbfc") (color . "#444d56") + (padding . "3px 5px") (display . "inline-block"))) + (div outline-text-4 ((margin-left . "15px"))) + (div outline-4 ((margin-left . "10px"))) + (h4 nil ((margin-bottom . "0px") (font-size . "11pt"))) + (h3 nil ((margin-bottom . "0px") + ,color (font-size . "14pt"))) + (h2 nil ((margin-top . "20px") (margin-bottom . "20px") + ,color (font-size . "18pt"))) + (h1 nil ((margin-top . "20px") (margin-bottom . "0px") + ,color (font-size . "24pt"))) + (p nil ((text-decoration . "none") (line-height . "11pt") + (margin-top . "10px") (margin-bottom . "0px") + ,font-size (max-width . "100ch"))) + (b nil ((font-weight . "500") (color . ,theme-color))) + (div nil (,@font (line-height . "12pt"))))))) ;; From a80ef01b884742e1f5ea0af8bf77245ea39f885f Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 1 Oct 2020 16:38:55 +0800 Subject: [PATCH 017/119] Mu4e: improve LaTeX fragment size check We also don't need to tell org-msg to wait for Org apparently --- modules/email/mu4e/autoload/email.el | 9 +++++++-- modules/email/mu4e/config.el | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index bb076d934..9b87845a3 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -256,6 +256,7 @@ clicked." (format "%.1fpx" (/ (string-to-number (shell-command-to-string + ;; TODO change to use 'file' (format "identify -format %%w %s" (substring img-uri 7)))) ; 7=(length "file://") (plist-get org-format-latex-options :scale)))) @@ -286,7 +287,9 @@ account for the value of :scale in `org-format-latex-options'." :class (concat "latex-fragment-" (if (equal "\\(" (substring latex-frag 0 2)) "inline" "block"))))) - (when (and (memq processing-type '(dvipng convert)) IS-LINUX) + (when (and (memq processing-type '(dvipng convert)) + (not IS-WINDOWS) ; relies on posix path + (executable-find "identify")) (apply #'plist-put attributes (+org-msg-img-scale-css source))) (org-html--format-image source attributes info))))) (t latex-frag)))) @@ -327,7 +330,9 @@ scales the image to account for the value of :scale in `org-format-latex-options processing-type info))) (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) (let ((source (org-export-file-uri (match-string 1 formula-link)))) - (when (and (memq processing-type '(dvipng convert)) IS-LINUX) + (when (and (memq processing-type '(dvipng convert)) + (not IS-WINDOWS) ; relies on posix path + (executable-find "identify")) (apply #'plist-put attributes (+org-msg-img-scale-css source))) (org-html--wrap-latex-environment (org-html--format-image source attributes info) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 7e60705d5..2e3cb5123 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -171,7 +171,7 @@ (advice-add #'mu4e~main-action-str :override #'mu4e~main-action-prettier-str)) (use-package! org-msg - :after (mu4e org) + :after mu4e :when (featurep! :lang org) :config (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng" From 522c2e0dda44cb670cb7a913560c5b63a5bdb1e1 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 1 Oct 2020 16:42:53 +0800 Subject: [PATCH 018/119] Mu4e: add some basic doctor checks --- modules/email/mu4e/doctor.el | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 modules/email/mu4e/doctor.el diff --git a/modules/email/mu4e/doctor.el b/modules/email/mu4e/doctor.el new file mode 100644 index 000000000..81e0e55ba --- /dev/null +++ b/modules/email/mu4e/doctor.el @@ -0,0 +1,15 @@ +;;; email/mu4e/doctor.el -*- lexical-binding: t; -*- + +(unless (executable-find "mu") + (warn! "Couldn't find mu command. Mu4e requires this to work.")) + +(unless (or (executable-find "mbsync") + (executable-find "offlineimap")) + (wan! "Couldn't find mbsync or offlineimap command. \ +You may not have a way of fetching mail.")) + +(when (and (featurep! :lang org) + (not IS-WINDOWS)) + (unless (executable-find "identify") + (warn! "Couldn't find the identify command from imagemagik. \ +LaTeX fragment re-scaling with org-msg will not work."))) From 940177613e1d6506564c0837c136a79645227f9f Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 1 Oct 2020 18:23:28 +0800 Subject: [PATCH 019/119] Mu4e: Tidy and tweak default settings --- modules/email/mu4e/config.el | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 2e3cb5123..b2808ada4 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -51,16 +51,22 @@ (t #'ido-completing-read)) ;; no need to ask mu4e-confirm-quit nil + mu4e-headers-thread-single-orphan-prefix '("─>" . "─▶") + mu4e-headers-thread-orphan-prefix '("┬>" . "┬▶ ") + mu4e-headers-thread-last-child-prefix '("└>" . "╰▶") + mu4e-headers-thread-child-prefix '("├>" . "├▶") + mu4e-headers-thread-connection-prefix '("│" . "│ ") ;; remove 'lists' column mu4e-headers-fields '((:account . 12) - (:human-date . 12) - (:flags . 4) + (:human-date . 8) + (:flags . 6) ; 3 icon flags (:from . 25) (:subject))) ;; set mail user agent - (setq mail-user-agent 'mu4e-user-agent) + (setq mail-user-agent 'mu4e-user-agent + message-mail-user-agent 'mu4e-user-agent) ;; Set the icons only when a graphical frame has been created (if (display-graphic-p) @@ -72,16 +78,9 @@ (mu4e~initialise-icons) (remove-hook #'mu4e~initialise-icons-hook))))) - ;; Header view - - (setq mu4e-headers-fields - '((:account . 12) - (:human-date . 8) - (:flags . 6) ; 3 icon flags - (:from . 25) - (:subject))) - (plist-put (cdr (assoc :flags mu4e-header-info)) :shortname " Flags") ; default=Flgs + (add-to-list 'mu4e-bookmarks + '(:name "Flagged messages" :query "flag:flagged" :key ?f)) (defvar mu4e~header-colourised-faces '(all-the-icons-lblue From f7a247906477a2b7e2be571253d478432da309f7 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 1 Oct 2020 19:16:33 +0800 Subject: [PATCH 020/119] Mu4e: Add nuance to Gmail-specific behaviour for the non-gmail accounts out there --- modules/email/mu4e/README.org | 3 +- modules/email/mu4e/config.el | 56 +++++++++++++++++++++++++++++------ 2 files changed, 49 insertions(+), 10 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index a7b831243..e9396175c 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -36,7 +36,8 @@ via IMAP) and ~mu~ (to index my mail into a format ~mu4e~ can understand). #+end_quote ** Module Flags -+ ~+gmail~ Enables gmail-specific configuration. ++ ~+gmail~ Enables gmail-specific configuration for mail ~To~ or ~From~ a gmail + address, or a maildir with ~gmail~ in the name. ** Plugins + [[https://github.com/jeremy-compostella/org-msg][org-msg]] diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index b2808ada4..29c037ec6 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -325,7 +325,10 @@ Must be set before org-msg is loaded to take effect.") (when (featurep! +gmail) (after! mu4e ;; don't save message to Sent Messages, Gmail/IMAP takes care of this - (setq mu4e-sent-messages-behavior 'delete + (setq mu4e-sent-messages-behavior + (lambda () + (if (string-match-p "@gmail.com\\'" (message-sendmail-envelope-from)) + 'delete 'sent)) ;; don't need to run cleanup after indexing for gmail mu4e-index-cleanup nil @@ -334,6 +337,19 @@ Must be set before org-msg is loaded to take effect.") ;; messages don't really "move" mu4e-index-lazy-check t) + (defun +mu4e-msg-gmail-p (msg) + (or + (string-match-p "gmail" + (cond + ((member (mu4e-message-field msg :to) + (plist-get mu4e~server-props :personal-addresses)) + (mu4e-message-field msg :to)) + ((member (mu4e-message-field msg :from) + (plist-get mu4e~server-props :personal-addresses)) + (mu4e-message-field msg :from)) + (t ""))) + (string-match-p "gmail" (mu4e-message-field msg :maildir)))) + ;; 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'. @@ -342,18 +358,39 @@ Must be set before org-msg is loaded to take effect.") (defun +mu4e--mark-seen (docid _msg target) (mu4e~proc-move docid (mu4e~mark-check-target target) "+S-u-N")) + (defvar +mu4e--last-invalid-gmail-action 0) + (delq! 'delete mu4e-marks #'assq) - (setf (alist-get 'trash mu4e-marks) + (setf (alist-get 'delete mu4e-marks) + (list + :char '("D" . "✘") + :prompt "Delete" + :show-target (lambda (target) "delete") + :action (lambda (docid msg target) + (if (+mu4e-msg-gmail-p msg) + (progn (message "The delete operation is invalid for Gmail accounts.") + (when (< 2 (- (float-time) +mu4e--last-invalid-gmail-action)) + (sit-for 1)) + (setq +mu4e--last-invalid-gmail-action (float-time))) + (mu4e~proc-remove docid)))) + (alist-get 'trash mu4e-marks) (list :char '("d" . "▼") :prompt "dtrash" :dyn-target (lambda (_target msg) (mu4e-get-trash-folder msg)) - :action #'+mu4e--mark-seen) + :action (lambda (docid msg target) + (if (+mu4e-msg-gmail-p msg) + (+mu4e--mark-seen docid msg target) + (mu4e~proc-move docid (mu4e~mark-check-target target) "+T-N")))) ;; Refile will be my "archive" function. (alist-get 'refile mu4e-marks) (list :char '("r" . "▼") :prompt "rrefile" :dyn-target (lambda (_target msg) (mu4e-get-refile-folder msg)) - :action #'+mu4e--mark-seen)) + :action (lambda (docid msg target) + (if (+mu4e-msg-gmail-p msg) + (+mu4e--mark-seen docid msg target) + (mu4e~proc-move docid (mu4e~mark-check-target target) "-N"))) + #'+mu4e--mark-seen)) ;; This hook correctly modifies gmail flags on emails when they are marked. ;; Without it, refiling (archiving), trashing, and flagging (starring) email @@ -361,8 +398,9 @@ Must be set before org-msg is loaded to take effect.") ;; are ineffectual otherwise. (add-hook! 'mu4e-mark-execute-pre-hook (defun +mu4e-gmail-fix-flags-h (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"))))))) + (when (+mu4e-msg-gmail-p 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")))))))) From 3179942dfbff207e440d5706d10b706e8722de33 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 2 Oct 2020 11:53:58 +0800 Subject: [PATCH 021/119] Mu4e: Make the delete action trash for gmail --- modules/email/mu4e/config.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 29c037ec6..dbd2fdf82 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -368,7 +368,8 @@ Must be set before org-msg is loaded to take effect.") :show-target (lambda (target) "delete") :action (lambda (docid msg target) (if (+mu4e-msg-gmail-p msg) - (progn (message "The delete operation is invalid for Gmail accounts.") + (progn (message "The delete operation is invalid for Gmail accounts. Trashing instead.") + (+mu4e--mark-seen docid msg target) (when (< 2 (- (float-time) +mu4e--last-invalid-gmail-action)) (sit-for 1)) (setq +mu4e--last-invalid-gmail-action (float-time))) @@ -401,6 +402,7 @@ Must be set before org-msg is loaded to take effect.") (when (+mu4e-msg-gmail-p msg) (pcase mark (`trash (mu4e-action-retag-message msg "-\\Inbox,+\\Trash,-\\Draft")) + (`delete (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")))))))) From 82c99b78f2336b2976ed9b31904c36acc7ae1dac Mon Sep 17 00:00:00 2001 From: TEC Date: Sun, 4 Oct 2020 01:00:01 +0800 Subject: [PATCH 022/119] Mu4e: add missing header colourising function --- modules/email/mu4e/config.el | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index dbd2fdf82..ef73a94d6 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -82,7 +82,14 @@ (add-to-list 'mu4e-bookmarks '(:name "Flagged messages" :query "flag:flagged" :key ?f)) - (defvar mu4e~header-colourised-faces + (defun mu4e-header-colourise (str) + (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) + (colour (nth (% str-sum (length mu4e-header-colourised-faces)) + mu4e-header-colourised-faces))) + (put-text-property 0 (length str) 'face colour str) + str)) + + (defvar mu4e-header-colourised-faces '(all-the-icons-lblue all-the-icons-purple all-the-icons-blue-alt From 79f8107e435606d7ae5ad28d9182873646017f85 Mon Sep 17 00:00:00 2001 From: TEC Date: Sun, 4 Oct 2020 01:01:00 +0800 Subject: [PATCH 023/119] Mu4e: have =mu4e replace an empty workspace --- modules/email/mu4e/autoload/email.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 9b87845a3..bf611ea3b 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -55,7 +55,12 @@ default/fallback account." (interactive) (require 'mu4e) (if (featurep! :ui workspaces) - (+workspace-switch +mu4e-workspace-name t) + ;; delete current workspace if empty + ;; this is useful when mu4e is in the daemon + ;; as otherwise you can accumulate empty workspaces + (unless (+workspace-buffer-list) + (+workspace-delete (+workspace-current-name))) + (+workspace-switch +mu4e-workspace-name t) (setq +mu4e--old-wconf (current-window-configuration)) (delete-other-windows) (switch-to-buffer (doom-fallback-buffer))) From d926ecd2741ddd2f7b8749f1376e46b48f152a52 Mon Sep 17 00:00:00 2001 From: TEC Date: Sun, 4 Oct 2020 01:02:43 +0800 Subject: [PATCH 024/119] Mu4e: rename my-mu4e-* function to +mu4e-* --- modules/email/mu4e/autoload/email.el | 2 +- modules/email/mu4e/config.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index bf611ea3b..b77bd8974 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -193,7 +193,7 @@ is tomorrow. With two prefixes, select the deadline." (t "later")))))) ;;;###autoload -(defun my-mu4e-set-account () +(defun +mu4e-set-account () "Set the account for composing a message. If a 'To' header is present, and correspands to an email account, this account will be selected. Otherwise, the user is prompted for the account they wish to use." diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index ef73a94d6..58e6463ce 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -172,7 +172,7 @@ :v "u" #'mu4e-headers-mark-for-unmark :vn "l" #'mu4e-msg-to-agenda)) - (add-hook 'mu4e-compose-pre-hook 'my-mu4e-set-account) + (add-hook 'mu4e-compose-pre-hook '+mu4e-set-account) (advice-add #'mu4e~main-action-str :override #'mu4e~main-action-prettier-str)) From a94832429a3a2b24fddb1d08a345bdf6758cd3b7 Mon Sep 17 00:00:00 2001 From: TEC Date: Sun, 4 Oct 2020 01:03:26 +0800 Subject: [PATCH 025/119] Mu4e: tweak flag bookmark, keymap, mu4e:main end --- modules/email/mu4e/config.el | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 58e6463ce..ba91de452 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -80,7 +80,7 @@ (plist-put (cdr (assoc :flags mu4e-header-info)) :shortname " Flags") ; default=Flgs (add-to-list 'mu4e-bookmarks - '(:name "Flagged messages" :query "flag:flagged" :key ?f)) + '(:name "Flagged messages" :query "flag:flagged" :key ?f) t) (defun mu4e-header-colourise (str) (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) @@ -151,6 +151,9 @@ (when (fboundp 'imagemagick-register-types) (imagemagick-register-types)) + (map! :map mu4e-main-mode-map + :ne "h" #'+workspace/other) + (map! :map mu4e-headers-mode-map :e "l" #'mu4e-msg-to-agenda) @@ -174,7 +177,10 @@ (add-hook 'mu4e-compose-pre-hook '+mu4e-set-account) - (advice-add #'mu4e~main-action-str :override #'mu4e~main-action-prettier-str)) + (advice-add #'mu4e~main-action-str :override #'mu4e~main-action-prettier-str) + (when (featurep! :editor evil) + ;; As mu4e~main-action-prettier-str replaces [k]ey with key q]uit should become quit + (setq evil-collection-mu4e-end-region-misc "quit"))) (use-package! org-msg :after mu4e From 18ca0d4e4e3ea5626e1275cd394c8d8f15e80375 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 10 Oct 2020 03:20:59 +0800 Subject: [PATCH 026/119] Mu4e: Improve reply face colouring --- modules/email/mu4e/config.el | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index ba91de452..70ea0a824 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -68,6 +68,15 @@ (setq mail-user-agent 'mu4e-user-agent message-mail-user-agent 'mu4e-user-agent) + ;; Make reply colouring consistant, and striped for readability + (custom-set-faces! + '(gnus-cite-2 :foreground nil :inherit gnus-cite-10) + '(gnus-cite-3 :foreground nil :inherit gnus-cite-7) + '(message-cited-text-1 :foreground nil :inherit gnus-cite-1) + '(message-cited-text-2 :foreground nil :inherit gnus-cite-2) + '(message-cited-text-3 :foreground nil :inherit gnus-cite-3) + '(message-cited-text-4 :foreground nil :inherit gnus-cite-4)) + ;; Set the icons only when a graphical frame has been created (if (display-graphic-p) (mu4e~initialise-icons) From aaaabacc9f36cd345052723c90f5360b61dc08cf Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 10 Oct 2020 03:28:58 +0800 Subject: [PATCH 027/119] Mu4e: alerts (first pass) --- modules/email/mu4e/config.el | 58 ++++++++++++++++++++++++++++++++++ modules/email/mu4e/packages.el | 2 ++ 2 files changed, 60 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 70ea0a824..c52e6e91a 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -428,3 +428,61 @@ Must be set before org-msg is loaded to take effect.") (`refile (mu4e-action-retag-message msg "-\\Inbox")) (`flag (mu4e-action-retag-message msg "+\\Starred")) (`unflag (mu4e-action-retag-message msg "-\\Starred")))))))) + +;; +;;; Alerts + +(use-package! mu4e-alert + :after mu4e + :config + (setq doom-modeline-mu4e t) + + (mu4e-alert-enable-mode-line-display) + (mu4e-alert-enable-notifications) + + (when IS-LINUX + (mu4e-alert-set-default-style 'libnotify) + + (setq mu4e-alert-email-notification-types '(subjects)) + (defun mu4e-alert-grouped-mail-notification-formatter-with-bell (mail-group all-mails) + "Default function to format MAIL-GROUP for notification. +ALL-MAILS are the all the unread emails" + (shell-command "paplay /usr/share/sounds/freedesktop/stereo/message.oga") + (if (> (length mail-group) 1) + (let* ((mail-count (length mail-group)) + (total-mails (length all-mails)) + (first-mail (car mail-group)) + (title-prefix (format "You have %d unread emails" + mail-count)) + (field-value (mu4e-alert--get-group first-mail)) + (title-suffix (format (pcase mu4e-alert-group-by + (`:from "from %s:") + (`:to "to %s:") + (`:maildir "in %s:") + (`:priority "with %s priority:") + (`:flags "with %s flags:")) + field-value)) + (title (format "%s %s" title-prefix title-suffix))) + (list :title title + :body (s-join "\n" + (mapcar (lambda (mail) + (format "%s%s • %s" + (cond + ((plist-get mail :in-reply-to) "⮩ ") + ((string-match-p "\\`Fwd:" + (plist-get mail :subject)) " ⮯ ") + (t "  ")) + (truncate-string-to-width (caar (plist-get mail :from)) + 20 nil nil t) + (truncate-string-to-width + (replace-regexp-in-string "\\`Re: \\|\\`Fwd: " "" + (plist-get mail :subject)) + 40 nil nil t))) + mail-group)))) + (let* ((new-mail (car mail-group)) + (subject (plist-get new-mail :subject)) + (sender (caar (plist-get new-mail :from)))) + (list :title sender :body subject)))) + (setq mu4e-alert-grouped-mail-notification-formatter #'mu4e-alert-grouped-mail-notification-formatter-with-bell)) + + (mu4e-alert-enable-mode-line-display)) diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index 2be20229a..808b419d9 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -3,3 +3,5 @@ (when (featurep! :lang org) (package! org-msg :pin "2db6725c4a4f4342a9c61895b7c3c82795b01fee")) + +(package! mu4e-alert :pin "91f0657c5b245a9de57aa38391221fb5d141d9bd") From 825ea7649543caf83b8cc72b7311b396cc83ef6c Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 14:52:31 +0800 Subject: [PATCH 028/119] Mu4e: org-msg join lines to para (as normal) --- modules/email/mu4e/config.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index c52e6e91a..9ad502bae 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -195,7 +195,7 @@ :after mu4e :when (featurep! :lang org) :config - (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil \\n:t tex:dvipng" + (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil tex:dvipng" org-msg-startup "hidestars indent inlineimages" org-msg-greeting-fmt "\nHi %s,\n\n" org-msg-greeting-name-limit 3 From 773d2b566423ca25472bc15d7d12fe558c683131 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 14:55:02 +0800 Subject: [PATCH 029/119] Mu4e: org-msg, tweak line width and spacing --- modules/email/mu4e/config.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 9ad502bae..472139599 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -293,7 +293,8 @@ Must be set before org-msg is loaded to take effect.") (background-color . ,(doom-color 'bg)) (margin . "4px 0px 8px 0px") (padding . "8px 12px") - (width . "95%") + (width . "max-content") + (min-width . "80ch") (border-radius . "5px") (font-weight . "500") ,monospace-font)) @@ -334,9 +335,9 @@ Must be set before org-msg is loaded to take effect.") ,color (font-size . "18pt"))) (h1 nil ((margin-top . "20px") (margin-bottom . "0px") ,color (font-size . "24pt"))) - (p nil ((text-decoration . "none") (line-height . "11pt") + (p nil ((text-decoration . "none") (line-height . "1.4") (margin-top . "10px") (margin-bottom . "0px") - ,font-size (max-width . "100ch"))) + ,font-size (max-width . "90ch"))) (b nil ((font-weight . "500") (color . ,theme-color))) (div nil (,@font (line-height . "12pt"))))))) From 362f682f1d1c3b9ca0ad0fdd26a98720e2853e70 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 15:40:59 +0800 Subject: [PATCH 030/119] Mu4e: add xwidget view option when available --- modules/email/mu4e/config.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 472139599..706271b99 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -160,6 +160,10 @@ (when (fboundp 'imagemagick-register-types) (imagemagick-register-types)) + (when (fboundp 'xwidget-webkit-browse-url) + (push '("view with xwidgets" . mu4e-action-view-with-xwidget) + mu4e-view-actions)) + (map! :map mu4e-main-mode-map :ne "h" #'+workspace/other) From b609b82d954b49ec26acf4a867eebccc981873c7 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 16:30:54 +0800 Subject: [PATCH 031/119] Mu4e: make "gmail in email adr" condition stricter --- modules/email/mu4e/config.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 706271b99..0a109e18d 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -366,7 +366,7 @@ Must be set before org-msg is loaded to take effect.") (defun +mu4e-msg-gmail-p (msg) (or - (string-match-p "gmail" + (string-match-p "@gmail.com" (cond ((member (mu4e-message-field msg :to) (plist-get mu4e~server-props :personal-addresses)) From 6118ad5c124c2fa436abd19fe087de0f836c59d7 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 16:41:33 +0800 Subject: [PATCH 032/119] Mu4e: enforce consistent naming scheme, "+" prefix --- modules/email/mu4e/autoload/email.el | 36 +++++++++---------- modules/email/mu4e/config.el | 54 ++++++++++++++-------------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index b77bd8974..5fb1b6c99 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -93,7 +93,7 @@ will also be the width of all other printable characters." (car (window-text-pixel-size))))) ;;;###autoload -(cl-defun mu4e~normalised-icon (name &key set colour height v-adjust) +(cl-defun +mu4e-normalised-icon (name &key set colour height v-adjust) "Convert :icon declaration to icon" (let* ((icon-set (intern (concat "all-the-icons-" (or set "faicon")))) (v-adjust (or v-adjust 0.02)) @@ -108,22 +108,22 @@ will also be the width of all other printable characters." ;; Set up all the fancy icons ;;;###autoload -(defun mu4e~initialise-icons () +(defun +mu4e-initialise-icons () (setq mu4e-use-fancy-chars t - mu4e-headers-draft-mark (cons "D" (mu4e~normalised-icon "pencil")) - mu4e-headers-flagged-mark (cons "F" (mu4e~normalised-icon "flag")) - mu4e-headers-new-mark (cons "N" (mu4e~normalised-icon "sync" :set "material" :height 0.8 :v-adjust -0.10)) - mu4e-headers-passed-mark (cons "P" (mu4e~normalised-icon "arrow-right")) - mu4e-headers-replied-mark (cons "R" (mu4e~normalised-icon "arrow-right")) - mu4e-headers-seen-mark (cons "S" "") ;(mu4e~normalised-icon "eye" :height 0.6 :v-adjust 0.07 :colour "dsilver")) - mu4e-headers-trashed-mark (cons "T" (mu4e~normalised-icon "trash")) - mu4e-headers-attach-mark (cons "a" (mu4e~normalised-icon "file-text-o" :colour "silver")) - mu4e-headers-encrypted-mark (cons "x" (mu4e~normalised-icon "lock")) - mu4e-headers-signed-mark (cons "s" (mu4e~normalised-icon "certificate" :height 0.7 :colour "dpurple")) - mu4e-headers-unread-mark (cons "u" (mu4e~normalised-icon "eye-slash" :v-adjust 0.05)))) + mu4e-headers-draft-mark (cons "D" (+mu4e-normalised-icon "pencil")) + mu4e-headers-flagged-mark (cons "F" (+mu4e-normalised-icon "flag")) + mu4e-headers-new-mark (cons "N" (+mu4e-normalised-icon "sync" :set "material" :height 0.8 :v-adjust -0.10)) + mu4e-headers-passed-mark (cons "P" (+mu4e-normalised-icon "arrow-right")) + mu4e-headers-replied-mark (cons "R" (+mu4e-normalised-icon "arrow-right")) + mu4e-headers-seen-mark (cons "S" "") ;(+mu4e-normalised-icon "eye" :height 0.6 :v-adjust 0.07 :colour "dsilver")) + mu4e-headers-trashed-mark (cons "T" (+mu4e-normalised-icon "trash")) + mu4e-headers-attach-mark (cons "a" (+mu4e-normalised-icon "file-text-o" :colour "silver")) + mu4e-headers-encrypted-mark (cons "x" (+mu4e-normalised-icon "lock")) + mu4e-headers-signed-mark (cons "s" (+mu4e-normalised-icon "certificate" :height 0.7 :colour "dpurple")) + mu4e-headers-unread-mark (cons "u" (+mu4e-normalised-icon "eye-slash" :v-adjust 0.05)))) ;;;###autoload -(defun mu4e~header-colourise (str) +(defun +mu4e-header-colourise (str) (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) (colour (nth (% str-sum (length mu4e-header-colourised-faces)) mu4e-header-colourised-faces))) @@ -134,7 +134,7 @@ will also be the width of all other printable characters." ;; Perfect for when you see an email you want to reply to ;; later, but don't want to forget about ;;;###autoload -(defun mu4e-msg-to-agenda (arg) +(defun +mu4e-msg-to-agenda (arg) "Refile a message and add a entry in the agenda file with a deadline. Default deadline is today. With one prefix, deadline is tomorrow. With two prefixes, select the deadline." @@ -208,7 +208,7 @@ Otherwise, the user is prompted for the account they wish to use." (ivy-read "Account: " (plist-get mu4e~server-props :personal-addresses) :action (lambda (candidate) (setq user-mail-address candidate))))) ;;;###autoload -(defun mu4e~main-action-prettier-str (str &optional func-or-shortcut) +(defun +mu4e~main-action-str-prettier (str &optional func-or-shortcut) "Highlight the first occurrence of [.] in STR. If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is @@ -268,7 +268,7 @@ clicked." (list :style (format "transform: scale(%.3f)" (/ 1.0 (plist-get org-format-latex-options :scale)))))) -(defun org-html-latex-fragment-scaled (latex-fragment _contents info) +(defun +org-html-latex-fragment-scaled (latex-fragment _contents info) "Transcode a LATEX-FRAGMENT object from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information. @@ -299,7 +299,7 @@ account for the value of :scale in `org-format-latex-options'." (org-html--format-image source attributes info))))) (t latex-frag)))) -(defun org-html-latex-environment-scaled (latex-environment _contents info) +(defun +org-html-latex-environment-scaled (latex-environment _contents info) "Transcode a LATEX-ENVIRONMENT element from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information. diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 0a109e18d..359a210b7 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -79,26 +79,26 @@ ;; Set the icons only when a graphical frame has been created (if (display-graphic-p) - (mu4e~initialise-icons) + (+mu4e-initialise-icons) ;; When it's the server, wait till the first graphical frame (add-hook! 'server-after-make-frame-hook - (defun mu4e~initialise-icons-hook () + (defun +mu4e-initialise-icons-hook () (when (display-graphic-p) - (mu4e~initialise-icons) - (remove-hook #'mu4e~initialise-icons-hook))))) + (+mu4e-initialise-icons) + (remove-hook #'+mu4e-initialise-icons-hook))))) (plist-put (cdr (assoc :flags mu4e-header-info)) :shortname " Flags") ; default=Flgs (add-to-list 'mu4e-bookmarks '(:name "Flagged messages" :query "flag:flagged" :key ?f) t) - (defun mu4e-header-colourise (str) + (defun +mu4e-header-colourise (str) (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) - (colour (nth (% str-sum (length mu4e-header-colourised-faces)) - mu4e-header-colourised-faces))) + (colour (nth (% str-sum (length ++mu4e-header-colourised-faces)) + ++mu4e-header-colourised-faces))) (put-text-property 0 (length str) 'face colour str) str)) - (defvar mu4e-header-colourised-faces + (defvar ++mu4e-header-colourised-faces '(all-the-icons-lblue all-the-icons-purple all-the-icons-blue-alt @@ -117,7 +117,7 @@ (lambda (msg) (let ((maildir (mu4e-message-field msg :maildir))) - (mu4e-header-colourise + (+mu4e-header-colourise (replace-regexp-in-string "^gmail" (propertize "g" 'face 'bold-italic) @@ -168,7 +168,7 @@ :ne "h" #'+workspace/other) (map! :map mu4e-headers-mode-map - :e "l" #'mu4e-msg-to-agenda) + :e "l" #'+mu4e-msg-to-agenda) (map! :localleader :map mu4e-compose-mode-map @@ -186,13 +186,13 @@ :v "!" #'mu4e-headers-mark-for-read :v "?" #'mu4e-headers-mark-for-unread :v "u" #'mu4e-headers-mark-for-unmark - :vn "l" #'mu4e-msg-to-agenda)) + :vn "l" #'+mu4e-msg-to-agenda)) (add-hook 'mu4e-compose-pre-hook '+mu4e-set-account) - (advice-add #'mu4e~main-action-str :override #'mu4e~main-action-prettier-str) + (advice-add #'mu4e~main-action-str :override #'+mu4e~main-action-str-prettier) (when (featurep! :editor evil) - ;; As mu4e~main-action-prettier-str replaces [k]ey with key q]uit should become quit + ;; As +mu4e~main-action-str-prettier replaces [k]ey with key q]uit should become quit (setq evil-collection-mu4e-end-region-misc "quit"))) (use-package! org-msg @@ -205,26 +205,26 @@ org-msg-greeting-name-limit 3 org-msg-text-plain-alternative t) - (defvar org-msg-currently-exporting nil + (defvar +org-msg-currently-exporting nil "Helper variable to indicate whether org-msg is currently exporting the org buffer to HTML. Usefull for affecting HTML export config.") - (defadvice! org-msg--now-exporting (&rest _) + (defadvice! +org-msg--now-exporting (&rest _) :before #'org-msg-org-to-xml - (setq org-msg-currently-exporting t)) - (defadvice! org-msg--not-exporting (&rest _) + (setq +org-msg-currently-exporting t)) + (defadvice! +org-msg--not-exporting (&rest _) :after #'org-msg-org-to-xml - (setq org-msg-currently-exporting nil)) + (setq +org-msg-currently-exporting nil)) - (advice-add #'org-html-latex-fragment :override #'org-html-latex-fragment-scaled) - (advice-add #'org-html-latex-environment :override #'org-html-latex-environment-scaled) + (advice-add #'org-html-latex-fragment :override #'+org-html-latex-fragment-scaled) + (advice-add #'org-html-latex-environment :override #'+org-html-latex-environment-scaled) - (defvar mu4e-compose--org-msg-toggle-next t ; t to initialise org-msg + (defvar +mu4e-compose-org-msg-toggle-next t ; t to initialise org-msg "Whether to toggle ") (defun mu4e-compose-org-msg-handle-toggle (toggle-p) - (when (xor toggle-p mu4e-compose--org-msg-toggle-next) + (when (xor toggle-p +mu4e-compose-org-msg-toggle-next) (org-msg-mode (if org-msg-mode -1 1)) - (setq mu4e-compose--org-msg-toggle-next - (not mu4e-compose--org-msg-toggle-next)))) + (setq +mu4e-compose-org-msg-toggle-next + (not +mu4e-compose-org-msg-toggle-next)))) (defadvice! mu4e-maybe-toggle-org-msg (orig-fn toggle-p) :around #'mu4e-compose-new @@ -353,7 +353,7 @@ Must be set before org-msg is loaded to take effect.") (after! mu4e ;; don't save message to Sent Messages, Gmail/IMAP takes care of this (setq mu4e-sent-messages-behavior - (lambda () + (lambda () ;; TODO make use +mu4e-msg-gmail-p (if (string-match-p "@gmail.com\\'" (message-sendmail-envelope-from)) 'delete 'sent)) @@ -449,7 +449,7 @@ Must be set before org-msg is loaded to take effect.") (mu4e-alert-set-default-style 'libnotify) (setq mu4e-alert-email-notification-types '(subjects)) - (defun mu4e-alert-grouped-mail-notification-formatter-with-bell (mail-group all-mails) + (defun +mu4e-alert-grouped-mail-notification-formatter-with-bell (mail-group all-mails) "Default function to format MAIL-GROUP for notification. ALL-MAILS are the all the unread emails" (shell-command "paplay /usr/share/sounds/freedesktop/stereo/message.oga") @@ -488,6 +488,6 @@ ALL-MAILS are the all the unread emails" (subject (plist-get new-mail :subject)) (sender (caar (plist-get new-mail :from)))) (list :title sender :body subject)))) - (setq mu4e-alert-grouped-mail-notification-formatter #'mu4e-alert-grouped-mail-notification-formatter-with-bell)) + (setq mu4e-alert-grouped-mail-notification-formatter #'+mu4e-alert-grouped-mail-notification-formatter-with-bell)) (mu4e-alert-enable-mode-line-display)) From 3f1b27500a963a020de29147e393a1a3ec8ba602 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 16:43:22 +0800 Subject: [PATCH 033/119] Mu4e: Readme, note use of mu4e-alert and document how-to disable packages (since it seems like disabling org-msg) is a frequent request. --- modules/email/mu4e/README.org | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index e9396175c..90a7c9b9d 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -41,6 +41,13 @@ via IMAP) and ~mu~ (to index my mail into a format ~mu4e~ can understand). ** Plugins + [[https://github.com/jeremy-compostella/org-msg][org-msg]] ++ [[https://github.com/iqbalansari/mu4e-alert][mu4e-alert]] + +To disable either of these packages, simply add +#+begin_src emacs-lisp +(package! X :disable t) +#+end_src +to your [[elisp:(find-file (expand-file-name (concat "config." (if (featurep! :config literate) "org" "el")) doom-private-dir))][config]] (where =X= is the package in question) and it will not be used. * Prerequisites This module requires: From fdc8effd0a4b9a0859603952cc208c0658067852 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 16:44:29 +0800 Subject: [PATCH 034/119] Mu4e: Readme, first pass of features section --- modules/email/mu4e/README.org | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 90a7c9b9d..4717c5691 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -111,7 +111,22 @@ sudo apt-get install offlineimap # then sudo apt-get install maildir-utils mu4e # mu and mu4e respectivly #+END_SRC -* TODO Features + +* Features ++ Tidied mu4e headers view, with flags from =all-the-icons= ++ Consistent colouring of reply depths (across compose and gnus modes) ++ Prettified =mu4e:main= view ++ =org-msg= integration + - can be toggled per-message by applying the + universal argument (=SPC u=) to the compose/reply/forward action. + - The initial value of ~+mu4e-compose-org-msg-toggle-next~ determines the default + composition mode (this can be toggled with =M-x org-msg-mode= as usual). + - A revamped custom style, with an accent colour that can be customised by + setting ~+org-msg-accent-color~) ++ Gmail integrations with the =+gmail= flag, which account for the different behaviour. + This is applied when using addresses which contain =@gmail.com= or have =gmail= in + the maildir name. ++ Email notifications with =mu4e-alert=, and (on Linux) a customised notification style * Configuration ** offlineimap From c59a1ff498024e45efdc2cae4dc265c0d7770e49 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 17:21:52 +0800 Subject: [PATCH 035/119] Mu4e: cooperative lock control --- modules/email/mu4e/README.org | 2 + modules/email/mu4e/autoload/email.el | 94 ++++++++++++++++++++++++++++ modules/email/mu4e/config.el | 12 +++- 3 files changed, 107 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 4717c5691..b7a285a6c 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -116,6 +116,8 @@ sudo apt-get install maildir-utils mu4e # mu and mu4e respectivly + Tidied mu4e headers view, with flags from =all-the-icons= + Consistent colouring of reply depths (across compose and gnus modes) + Prettified =mu4e:main= view ++ Cooperative locking of the =mu= process. Another Emacs instance may request + access, or grab the lock when it's available. + =org-msg= integration - can be toggled per-message by applying the universal argument (=SPC u=) to the compose/reply/forward action. diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 5fb1b6c99..bef0961e4 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -268,6 +268,7 @@ clicked." (list :style (format "transform: scale(%.3f)" (/ 1.0 (plist-get org-format-latex-options :scale)))))) +;;;###autoload (defun +org-html-latex-fragment-scaled (latex-fragment _contents info) "Transcode a LATEX-FRAGMENT object from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information. @@ -299,6 +300,7 @@ account for the value of :scale in `org-format-latex-options'." (org-html--format-image source attributes info))))) (t latex-frag)))) +;;;###autoload (defun +org-html-latex-environment-scaled (latex-environment _contents info) "Transcode a LATEX-ENVIRONMENT element from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information. @@ -343,3 +345,95 @@ scales the image to account for the value of :scale in `org-format-latex-options (org-html--format-image source attributes info) info caption label))))) (t (org-html--wrap-latex-environment latex-frag info caption label))))) + +;; +;; Cooperative locking + +(defvar +mu4e-lock-file "/tmp/mu4e_lock" + "Location of the lock file which stores the PID of the process currenty running mu4e") +(defvar +mu4e-lock-request-file "/tmp/mu4e_lock_request" + "Location of the lock file for which creating indicated that another process wants the lock to be released") + +(defvar +mu4e-lock-greedy nil + "Whether to 'grab' the `+mu4e-lock-file' if nobody else has it, i.e. start Mu4e") +(defvar +mu4e-lock-relaxed nil + "Whether if someone else wants the lock (signaled via `+mu4e-lock-request-file'), we should stop Mu4e and let go of it") + +;;;###autoload +(defun +mu4e-lock-pid-info () + "Get info on the PID refered to in `+mu4e-lock-file' in the form (pid . process-attributes) + If the file or process do not exist, the lock file is deleted an nil returned." + (when (file-exists-p +mu4e-lock-file) + (let* ((pid (string-to-number (f-read-text +mu4e-lock-file 'utf-8))) + (process (process-attributes pid))) + (if process (cons pid process) + (delete-file +mu4e-lock-file) nil)))) + +;;;###autoload +(defun +mu4e-lock-avalible (&optional strict) + "If the `+mu4e-lock-file' is avalible (unset or owned by this emacs) return t. +If STRICT only accept an unset lock file." + (not (when-let* ((lock-info (+mu4e-lock-pid-info)) + (pid (car lock-info))) + (when (or strict (/= (emacs-pid) pid)) t)))) + +;;;###autoload +(defun +mu4e-lock-file-delete-maybe () + "Check `+mu4e-lock-file', and delete it if this process is responsible for it." + (when (+mu4e-lock-avalible) + (delete-file +mu4e-lock-file) + (file-notify-rm-watch +mu4e-lock--request-watcher))) + +;;;###autoload +(defun +mu4e-lock-start (orig-fun &optional callback) + "Check `+mu4e-lock-file', and if another process is responsible for it, abort starting. +Else, write to this process' PID to the lock file" + (unless (+mu4e-lock-avalible) + (shell-command (format "touch %s" +mu4e-lock-request-file)) + (message "Lock file exists, requesting that it be given up") + (sleep-for 0.1) + (delete-file +mu4e-lock-request-file)) + (if (not (+mu4e-lock-avalible)) + (user-error "Unfortunately another Emacs is already doing stuff with Mu4e, and you can only have one at a time") + (f-write-text (number-to-string (emacs-pid)) 'utf-8 +mu4e-lock-file) + (delete-file +mu4e-lock-request-file) + (funcall orig-fun callback) + (setq +mu4e-lock--request-watcher + (file-notify-add-watch +mu4e-lock-request-file + '(change) + #'+mu4e-lock-request)))) + +(defvar +mu4e-lock--file-watcher nil) +(defvar +mu4e-lock--file-just-deleted nil) +(defvar +mu4e-lock--request-watcher nil) + +;;;###autoload +(defun +mu4e-lock-add-watcher () + (setq +mu4e-lock--file-just-deleted nil) + (file-notify-rm-watch +mu4e-lock--file-watcher) + (setq +mu4e-lock--file-watcher + (file-notify-add-watch +mu4e-lock-file + '(change) + #'++mu4e-lock-file-updated))) + +;;;###autoload +(defun +mu4e-lock-request (event) + "Handle another process requesting the Mu4e lock." + (when (equal (nth 1 event) 'created) + (when +mu4e-lock-relaxed + (mu4e~stop) + (file-notify-rm-watch +mu4e-lock--file-watcher) + (message "Someone else wants to use Mu4e, releasing lock") + (delete-file +mu4e-lock-file) + (run-at-time 0.2 nil #'+mu4e-lock-add-watcher)) + (delete-file +mu4e-lock-request-file))) + +;;;###autoload +(defun ++mu4e-lock-file-updated (event) + (if +mu4e-lock--file-just-deleted + (+mu4e-lock-add-watcher) + (when (equal (nth 1 event) 'deleted) + (setq +mu4e-lock--file-just-deleted t) + (when (and +mu4e-lock-greedy (+mu4e-lock-avalible t)) + (message "Noticed Mu4e lock was avalible, grabbed it") + (run-at-time 0.2 nil #'mu4e~start))))) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 359a210b7..353d2b41f 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -193,7 +193,17 @@ (advice-add #'mu4e~main-action-str :override #'+mu4e~main-action-str-prettier) (when (featurep! :editor evil) ;; As +mu4e~main-action-str-prettier replaces [k]ey with key q]uit should become quit - (setq evil-collection-mu4e-end-region-misc "quit"))) + (setq evil-collection-mu4e-end-region-misc "quit")) + + ;; process lock control + (when IS-WINDOWS + (setq ;; REVIEW untested + +mu4e-lock-file (expand-file-name "%userprofile%\\AppData\\Local\\Temp\\mu4e_lock") + +mu4e-lock-request-file (expand-file-name "%userprofile%\\AppData\\Local\\Temp\\mu4e_lock_request"))) + + (add-hook 'kill-emacs-hook #'+mu4e-lock-file-delete-maybe) + (advice-add 'mu4e~start :around #'+mu4e-lock-start) + (advice-add 'mu4e-quit :after #'+mu4e-lock-file-delete-maybe)) (use-package! org-msg :after mu4e From 522c1ca33b7cf88f7f952e01c98b5cbc334f9770 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 17:26:26 +0800 Subject: [PATCH 036/119] Mu4e: Include workspace switch in if true case --- modules/email/mu4e/autoload/email.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index bef0961e4..b5b651f87 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -58,9 +58,10 @@ default/fallback account." ;; delete current workspace if empty ;; this is useful when mu4e is in the daemon ;; as otherwise you can accumulate empty workspaces - (unless (+workspace-buffer-list) - (+workspace-delete (+workspace-current-name))) - (+workspace-switch +mu4e-workspace-name t) + (progn + (unless (+workspace-buffer-list) + (+workspace-delete (+workspace-current-name))) + (+workspace-switch +mu4e-workspace-name t)) (setq +mu4e--old-wconf (current-window-configuration)) (delete-other-windows) (switch-to-buffer (doom-fallback-buffer))) From a8d7d61e4428a130838af27e9e3966efd49e55bd Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 16:49:09 +0200 Subject: [PATCH 037/119] Set context-aware "from" address (mu4e) The user can configure a list of addresses that are associated with a context by passing a list to set-email-account!, e.g. (set-email-account! "foo" ... (+mu4e-personal-addresses ("foo@bar.org" "bar@baz.org"))) This list, if it exists, is used to prompt the user for the "from" address after trying to set the "from" address automatically. --- modules/email/mu4e/autoload/email.el | 18 ++++++++++++------ modules/email/mu4e/config.el | 5 ++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index b5b651f87..287a6c02d 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -15,6 +15,7 @@ OPTIONAL: + `mu4e-trash-folder' + `mu4e-refile-folder' + `mu4e-compose-signature' + + `+mu4e-personal-adresses' DEFAULT-P is a boolean. If non-nil, it marks that email account as the default/fallback account." @@ -194,19 +195,24 @@ is tomorrow. With two prefixes, select the deadline." (t "later")))))) ;;;###autoload -(defun +mu4e-set-account () +(defun +mu4e-set-from-address () "Set the account for composing a message. If a 'To' header is present, -and correspands to an email account, this account will be selected. -Otherwise, the user is prompted for the account they wish to use." +and correspands to an email address, this address will be selected. +Otherwise, the user is prompted for the address they wish to use. Possible +selections come from the mu database or a list of email addresses associated +with the current context." (unless (and mu4e-compose-parent-message (let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to)))) (from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from))))) - (if (member to (plist-get mu4e~server-props :personal-addresses)) + (if (member to (mu4e-personal-addresses)) (setq user-mail-address to) - (if (member from (plist-get mu4e~server-props :personal-addresses)) + (if (member from (mu4e-personal-addresses)) (setq user-mail-address from) nil)))) - (ivy-read "Account: " (plist-get mu4e~server-props :personal-addresses) :action (lambda (candidate) (setq user-mail-address candidate))))) + (ivy-read "From: " (if-let ((context-addresses (alist-get '+mu4e-personal-addresses (mu4e-context-vars mu4e~context-current)))) + context-addresses + (mu4e-personal-addresses)) + :action (lambda (candidate) (setq user-mail-address candidate))))) ;;;###autoload (defun +mu4e~main-action-str-prettier (str &optional func-or-shortcut) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 353d2b41f..2f5183a04 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -3,6 +3,9 @@ (defvar +mu4e-backend 'mbsync "Which backend to use. Can either be offlineimap, mbsync or nil (manual).") +(defvar +mu4e-personal-adresses 'nil + "Alternative to mu4e-personal-adresses that can be set for each account (mu4e context).") + ;; ;;; Packages @@ -188,7 +191,7 @@ :v "u" #'mu4e-headers-mark-for-unmark :vn "l" #'+mu4e-msg-to-agenda)) - (add-hook 'mu4e-compose-pre-hook '+mu4e-set-account) + (add-hook 'mu4e-compose-pre-hook '+mu4e-set-from-address) (advice-add #'mu4e~main-action-str :override #'+mu4e~main-action-str-prettier) (when (featurep! :editor evil) From f3daba3471073b47de47e6ba3044e9efd837e378 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 23:36:55 +0800 Subject: [PATCH 038/119] Mu4e: add support for non-@gmail gmail accounts --- modules/email/mu4e/README.org | 3 ++- modules/email/mu4e/config.el | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index b7a285a6c..be7670e43 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -127,7 +127,8 @@ sudo apt-get install maildir-utils mu4e # mu and mu4e respectivly setting ~+org-msg-accent-color~) + Gmail integrations with the =+gmail= flag, which account for the different behaviour. This is applied when using addresses which contain =@gmail.com= or have =gmail= in - the maildir name. + the maildir name. You can use ~+mu4e-gmail-addresses~ when you want an address + to be treated as such but it meets neither conditions (e.g. with Gsuite). + Email notifications with =mu4e-alert=, and (on Linux) a customised notification style * Configuration diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 2f5183a04..2a66b01b5 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -364,10 +364,18 @@ Must be set before org-msg is loaded to take effect.") (when (featurep! +gmail) (after! mu4e + (defvar +mu4e-gmail-addresses nil + "A list of email addresses which, despite not: +- having '@gmail.com' in them, or +- being in a maildir where the name includes 'gmail' + +Should be treated as a gmail address.") + ;; don't save message to Sent Messages, Gmail/IMAP takes care of this (setq mu4e-sent-messages-behavior (lambda () ;; TODO make use +mu4e-msg-gmail-p - (if (string-match-p "@gmail.com\\'" (message-sendmail-envelope-from)) + (if (or (string-match-p "@gmail.com\\'" (message-sendmail-envelope-from)) + (member (message-sendmail-envelope-from) +mu4e-gmail-addresses)) 'delete 'sent)) ;; don't need to run cleanup after indexing for gmail @@ -382,10 +390,12 @@ Must be set before org-msg is loaded to take effect.") (string-match-p "@gmail.com" (cond ((member (mu4e-message-field msg :to) - (plist-get mu4e~server-props :personal-addresses)) + (append (mu4e-personal-addresses) + +mu4e-gmail-addresses)) (mu4e-message-field msg :to)) ((member (mu4e-message-field msg :from) - (plist-get mu4e~server-props :personal-addresses)) + (append (mu4e-personal-addresses) + +mu4e-gmail-addresses)) (mu4e-message-field msg :from)) (t ""))) (string-match-p "gmail" (mu4e-message-field msg :maildir)))) From 6bf9ecacc743d7adde45731552a06b57b5604edc Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 13 Oct 2020 23:48:42 +0800 Subject: [PATCH 039/119] Mu4e: have relaxed lock by default --- modules/email/mu4e/autoload/email.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 287a6c02d..61f400086 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -363,7 +363,7 @@ scales the image to account for the value of :scale in `org-format-latex-options (defvar +mu4e-lock-greedy nil "Whether to 'grab' the `+mu4e-lock-file' if nobody else has it, i.e. start Mu4e") -(defvar +mu4e-lock-relaxed nil +(defvar +mu4e-lock-relaxed t "Whether if someone else wants the lock (signaled via `+mu4e-lock-request-file'), we should stop Mu4e and let go of it") ;;;###autoload From 06e02eec549d73b347abfc719af522dfc7709f25 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 00:14:34 +0800 Subject: [PATCH 040/119] Mu4e: Reference @tecosaur's goimapnotify use --- modules/email/mu4e/README.org | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index be7670e43..8d3698dbe 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -153,8 +153,8 @@ You can now proceed with the [[#mu-and-mu4e][mu and mu4e]] section. The steps needed to set up =mu4e= with =mbsync= are very similar to the ones for [[#offlineimap][offlineimap]]. -Start with writing a ~\~/.mbsyncrc~. An example for GMAIL can be found on -[[http://pragmaticemacs.com/emacs/migrating-from-offlineimap-to-mbsync-for-mu4e/][pragmaticemacs.com]]. A non-GMAIL example is available as a gist [[https://gist.github.com/agraul/60977cc497c3aec44e10591f94f49ef0][here]]. The [[http://isync.sourceforge.net/mbsync.html][manual +Start with writing a ~\~/.mbsyncrc~. An example for Gmail can be found on +[[http://pragmaticemacs.com/emacs/migrating-from-offlineimap-to-mbsync-for-mu4e/][pragmaticemacs.com]]. A non-Gmail example is available as a gist [[https://gist.github.com/agraul/60977cc497c3aec44e10591f94f49ef0][here]]. The [[http://isync.sourceforge.net/mbsync.html][manual page]] contains all needed information to set up your own. Next you can download your email with ~mbsync --all~. This may take a while, but @@ -162,6 +162,13 @@ should be quicker than =offlineimap= ;). You can now proceed with the [[#mu-and-mu4e][mu and mu4e]] section. +*** Faster syncing +It's possible to use IMAP IDLE to be quickly notified of updates, then use a +tailored =mbsync= command to just fetch the new changes. + +If this is of interest, this approach can be seen [[https://tecosaur.github.io/emacs-config/config.html#fetching][in @tecosaur's config]] where +[[https://gitlab.com/shackra/goimapnotify][goimapnotify]] is used for this. + ** mu and mu4e You should have your email downloaded already. If you have not, you need to set =offlineimap= or =mbsync= up before you proceed. From 176252dea0efa0fc3a7ef6af0885363e10de1e8a Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 00:23:17 +0800 Subject: [PATCH 041/119] Mu4e: Readme, improve features/config content --- modules/email/mu4e/README.org | 46 +++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 8d3698dbe..fd72a97df 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -19,6 +19,7 @@ - [[#mbsync][mbsync]] - [[#mu-and-mu4e][mu and mu4e]] - [[#orgmsg][OrgMsg]] + - [[#mu4e-alert][mu4e-alert]] - [[#troubleshooting][Troubleshooting]] - [[#no-such-file-or-directory-mu4e][=No such file or directory, mu4e=]] - [[#void-function-org-time-add-error-on-gentoo][~(void-function org-time-add)~ error on Gentoo]] @@ -43,12 +44,6 @@ via IMAP) and ~mu~ (to index my mail into a format ~mu4e~ can understand). + [[https://github.com/jeremy-compostella/org-msg][org-msg]] + [[https://github.com/iqbalansari/mu4e-alert][mu4e-alert]] -To disable either of these packages, simply add -#+begin_src emacs-lisp -(package! X :disable t) -#+end_src -to your [[elisp:(find-file (expand-file-name (concat "config." (if (featurep! :config literate) "org" "el")) doom-private-dir))][config]] (where =X= is the package in question) and it will not be used. - * Prerequisites This module requires: @@ -118,17 +113,9 @@ sudo apt-get install maildir-utils mu4e # mu and mu4e respectivly + Prettified =mu4e:main= view + Cooperative locking of the =mu= process. Another Emacs instance may request access, or grab the lock when it's available. -+ =org-msg= integration - - can be toggled per-message by applying the - universal argument (=SPC u=) to the compose/reply/forward action. - - The initial value of ~+mu4e-compose-org-msg-toggle-next~ determines the default - composition mode (this can be toggled with =M-x org-msg-mode= as usual). - - A revamped custom style, with an accent colour that can be customised by - setting ~+org-msg-accent-color~) -+ Gmail integrations with the =+gmail= flag, which account for the different behaviour. - This is applied when using addresses which contain =@gmail.com= or have =gmail= in - the maildir name. You can use ~+mu4e-gmail-addresses~ when you want an address - to be treated as such but it meets neither conditions (e.g. with Gsuite). ++ =org-msg= integration, which can be toggled per-message, with revamped style and + an accent colour ++ Gmail integrations with the =+gmail= flag + Email notifications with =mu4e-alert=, and (on Linux) a customised notification style * Configuration @@ -173,7 +160,7 @@ If this is of interest, this approach can be seen [[https://tecosaur.github.io/e You should have your email downloaded already. If you have not, you need to set =offlineimap= or =mbsync= up before you proceed. -Before you can use =mu4e= or the cli program =mu=, you need to index your email +Before you can use =mu4e= or the CLI program =mu=, you need to index your email initially. How to do that differs a little depending on the version of =mu= you use. You can check your version with ~mu --version~. @@ -202,6 +189,16 @@ Then configure Emacs to use your email address: (mu4e-compose-signature . "---\nHenrik Lissner")) t) #+END_SRC + +*** Gmail +With the =+gmail= flag, integrations are applied which account for the different +behaviour of Gmail. + +The integrations are applied when using addresses which contain =@gmail.com= or +have =gmail= in the maildir name. You can use ~+mu4e-gmail-addresses~ when you want +an address to be treated as such but it meets neither conditions (e.g. with +Gsuite). + ** OrgMsg By default, ~org-msg-mode~ is enabled before composing the first message. To disable ~org-msg-mode~ by default, simply @@ -212,6 +209,19 @@ To disable ~org-msg-mode~ by default, simply To toggle org-msg for a single message, just apply the universal argument to the compose or reply command (=SPC u= with ~evil~, =C-u= otherwise). +The accent colour that Doom uses can be customised by setting +~+org-msg-accent-color~ to a CSS colour string. + +*** Disabling +If you don't like OrgMsg, simply add +#+begin_src emacs-lisp +(package! org-msg :disable t) +#+end_src +to your [[elisp:(find-file (expand-file-name "packages.el" doom-private-dir))][packages.el]] and it will not be used. + +** mu4e-alert +This is used by default. It can be disabled in the same manner as [[*OrgMsg][OrgMsg.]] + * Troubleshooting ** =No such file or directory, mu4e= You will get =No such file or directory, mu4e= errors if you don't run ~doom From 1b9dce8fcdc2a0b2848a11b7ca6720c2104e1b69 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 01:22:53 +0800 Subject: [PATCH 042/119] Mu4e: Refactor install instructions into table --- modules/email/mu4e/README.org | 56 ++++++----------------------------- 1 file changed, 9 insertions(+), 47 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index fd72a97df..323634119 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -8,11 +8,7 @@ - [[#module-flags][Module Flags]] - [[#plugins][Plugins]] - [[#prerequisites][Prerequisites]] - - [[#macos][MacOS]] - - [[#arch-linux][Arch Linux]] - [[#nixos][NixOS]] - - [[#opensuse][openSUSE]] - - [[#debianubuntu][Debian/Ubuntu]] - [[#features][Features]] - [[#configuration][Configuration]] - [[#offlineimap][offlineimap]] @@ -50,29 +46,16 @@ This module requires: + Either ~mbsync~ (default) or ~offlineimap~ (to sync mail with) + ~mu~, to index your downloaded messages and to provide the ~mu4e~ package. -** MacOS -#+BEGIN_SRC sh -brew install mu -# And one of the following -brew install isync # mbsync -brew install offlineimap -#+END_SRC +#+name: Install Matrix +| Platform | Install command | Base packages | +|---------------+------------------------+---------------------| +| MacOS | ~brew install ~ | =mu= | +| Arch | ~pacman -S ~ | (AUR, ~yay -S~) =mu= | +| openSUSE | ~zypper install ~ | =maildir-utils=, =mu4e= | +| Fedora | ~dnf install ~ | =maildir-utils= | +| Debian/Ubuntu | ~apt-get install ~ | =maildir-utils=, =mu4e= | -** Arch Linux -Run one of the following commands. - -#+BEGIN_SRC sh -sudo pacman -S isync # mbsync -# OR -sudo pacman -S offlineimap -#+END_SRC - -Install ~mu~, which is not available in the main repositories but in the AUR, by -using for example the AUR helper ~yay~. - -#+BEGIN_SRC sh -yay -S mu -#+END_SRC +The install either the =isync= (=mbsync=) or =offlineimap= package. ** NixOS #+BEGIN_SRC nix @@ -86,27 +69,6 @@ environment.systemPackages = with pkgs; [ [[https://github.com/Emiller88/dotfiles/blob/5eaabedf1b141c80a8d32e1b496055231476f65e/modules/shell/mail.nix][An example of setting up mbsync and mu with home-manager]] -** openSUSE -Remove ~#~ in ~#sync_program=offlineimap~ to choose ~offlineimap~ instead of -~mbsync~. - -#+BEGIN_SRC sh :dir /sudo:: -sync_program=isync # mbsync -#sync_program=offlineimap - -sudo zypper install maildir-utils $sync_program -#+END_SRC - -** Debian/Ubuntu -Run the command corresponding to the desired backend and the last one. -#+BEGIN_SRC sh -sudo apt-get install isync # mbsync -# or -sudo apt-get install offlineimap -# then -sudo apt-get install maildir-utils mu4e # mu and mu4e respectivly -#+END_SRC - * Features + Tidied mu4e headers view, with flags from =all-the-icons= + Consistent colouring of reply depths (across compose and gnus modes) From 9673b66dc1a1c15df0af5b129d369619dee580fc Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 01:23:55 +0800 Subject: [PATCH 043/119] Mu4e: Use more robust xwidget support check This shouldn't be defined unless the C library is present. --- modules/email/mu4e/config.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 2a66b01b5..e763932ce 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -163,7 +163,7 @@ (when (fboundp 'imagemagick-register-types) (imagemagick-register-types)) - (when (fboundp 'xwidget-webkit-browse-url) + (when (fboundp 'make-xwidget) (push '("view with xwidgets" . mu4e-action-view-with-xwidget) mu4e-view-actions)) From e2792127f074a5ce1b0c87fda110f440dbcb4f58 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 01:32:22 +0800 Subject: [PATCH 044/119] Mu4e: correct reference to renamed variable --- modules/email/mu4e/autoload/email.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 61f400086..7042d1093 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -263,7 +263,7 @@ clicked." ;;;###autoload (defun +org-msg-img-scale-css (img-uri) "For a given IMG-URI, use imagemagik to find its width." - (if org-msg-currently-exporting + (if +org-msg-currently-exporting (list :width (format "%.1fpx" (/ (string-to-number From 75601101c6fd38fa1842d9fc373a66dbfa184feb Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 01:38:00 +0800 Subject: [PATCH 045/119] Mu4e: Don't require a context to compose emails --- modules/email/mu4e/autoload/email.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 7042d1093..850de09fa 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -209,7 +209,9 @@ with the current context." (if (member from (mu4e-personal-addresses)) (setq user-mail-address from) nil)))) - (ivy-read "From: " (if-let ((context-addresses (alist-get '+mu4e-personal-addresses (mu4e-context-vars mu4e~context-current)))) + (ivy-read "From: " (if-let ((context-addresses + (when mu4e~context-current + (alist-get '+mu4e-personal-addresses (mu4e-context-vars mu4e~context-current))))) context-addresses (mu4e-personal-addresses)) :action (lambda (candidate) (setq user-mail-address candidate))))) From 37b918d0d6e1a69d466de75b5af6c388a6db610a Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 01:57:14 +0800 Subject: [PATCH 046/119] Mu4e: Leave org-msg's salutation to the user --- modules/email/mu4e/config.el | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index e763932ce..83812c4e2 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -214,7 +214,6 @@ :config (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil tex:dvipng" org-msg-startup "hidestars indent inlineimages" - org-msg-greeting-fmt "\nHi %s,\n\n" org-msg-greeting-name-limit 3 org-msg-text-plain-alternative t) From 7dff598725989e269e806419557f83a9d360e125 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 13:01:46 +0800 Subject: [PATCH 047/119] Mu4e: Gate org-msg behind +org flag --- docs/modules.org | 2 +- init.example.el | 2 +- modules/email/mu4e/README.org | 11 +++++++---- modules/email/mu4e/config.el | 2 +- modules/email/mu4e/doctor.el | 2 +- modules/email/mu4e/packages.el | 2 +- 6 files changed, 12 insertions(+), 9 deletions(-) diff --git a/docs/modules.org b/docs/modules.org index 2187b1cb5..539f24be7 100644 --- a/docs/modules.org +++ b/docs/modules.org @@ -84,7 +84,7 @@ Modules that reconfigure or augment packages or features built into Emacs. + [[file:../modules/emacs/vc/README.org][vc]] - TODO * :email -+ [[file:../modules/email/mu4e/README.org][mu4e]] =+gmail= - TODO ++ [[file:../modules/email/mu4e/README.org][mu4e]] =+org +gmail= - TODO + [[file:../modules/email/notmuch/README.org][notmuch]] - TODO + wanderlust =+gmail= - TODO diff --git a/init.example.el b/init.example.el index b24c44cb6..457989e54 100644 --- a/init.example.el +++ b/init.example.el @@ -171,7 +171,7 @@ ;;zig ; C, but simpler :email - ;;(mu4e +gmail) + ;;(mu4e +org +gmail) ;;notmuch ;;(wanderlust +gmail) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 323634119..ed8134ae9 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -33,12 +33,15 @@ via IMAP) and ~mu~ (to index my mail into a format ~mu4e~ can understand). #+end_quote ** Module Flags -+ ~+gmail~ Enables gmail-specific configuration for mail ~To~ or ~From~ a gmail ++ =+gmail= Enables gmail-specific configuration for mail ~To~ or ~From~ a gmail address, or a maildir with ~gmail~ in the name. ++ =+org= Use =org-msg= for composing email in Org, then sending a multipart text + (ASCII export) and HTML message. ** Plugins -+ [[https://github.com/jeremy-compostella/org-msg][org-msg]] + [[https://github.com/iqbalansari/mu4e-alert][mu4e-alert]] ++ =+org= + + [[https://github.com/jeremy-compostella/org-msg][org-msg]] * Prerequisites This module requires: @@ -75,7 +78,7 @@ environment.systemPackages = with pkgs; [ + Prettified =mu4e:main= view + Cooperative locking of the =mu= process. Another Emacs instance may request access, or grab the lock when it's available. -+ =org-msg= integration, which can be toggled per-message, with revamped style and ++ =org-msg= integration with =+org=, which can be toggled per-message, with revamped style and an accent colour + Gmail integrations with the =+gmail= flag + Email notifications with =mu4e-alert=, and (on Linux) a customised notification style @@ -102,7 +105,7 @@ You can now proceed with the [[#mu-and-mu4e][mu and mu4e]] section. The steps needed to set up =mu4e= with =mbsync= are very similar to the ones for [[#offlineimap][offlineimap]]. -Start with writing a ~\~/.mbsyncrc~. An example for Gmail can be found on +Start with writing a ~~/.mbsyncrc~. An example for Gmail can be found on [[http://pragmaticemacs.com/emacs/migrating-from-offlineimap-to-mbsync-for-mu4e/][pragmaticemacs.com]]. A non-Gmail example is available as a gist [[https://gist.github.com/agraul/60977cc497c3aec44e10591f94f49ef0][here]]. The [[http://isync.sourceforge.net/mbsync.html][manual page]] contains all needed information to set up your own. diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 83812c4e2..a6135cf33 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -210,7 +210,7 @@ (use-package! org-msg :after mu4e - :when (featurep! :lang org) + :when (featurep! +org) :config (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil tex:dvipng" org-msg-startup "hidestars indent inlineimages" diff --git a/modules/email/mu4e/doctor.el b/modules/email/mu4e/doctor.el index 81e0e55ba..3355e6021 100644 --- a/modules/email/mu4e/doctor.el +++ b/modules/email/mu4e/doctor.el @@ -8,7 +8,7 @@ (wan! "Couldn't find mbsync or offlineimap command. \ You may not have a way of fetching mail.")) -(when (and (featurep! :lang org) +(when (and (featurep! +org) (not IS-WINDOWS)) (unless (executable-find "identify") (warn! "Couldn't find the identify command from imagemagik. \ diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index 808b419d9..3a448797e 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -1,7 +1,7 @@ ;; -*- no-byte-compile: t; -*- ;;; email/mu4e/packages.el -(when (featurep! :lang org) +(when (featurep! +org) (package! org-msg :pin "2db6725c4a4f4342a9c61895b7c3c82795b01fee")) (package! mu4e-alert :pin "91f0657c5b245a9de57aa38391221fb5d141d9bd") From 2a2f8bfbac9dc0121148b63140f7e48380d6493f Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 14:05:50 +0800 Subject: [PATCH 048/119] Mu4e: correct misspelling --- modules/email/mu4e/autoload/email.el | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 850de09fa..3b83c772e 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -379,8 +379,8 @@ scales the image to account for the value of :scale in `org-format-latex-options (delete-file +mu4e-lock-file) nil)))) ;;;###autoload -(defun +mu4e-lock-avalible (&optional strict) - "If the `+mu4e-lock-file' is avalible (unset or owned by this emacs) return t. +(defun +mu4e-lock-available (&optional strict) + "If the `+mu4e-lock-file' is available (unset or owned by this emacs) return t. If STRICT only accept an unset lock file." (not (when-let* ((lock-info (+mu4e-lock-pid-info)) (pid (car lock-info))) @@ -389,7 +389,7 @@ If STRICT only accept an unset lock file." ;;;###autoload (defun +mu4e-lock-file-delete-maybe () "Check `+mu4e-lock-file', and delete it if this process is responsible for it." - (when (+mu4e-lock-avalible) + (when (+mu4e-lock-available) (delete-file +mu4e-lock-file) (file-notify-rm-watch +mu4e-lock--request-watcher))) @@ -397,12 +397,12 @@ If STRICT only accept an unset lock file." (defun +mu4e-lock-start (orig-fun &optional callback) "Check `+mu4e-lock-file', and if another process is responsible for it, abort starting. Else, write to this process' PID to the lock file" - (unless (+mu4e-lock-avalible) + (unless (+mu4e-lock-available) (shell-command (format "touch %s" +mu4e-lock-request-file)) (message "Lock file exists, requesting that it be given up") (sleep-for 0.1) (delete-file +mu4e-lock-request-file)) - (if (not (+mu4e-lock-avalible)) + (if (not (+mu4e-lock-available)) (user-error "Unfortunately another Emacs is already doing stuff with Mu4e, and you can only have one at a time") (f-write-text (number-to-string (emacs-pid)) 'utf-8 +mu4e-lock-file) (delete-file +mu4e-lock-request-file) @@ -443,6 +443,6 @@ Else, write to this process' PID to the lock file" (+mu4e-lock-add-watcher) (when (equal (nth 1 event) 'deleted) (setq +mu4e-lock--file-just-deleted t) - (when (and +mu4e-lock-greedy (+mu4e-lock-avalible t)) - (message "Noticed Mu4e lock was avalible, grabbed it") + (when (and +mu4e-lock-greedy (+mu4e-lock-available t)) + (message "Noticed Mu4e lock was available, grabbed it") (run-at-time 0.2 nil #'mu4e~start))))) From a75bace4986cec2b07d1332fe71274ba48cc4815 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 14:06:15 +0800 Subject: [PATCH 049/119] Mu4e: Remove duplicate + in function name --- modules/email/mu4e/autoload/email.el | 4 ++-- modules/email/mu4e/config.el | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 3b83c772e..082caf474 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -423,7 +423,7 @@ Else, write to this process' PID to the lock file" (setq +mu4e-lock--file-watcher (file-notify-add-watch +mu4e-lock-file '(change) - #'++mu4e-lock-file-updated))) + #'+mu4e-lock-file-updated))) ;;;###autoload (defun +mu4e-lock-request (event) @@ -438,7 +438,7 @@ Else, write to this process' PID to the lock file" (delete-file +mu4e-lock-request-file))) ;;;###autoload -(defun ++mu4e-lock-file-updated (event) +(defun +mu4e-lock-file-updated (event) (if +mu4e-lock--file-just-deleted (+mu4e-lock-add-watcher) (when (equal (nth 1 event) 'deleted) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index a6135cf33..68a596be2 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -96,12 +96,12 @@ (defun +mu4e-header-colourise (str) (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) - (colour (nth (% str-sum (length ++mu4e-header-colourised-faces)) - ++mu4e-header-colourised-faces))) + (colour (nth (% str-sum (length +mu4e-header-colourised-faces)) + +mu4e-header-colourised-faces))) (put-text-property 0 (length str) 'face colour str) str)) - (defvar ++mu4e-header-colourised-faces + (defvar +mu4e-header-colourised-faces '(all-the-icons-lblue all-the-icons-purple all-the-icons-blue-alt From 358ff84c5473aaba3f193bae6acfa344b137c7a9 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 14:10:22 +0800 Subject: [PATCH 050/119] Mu4e: Factor out f dependency --- modules/email/mu4e/autoload/email.el | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 082caf474..18c8a2983 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -373,7 +373,11 @@ scales the image to account for the value of :scale in `org-format-latex-options "Get info on the PID refered to in `+mu4e-lock-file' in the form (pid . process-attributes) If the file or process do not exist, the lock file is deleted an nil returned." (when (file-exists-p +mu4e-lock-file) - (let* ((pid (string-to-number (f-read-text +mu4e-lock-file 'utf-8))) + (let* ((pid (string-to-number + (with-temp-buffer + (setq coding-system-for-read 'utf-8) + (insert-file-contents +mu4e-lock-file) + (buffer-string)))) (process (process-attributes pid))) (if process (cons pid process) (delete-file +mu4e-lock-file) nil)))) @@ -404,7 +408,7 @@ Else, write to this process' PID to the lock file" (delete-file +mu4e-lock-request-file)) (if (not (+mu4e-lock-available)) (user-error "Unfortunately another Emacs is already doing stuff with Mu4e, and you can only have one at a time") - (f-write-text (number-to-string (emacs-pid)) 'utf-8 +mu4e-lock-file) + (write-region (number-to-string (emacs-pid)) nil +mu4e-lock-file) (delete-file +mu4e-lock-request-file) (funcall orig-fun callback) (setq +mu4e-lock--request-watcher From 8e0001f6fdfc64a499af6be5ae2fcc8950f8175d Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 14:13:04 +0800 Subject: [PATCH 051/119] Mu4e: Generalise ivy-read to completing-read --- modules/email/mu4e/autoload/email.el | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 18c8a2983..810ca0e8f 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -209,12 +209,14 @@ with the current context." (if (member from (mu4e-personal-addresses)) (setq user-mail-address from) nil)))) - (ivy-read "From: " (if-let ((context-addresses - (when mu4e~context-current - (alist-get '+mu4e-personal-addresses (mu4e-context-vars mu4e~context-current))))) - context-addresses - (mu4e-personal-addresses)) - :action (lambda (candidate) (setq user-mail-address candidate))))) + (setq user-mail-address + (completing-read + "From: " + (if-let ((context-addresses + (when mu4e~context-current + (alist-get '+mu4e-personal-addresses (mu4e-context-vars mu4e~context-current))))) + context-addresses + (mu4e-personal-addresses)))))) ;;;###autoload (defun +mu4e~main-action-str-prettier (str &optional func-or-shortcut) From b1f7e9b9f933367bfa685428fd1d331392360519 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 14:15:24 +0800 Subject: [PATCH 052/119] Mu4e: follow function naming conventions Rename +mu4e-msg-to-agenda and +get-string-width --- modules/email/mu4e/autoload/email.el | 8 ++++---- modules/email/mu4e/config.el | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 810ca0e8f..4a24f6b7e 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -81,7 +81,7 @@ default/fallback account." ;; Icons need a bit of work ;; Spacing needs to be determined and adjucted ;;;###autoload -(defun +get-string-width (str) +(defun +mu4e--get-string-width (str) "Return the width in pixels of a string in the current window's default font. If the font is mono-spaced, this will also be the width of all other printable characters." @@ -103,8 +103,8 @@ will also be the width of all other printable characters." (icon (if colour (apply icon-set `(,name :face ,(intern (concat "all-the-icons-" colour)) :height ,height :v-adjust ,v-adjust)) (apply icon-set `(,name :height ,height :v-adjust ,v-adjust)))) - (icon-width (+get-string-width icon)) - (space-width (+get-string-width " ")) + (icon-width (+mu4e--get-string-width icon)) + (space-width (+mu4e--get-string-width " ")) (space-factor (- 2 (/ (float icon-width) space-width)))) (concat (propertize " " 'display `(space . (:width ,space-factor))) icon))) @@ -136,7 +136,7 @@ will also be the width of all other printable characters." ;; Perfect for when you see an email you want to reply to ;; later, but don't want to forget about ;;;###autoload -(defun +mu4e-msg-to-agenda (arg) +(defun +mu4e/refile-msg-to-agenda (arg) "Refile a message and add a entry in the agenda file with a deadline. Default deadline is today. With one prefix, deadline is tomorrow. With two prefixes, select the deadline." diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 68a596be2..149582b6a 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -171,7 +171,7 @@ :ne "h" #'+workspace/other) (map! :map mu4e-headers-mode-map - :e "l" #'+mu4e-msg-to-agenda) + :vne "l" #'mu4e/refile-msg-to-agenda) (map! :localleader :map mu4e-compose-mode-map @@ -188,8 +188,7 @@ :v "*" #'mu4e-headers-mark-for-something :v "!" #'mu4e-headers-mark-for-read :v "?" #'mu4e-headers-mark-for-unread - :v "u" #'mu4e-headers-mark-for-unmark - :vn "l" #'+mu4e-msg-to-agenda)) + :v "u" #'mu4e-headers-mark-for-unmark)) (add-hook 'mu4e-compose-pre-hook '+mu4e-set-from-address) From 92cfdd6f7f3a13aa6c0f8b30b05994a95a8e885d Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 14:17:35 +0800 Subject: [PATCH 053/119] Mu4e: Change colourise to (sigh) american spelling --- modules/email/mu4e/autoload/email.el | 6 +++--- modules/email/mu4e/config.el | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 4a24f6b7e..d2aceef9f 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -125,10 +125,10 @@ will also be the width of all other printable characters." mu4e-headers-unread-mark (cons "u" (+mu4e-normalised-icon "eye-slash" :v-adjust 0.05)))) ;;;###autoload -(defun +mu4e-header-colourise (str) +(defun +mu4e-header-colorize (str) (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) - (colour (nth (% str-sum (length mu4e-header-colourised-faces)) - mu4e-header-colourised-faces))) + (colour (nth (% str-sum (length mu4e-header-colorized-faces)) + mu4e-header-colorized-faces))) (put-text-property 0 (length str) 'face colour str) str)) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 149582b6a..df269d9fc 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -94,14 +94,14 @@ (add-to-list 'mu4e-bookmarks '(:name "Flagged messages" :query "flag:flagged" :key ?f) t) - (defun +mu4e-header-colourise (str) + (defun +mu4e-header-colorize (str) (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) - (colour (nth (% str-sum (length +mu4e-header-colourised-faces)) - +mu4e-header-colourised-faces))) + (colour (nth (% str-sum (length +mu4e-header-colorized-faces)) + +mu4e-header-colorized-faces))) (put-text-property 0 (length str) 'face colour str) str)) - (defvar +mu4e-header-colourised-faces + (defvar +mu4e-header-colorized-faces '(all-the-icons-lblue all-the-icons-purple all-the-icons-blue-alt @@ -120,7 +120,7 @@ (lambda (msg) (let ((maildir (mu4e-message-field msg :maildir))) - (+mu4e-header-colourise + (+mu4e-header-colorize (replace-regexp-in-string "^gmail" (propertize "g" 'face 'bold-italic) From f7f58745c36872e7c6579e08799143175f11541e Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 15:00:57 +0800 Subject: [PATCH 054/119] Mu4e: Correct windows mu lock file paths --- modules/email/mu4e/config.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index df269d9fc..6b45af9e1 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -199,9 +199,9 @@ ;; process lock control (when IS-WINDOWS - (setq ;; REVIEW untested - +mu4e-lock-file (expand-file-name "%userprofile%\\AppData\\Local\\Temp\\mu4e_lock") - +mu4e-lock-request-file (expand-file-name "%userprofile%\\AppData\\Local\\Temp\\mu4e_lock_request"))) + (setq + +mu4e-lock-file (expand-file-name "~/AppData/Local/Temp/mu4e_lock") + +mu4e-lock-request-file (expand-file-name "~/AppData/Local/Temp/mu4e_lock_request"))) (add-hook 'kill-emacs-hook #'+mu4e-lock-file-delete-maybe) (advice-add 'mu4e~start :around #'+mu4e-lock-start) From b983b8ec338740c95c6e50073c1bef9c05686d98 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 15:37:15 +0800 Subject: [PATCH 055/119] Mu4e: Refile autoload functions semantically With a dash of renaming --- modules/email/mu4e/autoload/advice.el | 123 ++++++++++++ modules/email/mu4e/autoload/email.el | 256 ++----------------------- modules/email/mu4e/autoload/mu-lock.el | 94 +++++++++ modules/email/mu4e/config.el | 8 +- 4 files changed, 239 insertions(+), 242 deletions(-) create mode 100644 modules/email/mu4e/autoload/advice.el create mode 100644 modules/email/mu4e/autoload/mu-lock.el diff --git a/modules/email/mu4e/autoload/advice.el b/modules/email/mu4e/autoload/advice.el new file mode 100644 index 000000000..9e29527f6 --- /dev/null +++ b/modules/email/mu4e/autoload/advice.el @@ -0,0 +1,123 @@ +;;; email/mu4e/autoload/advice.el -*- lexical-binding: t; -*- + +;;;###autoload +(defun +mu4e~main-action-str-prettier-a (str &optional func-or-shortcut) + "Highlight the first occurrence of [.] in STR. +If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it +when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is +a string, execute the corresponding keyboard action when it is +clicked." + (let ((newstr + (replace-regexp-in-string + "\\[\\(..?\\)\\]" + (lambda(m) + (format "%s" + (propertize (match-string 1 m) 'face '(mode-line-emphasis bold)))) + (replace-regexp-in-string "\t\\*" "\t⚫" str))) + (map (make-sparse-keymap)) + (func (if (functionp func-or-shortcut) + func-or-shortcut + (if (stringp func-or-shortcut) + (lambda()(interactive) + (execute-kbd-macro func-or-shortcut)))))) + (define-key map [mouse-2] func) + (define-key map (kbd "RET") func) + (put-text-property 0 (length newstr) 'keymap map newstr) + (put-text-property (string-match "[A-Za-z].+$" newstr) + (- (length newstr) 1) 'mouse-face 'highlight newstr) + newstr)) + +;; Org msg LaTeX image scaling + +;;;###autoload +(defun +org-msg-img-scale-css (img-uri) + "For a given IMG-URI, use imagemagik to find its width." + (if +org-msg-currently-exporting + (list :width + (format "%.1fpx" + (/ (string-to-number + (shell-command-to-string + ;; TODO change to use 'file' + (format "identify -format %%w %s" + (substring img-uri 7)))) ; 7=(length "file://") + (plist-get org-format-latex-options :scale)))) + (list :style (format "transform: scale(%.3f)" + (/ 1.0 (plist-get org-format-latex-options :scale)))))) + +;;;###autoload +(defun +org-html-latex-fragment-scaled-a (latex-fragment _contents info) + "Transcode a LATEX-FRAGMENT object from Org to HTML. +CONTENTS is nil. INFO is a plist holding contextual information. + +This differs from `org-html-latex-fragment' in that it uses the LaTeX fragment +as a meaningful alt value, applies a class to indicate what sort of fragment it is +(latex-fragment-inline or latex-fragment-block), and (on Linux) scales the image to +account for the value of :scale in `org-format-latex-options'." + (let ((latex-frag (org-element-property :value latex-fragment)) + (processing-type (plist-get info :with-latex))) + (cond + ((memq processing-type '(t mathjax)) + (org-html-format-latex latex-frag 'mathjax info)) + ((memq processing-type '(t html)) + (org-html-format-latex latex-frag 'html info)) + ((assq processing-type org-preview-latex-process-alist) + (let ((formula-link + (org-html-format-latex latex-frag processing-type info))) + (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) + (let ((source (org-export-file-uri (match-string 1 formula-link))) + (attributes (list :alt latex-frag + :class (concat "latex-fragment-" + (if (equal "\\(" (substring latex-frag 0 2)) + "inline" "block"))))) + (when (and (memq processing-type '(dvipng convert)) + (not IS-WINDOWS) ; relies on posix path + (executable-find "identify")) + (apply #'plist-put attributes (+org-msg-img-scale-css source))) + (org-html--format-image source attributes info))))) + (t latex-frag)))) + +;;;###autoload +(defun +org-html-latex-environment-scaled-a (latex-environment _contents info) + "Transcode a LATEX-ENVIRONMENT element from Org to HTML. +CONTENTS is nil. INFO is a plist holding contextual information. + +This differs from `org-html-latex-environment' in that (on Linux) it +scales the image to account for the value of :scale in `org-format-latex-options'." + (let ((processing-type (plist-get info :with-latex)) + (latex-frag (org-remove-indentation + (org-element-property :value latex-environment))) + (attributes (org-export-read-attribute :attr_html latex-environment)) + (label (and (org-element-property :name latex-environment) + (org-export-get-reference latex-environment info))) + (caption (and (org-html--latex-environment-numbered-p latex-environment) + (number-to-string + (org-export-get-ordinal + latex-environment info nil + (lambda (l _) + (and (org-html--math-environment-p l) + (org-html--latex-environment-numbered-p l)))))))) + (plist-put attributes :class "latex-environment") + (cond + ((memq processing-type '(t mathjax)) + (org-html-format-latex + (if (org-string-nw-p label) + (replace-regexp-in-string "\\`.*" + (format "\\&\n\\\\label{%s}" label) + latex-frag) + latex-frag) + 'mathjax info)) + ((assq processing-type org-preview-latex-process-alist) + (let ((formula-link + (org-html-format-latex + (org-html--unlabel-latex-environment latex-frag) + processing-type info))) + (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) + (let ((source (org-export-file-uri (match-string 1 formula-link)))) + (when (and (memq processing-type '(dvipng convert)) + (not IS-WINDOWS) ; relies on posix path + (executable-find "identify")) + (apply #'plist-put attributes (+org-msg-img-scale-css source))) + (org-html--wrap-latex-environment + (org-html--format-image source attributes info) + info caption label))))) + (t (org-html--wrap-latex-environment latex-frag info caption label))))) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index d2aceef9f..ffed628e0 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -43,9 +43,8 @@ default/fallback account." context))) - (defvar +mu4e-workspace-name "*mu4e*" - "TODO") + "Name of the workspace created by `=mu4e', dedicated to mu4e.") (defvar +mu4e--old-wconf nil) (add-hook 'mu4e-main-mode-hook #'+mu4e-init-h) @@ -194,8 +193,24 @@ is tomorrow. With two prefixes, select the deadline." ((= arg 4) "tomorrow") (t "later")))))) +;; +;; Hooks + +(defun +mu4e-init-h () + (add-hook 'kill-buffer-hook #'+mu4e-kill-mu4e-h nil t)) + +(defun +mu4e-kill-mu4e-h () + ;; (prolusion-mail-hide) + (cond + ((and (featurep! :ui workspaces) (+workspace-exists-p +mu4e-workspace-name)) + (+workspace/delete +mu4e-workspace-name)) + + (+mu4e--old-wconf + (set-window-configuration +mu4e--old-wconf) + (setq +mu4e--old-wconf nil)))) + ;;;###autoload -(defun +mu4e-set-from-address () +(defun +mu4e-set-from-address-h () "Set the account for composing a message. If a 'To' header is present, and correspands to an email address, this address will be selected. Otherwise, the user is prompted for the address they wish to use. Possible @@ -217,238 +232,3 @@ with the current context." (alist-get '+mu4e-personal-addresses (mu4e-context-vars mu4e~context-current))))) context-addresses (mu4e-personal-addresses)))))) - -;;;###autoload -(defun +mu4e~main-action-str-prettier (str &optional func-or-shortcut) - "Highlight the first occurrence of [.] in STR. -If FUNC-OR-SHORTCUT is non-nil and if it is a function, call it -when STR is clicked (using RET or mouse-2); if FUNC-OR-SHORTCUT is -a string, execute the corresponding keyboard action when it is -clicked." - :override #'mu4e~main-action-str - (let ((newstr - (replace-regexp-in-string - "\\[\\(..?\\)\\]" - (lambda(m) - (format "%s" - (propertize (match-string 1 m) 'face '(mode-line-emphasis bold)))) - (replace-regexp-in-string "\t\\*" "\t⚫" str))) - (map (make-sparse-keymap)) - (func (if (functionp func-or-shortcut) - func-or-shortcut - (if (stringp func-or-shortcut) - (lambda()(interactive) - (execute-kbd-macro func-or-shortcut)))))) - (define-key map [mouse-2] func) - (define-key map (kbd "RET") func) - (put-text-property 0 (length newstr) 'keymap map newstr) - (put-text-property (string-match "[A-Za-z].+$" newstr) - (- (length newstr) 1) 'mouse-face 'highlight newstr) - newstr)) - -;; -;; Hooks - -(defun +mu4e-init-h () - (add-hook 'kill-buffer-hook #'+mu4e-kill-mu4e-h nil t)) - -(defun +mu4e-kill-mu4e-h () - ;; (prolusion-mail-hide) - (cond - ((and (featurep! :ui workspaces) (+workspace-exists-p +mu4e-workspace-name)) - (+workspace/delete +mu4e-workspace-name)) - - (+mu4e--old-wconf - (set-window-configuration +mu4e--old-wconf) - (setq +mu4e--old-wconf nil)))) - -;; org-msg hooks - -;;;###autoload -(defun +org-msg-img-scale-css (img-uri) - "For a given IMG-URI, use imagemagik to find its width." - (if +org-msg-currently-exporting - (list :width - (format "%.1fpx" - (/ (string-to-number - (shell-command-to-string - ;; TODO change to use 'file' - (format "identify -format %%w %s" - (substring img-uri 7)))) ; 7=(length "file://") - (plist-get org-format-latex-options :scale)))) - (list :style (format "transform: scale(%.3f)" - (/ 1.0 (plist-get org-format-latex-options :scale)))))) - -;;;###autoload -(defun +org-html-latex-fragment-scaled (latex-fragment _contents info) - "Transcode a LATEX-FRAGMENT object from Org to HTML. -CONTENTS is nil. INFO is a plist holding contextual information. - -This differs from `org-html-latex-fragment' in that it uses the LaTeX fragment -as a meaningful alt value, applies a class to indicate what sort of fragment it is -(latex-fragment-inline or latex-fragment-block), and (on Linux) scales the image to -account for the value of :scale in `org-format-latex-options'." - (let ((latex-frag (org-element-property :value latex-fragment)) - (processing-type (plist-get info :with-latex))) - (cond - ((memq processing-type '(t mathjax)) - (org-html-format-latex latex-frag 'mathjax info)) - ((memq processing-type '(t html)) - (org-html-format-latex latex-frag 'html info)) - ((assq processing-type org-preview-latex-process-alist) - (let ((formula-link - (org-html-format-latex latex-frag processing-type info))) - (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) - (let ((source (org-export-file-uri (match-string 1 formula-link))) - (attributes (list :alt latex-frag - :class (concat "latex-fragment-" - (if (equal "\\(" (substring latex-frag 0 2)) - "inline" "block"))))) - (when (and (memq processing-type '(dvipng convert)) - (not IS-WINDOWS) ; relies on posix path - (executable-find "identify")) - (apply #'plist-put attributes (+org-msg-img-scale-css source))) - (org-html--format-image source attributes info))))) - (t latex-frag)))) - -;;;###autoload -(defun +org-html-latex-environment-scaled (latex-environment _contents info) - "Transcode a LATEX-ENVIRONMENT element from Org to HTML. -CONTENTS is nil. INFO is a plist holding contextual information. - -This differs from `org-html-latex-environment' in that (on Linux) it -scales the image to account for the value of :scale in `org-format-latex-options'." - (let ((processing-type (plist-get info :with-latex)) - (latex-frag (org-remove-indentation - (org-element-property :value latex-environment))) - (attributes (org-export-read-attribute :attr_html latex-environment)) - (label (and (org-element-property :name latex-environment) - (org-export-get-reference latex-environment info))) - (caption (and (org-html--latex-environment-numbered-p latex-environment) - (number-to-string - (org-export-get-ordinal - latex-environment info nil - (lambda (l _) - (and (org-html--math-environment-p l) - (org-html--latex-environment-numbered-p l)))))))) - (plist-put attributes :class "latex-environment") - (cond - ((memq processing-type '(t mathjax)) - (org-html-format-latex - (if (org-string-nw-p label) - (replace-regexp-in-string "\\`.*" - (format "\\&\n\\\\label{%s}" label) - latex-frag) - latex-frag) - 'mathjax info)) - ((assq processing-type org-preview-latex-process-alist) - (let ((formula-link - (org-html-format-latex - (org-html--unlabel-latex-environment latex-frag) - processing-type info))) - (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) - (let ((source (org-export-file-uri (match-string 1 formula-link)))) - (when (and (memq processing-type '(dvipng convert)) - (not IS-WINDOWS) ; relies on posix path - (executable-find "identify")) - (apply #'plist-put attributes (+org-msg-img-scale-css source))) - (org-html--wrap-latex-environment - (org-html--format-image source attributes info) - info caption label))))) - (t (org-html--wrap-latex-environment latex-frag info caption label))))) - -;; -;; Cooperative locking - -(defvar +mu4e-lock-file "/tmp/mu4e_lock" - "Location of the lock file which stores the PID of the process currenty running mu4e") -(defvar +mu4e-lock-request-file "/tmp/mu4e_lock_request" - "Location of the lock file for which creating indicated that another process wants the lock to be released") - -(defvar +mu4e-lock-greedy nil - "Whether to 'grab' the `+mu4e-lock-file' if nobody else has it, i.e. start Mu4e") -(defvar +mu4e-lock-relaxed t - "Whether if someone else wants the lock (signaled via `+mu4e-lock-request-file'), we should stop Mu4e and let go of it") - -;;;###autoload -(defun +mu4e-lock-pid-info () - "Get info on the PID refered to in `+mu4e-lock-file' in the form (pid . process-attributes) - If the file or process do not exist, the lock file is deleted an nil returned." - (when (file-exists-p +mu4e-lock-file) - (let* ((pid (string-to-number - (with-temp-buffer - (setq coding-system-for-read 'utf-8) - (insert-file-contents +mu4e-lock-file) - (buffer-string)))) - (process (process-attributes pid))) - (if process (cons pid process) - (delete-file +mu4e-lock-file) nil)))) - -;;;###autoload -(defun +mu4e-lock-available (&optional strict) - "If the `+mu4e-lock-file' is available (unset or owned by this emacs) return t. -If STRICT only accept an unset lock file." - (not (when-let* ((lock-info (+mu4e-lock-pid-info)) - (pid (car lock-info))) - (when (or strict (/= (emacs-pid) pid)) t)))) - -;;;###autoload -(defun +mu4e-lock-file-delete-maybe () - "Check `+mu4e-lock-file', and delete it if this process is responsible for it." - (when (+mu4e-lock-available) - (delete-file +mu4e-lock-file) - (file-notify-rm-watch +mu4e-lock--request-watcher))) - -;;;###autoload -(defun +mu4e-lock-start (orig-fun &optional callback) - "Check `+mu4e-lock-file', and if another process is responsible for it, abort starting. -Else, write to this process' PID to the lock file" - (unless (+mu4e-lock-available) - (shell-command (format "touch %s" +mu4e-lock-request-file)) - (message "Lock file exists, requesting that it be given up") - (sleep-for 0.1) - (delete-file +mu4e-lock-request-file)) - (if (not (+mu4e-lock-available)) - (user-error "Unfortunately another Emacs is already doing stuff with Mu4e, and you can only have one at a time") - (write-region (number-to-string (emacs-pid)) nil +mu4e-lock-file) - (delete-file +mu4e-lock-request-file) - (funcall orig-fun callback) - (setq +mu4e-lock--request-watcher - (file-notify-add-watch +mu4e-lock-request-file - '(change) - #'+mu4e-lock-request)))) - -(defvar +mu4e-lock--file-watcher nil) -(defvar +mu4e-lock--file-just-deleted nil) -(defvar +mu4e-lock--request-watcher nil) - -;;;###autoload -(defun +mu4e-lock-add-watcher () - (setq +mu4e-lock--file-just-deleted nil) - (file-notify-rm-watch +mu4e-lock--file-watcher) - (setq +mu4e-lock--file-watcher - (file-notify-add-watch +mu4e-lock-file - '(change) - #'+mu4e-lock-file-updated))) - -;;;###autoload -(defun +mu4e-lock-request (event) - "Handle another process requesting the Mu4e lock." - (when (equal (nth 1 event) 'created) - (when +mu4e-lock-relaxed - (mu4e~stop) - (file-notify-rm-watch +mu4e-lock--file-watcher) - (message "Someone else wants to use Mu4e, releasing lock") - (delete-file +mu4e-lock-file) - (run-at-time 0.2 nil #'+mu4e-lock-add-watcher)) - (delete-file +mu4e-lock-request-file))) - -;;;###autoload -(defun +mu4e-lock-file-updated (event) - (if +mu4e-lock--file-just-deleted - (+mu4e-lock-add-watcher) - (when (equal (nth 1 event) 'deleted) - (setq +mu4e-lock--file-just-deleted t) - (when (and +mu4e-lock-greedy (+mu4e-lock-available t)) - (message "Noticed Mu4e lock was available, grabbed it") - (run-at-time 0.2 nil #'mu4e~start))))) diff --git a/modules/email/mu4e/autoload/mu-lock.el b/modules/email/mu4e/autoload/mu-lock.el new file mode 100644 index 000000000..845844757 --- /dev/null +++ b/modules/email/mu4e/autoload/mu-lock.el @@ -0,0 +1,94 @@ +;;; email/mu4e/autoload/mu-lock.el -*- lexical-binding: t; -*- + +(defvar +mu4e-lock-file "/tmp/mu4e_lock" + "Location of the lock file which stores the PID of the process currenty running mu4e") +(defvar +mu4e-lock-request-file "/tmp/mu4e_lock_request" + "Location of the lock file for which creating indicated that another process wants the lock to be released") + +(defvar +mu4e-lock-greedy nil + "Whether to 'grab' the `+mu4e-lock-file' if nobody else has it, i.e. start Mu4e") +(defvar +mu4e-lock-relaxed t + "Whether if someone else wants the lock (signaled via `+mu4e-lock-request-file'), we should stop Mu4e and let go of it") + +;;;###autoload +(defun +mu4e-lock-pid-info () + "Get info on the PID refered to in `+mu4e-lock-file' in the form (pid . process-attributes) + If the file or process do not exist, the lock file is deleted an nil returned." + (when (file-exists-p +mu4e-lock-file) + (let* ((pid (string-to-number + (with-temp-buffer + (setq coding-system-for-read 'utf-8) + (insert-file-contents +mu4e-lock-file) + (buffer-string)))) + (process (process-attributes pid))) + (if process (cons pid process) + (delete-file +mu4e-lock-file) nil)))) + +;;;###autoload +(defun +mu4e-lock-available (&optional strict) + "If the `+mu4e-lock-file' is available (unset or owned by this emacs) return t. +If STRICT only accept an unset lock file." + (not (when-let* ((lock-info (+mu4e-lock-pid-info)) + (pid (car lock-info))) + (when (or strict (/= (emacs-pid) pid)) t)))) + +;;;###autoload +(defun +mu4e-lock-file-delete-maybe () + "Check `+mu4e-lock-file', and delete it if this process is responsible for it." + (when (+mu4e-lock-available) + (delete-file +mu4e-lock-file) + (file-notify-rm-watch +mu4e-lock--request-watcher))) + +;;;###autoload +(defun +mu4e-lock-start (orig-fun &optional callback) + "Check `+mu4e-lock-file', and if another process is responsible for it, abort starting. +Else, write to this process' PID to the lock file" + (unless (+mu4e-lock-available) + (shell-command (format "touch %s" +mu4e-lock-request-file)) + (message "Lock file exists, requesting that it be given up") + (sleep-for 0.1) + (delete-file +mu4e-lock-request-file)) + (if (not (+mu4e-lock-available)) + (user-error "Unfortunately another Emacs is already doing stuff with Mu4e, and you can only have one at a time") + (write-region (number-to-string (emacs-pid)) nil +mu4e-lock-file) + (delete-file +mu4e-lock-request-file) + (funcall orig-fun callback) + (setq +mu4e-lock--request-watcher + (file-notify-add-watch +mu4e-lock-request-file + '(change) + #'+mu4e-lock-request)))) + +(defvar +mu4e-lock--file-watcher nil) +(defvar +mu4e-lock--file-just-deleted nil) +(defvar +mu4e-lock--request-watcher nil) + +;;;###autoload +(defun +mu4e-lock-add-watcher () + (setq +mu4e-lock--file-just-deleted nil) + (file-notify-rm-watch +mu4e-lock--file-watcher) + (setq +mu4e-lock--file-watcher + (file-notify-add-watch +mu4e-lock-file + '(change) + #'+mu4e-lock-file-updated))) + +;;;###autoload +(defun +mu4e-lock-request (event) + "Handle another process requesting the Mu4e lock." + (when (equal (nth 1 event) 'created) + (when +mu4e-lock-relaxed + (mu4e~stop) + (file-notify-rm-watch +mu4e-lock--file-watcher) + (message "Someone else wants to use Mu4e, releasing lock") + (delete-file +mu4e-lock-file) + (run-at-time 0.2 nil #'+mu4e-lock-add-watcher)) + (delete-file +mu4e-lock-request-file))) + +;;;###autoload +(defun +mu4e-lock-file-updated (event) + (if +mu4e-lock--file-just-deleted + (+mu4e-lock-add-watcher) + (when (equal (nth 1 event) 'deleted) + (setq +mu4e-lock--file-just-deleted t) + (when (and +mu4e-lock-greedy (+mu4e-lock-available t)) + (message "Noticed Mu4e lock was available, grabbed it") + (run-at-time 0.2 nil #'mu4e~start))))) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 6b45af9e1..d0b6c1dbd 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -190,9 +190,9 @@ :v "?" #'mu4e-headers-mark-for-unread :v "u" #'mu4e-headers-mark-for-unmark)) - (add-hook 'mu4e-compose-pre-hook '+mu4e-set-from-address) + (add-hook 'mu4e-compose-pre-hook '+mu4e-set-from-address-h) - (advice-add #'mu4e~main-action-str :override #'+mu4e~main-action-str-prettier) + (advice-add #'mu4e~main-action-str :override #'+mu4e~main-action-str-prettier-a) (when (featurep! :editor evil) ;; As +mu4e~main-action-str-prettier replaces [k]ey with key q]uit should become quit (setq evil-collection-mu4e-end-region-misc "quit")) @@ -226,8 +226,8 @@ Usefull for affecting HTML export config.") :after #'org-msg-org-to-xml (setq +org-msg-currently-exporting nil)) - (advice-add #'org-html-latex-fragment :override #'+org-html-latex-fragment-scaled) - (advice-add #'org-html-latex-environment :override #'+org-html-latex-environment-scaled) + (advice-add #'org-html-latex-fragment :override #'+org-html-latex-fragment-scaled-a) + (advice-add #'org-html-latex-environment :override #'+org-html-latex-environment-scaled-a) (defvar +mu4e-compose-org-msg-toggle-next t ; t to initialise org-msg "Whether to toggle ") From 7cf91ff61d0209c5837a4a5a6f3aa94f7bc5bb7c Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 17:21:20 +0800 Subject: [PATCH 056/119] =?UTF-8?q?Mu4e:=20Further=20americanisation=20(co?= =?UTF-8?q?lour=20=E2=86=92=20color)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/email/mu4e/README.org | 8 ++++---- modules/email/mu4e/autoload/email.el | 18 +++++++++--------- modules/email/mu4e/config.el | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index ed8134ae9..6fbcca032 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -74,12 +74,12 @@ environment.systemPackages = with pkgs; [ * Features + Tidied mu4e headers view, with flags from =all-the-icons= -+ Consistent colouring of reply depths (across compose and gnus modes) ++ Consistent coloring of reply depths (across compose and gnus modes) + Prettified =mu4e:main= view + Cooperative locking of the =mu= process. Another Emacs instance may request access, or grab the lock when it's available. + =org-msg= integration with =+org=, which can be toggled per-message, with revamped style and - an accent colour + an accent color + Gmail integrations with the =+gmail= flag + Email notifications with =mu4e-alert=, and (on Linux) a customised notification style @@ -174,8 +174,8 @@ To disable ~org-msg-mode~ by default, simply To toggle org-msg for a single message, just apply the universal argument to the compose or reply command (=SPC u= with ~evil~, =C-u= otherwise). -The accent colour that Doom uses can be customised by setting -~+org-msg-accent-color~ to a CSS colour string. +The accent color that Doom uses can be customised by setting +~+org-msg-accent-color~ to a CSS color string. *** Disabling If you don't like OrgMsg, simply add diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index ffed628e0..4a91ef63d 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -94,13 +94,13 @@ will also be the width of all other printable characters." (car (window-text-pixel-size))))) ;;;###autoload -(cl-defun +mu4e-normalised-icon (name &key set colour height v-adjust) +(cl-defun +mu4e-normalised-icon (name &key set color height v-adjust) "Convert :icon declaration to icon" (let* ((icon-set (intern (concat "all-the-icons-" (or set "faicon")))) (v-adjust (or v-adjust 0.02)) (height (or height 0.8)) - (icon (if colour - (apply icon-set `(,name :face ,(intern (concat "all-the-icons-" colour)) :height ,height :v-adjust ,v-adjust)) + (icon (if color + (apply icon-set `(,name :face ,(intern (concat "all-the-icons-" color)) :height ,height :v-adjust ,v-adjust)) (apply icon-set `(,name :height ,height :v-adjust ,v-adjust)))) (icon-width (+mu4e--get-string-width icon)) (space-width (+mu4e--get-string-width " ")) @@ -116,19 +116,19 @@ will also be the width of all other printable characters." mu4e-headers-new-mark (cons "N" (+mu4e-normalised-icon "sync" :set "material" :height 0.8 :v-adjust -0.10)) mu4e-headers-passed-mark (cons "P" (+mu4e-normalised-icon "arrow-right")) mu4e-headers-replied-mark (cons "R" (+mu4e-normalised-icon "arrow-right")) - mu4e-headers-seen-mark (cons "S" "") ;(+mu4e-normalised-icon "eye" :height 0.6 :v-adjust 0.07 :colour "dsilver")) + mu4e-headers-seen-mark (cons "S" "") ;(+mu4e-normalised-icon "eye" :height 0.6 :v-adjust 0.07 :color "dsilver")) mu4e-headers-trashed-mark (cons "T" (+mu4e-normalised-icon "trash")) - mu4e-headers-attach-mark (cons "a" (+mu4e-normalised-icon "file-text-o" :colour "silver")) + mu4e-headers-attach-mark (cons "a" (+mu4e-normalised-icon "file-text-o" :color "silver")) mu4e-headers-encrypted-mark (cons "x" (+mu4e-normalised-icon "lock")) - mu4e-headers-signed-mark (cons "s" (+mu4e-normalised-icon "certificate" :height 0.7 :colour "dpurple")) + mu4e-headers-signed-mark (cons "s" (+mu4e-normalised-icon "certificate" :height 0.7 :color "dpurple")) mu4e-headers-unread-mark (cons "u" (+mu4e-normalised-icon "eye-slash" :v-adjust 0.05)))) ;;;###autoload (defun +mu4e-header-colorize (str) (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) - (colour (nth (% str-sum (length mu4e-header-colorized-faces)) - mu4e-header-colorized-faces))) - (put-text-property 0 (length str) 'face colour str) + (color (nth (% str-sum (length +mu4e-header-colorized-faces)) + +mu4e-header-colorized-faces))) + (put-text-property 0 (length str) 'face color str) str)) ;; Adding emails to the agenda diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index d0b6c1dbd..738a188c3 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -71,7 +71,7 @@ (setq mail-user-agent 'mu4e-user-agent message-mail-user-agent 'mu4e-user-agent) - ;; Make reply colouring consistant, and striped for readability + ;; Make reply coloring consistant, and striped for readability (custom-set-faces! '(gnus-cite-2 :foreground nil :inherit gnus-cite-10) '(gnus-cite-3 :foreground nil :inherit gnus-cite-7) From 64905654040d158216158e477c0d68448787ffeb Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 17:28:10 +0800 Subject: [PATCH 057/119] Mu4e: Add account stripe, and use it by default --- modules/email/mu4e/autoload/email.el | 42 +++++++++++++++++ modules/email/mu4e/config.el | 67 ++++++++++++++++------------ 2 files changed, 80 insertions(+), 29 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 4a91ef63d..7efe18789 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -131,6 +131,48 @@ will also be the width of all other printable characters." (put-text-property 0 (length str) 'face color str) str)) +;;;###autoload +(defun +mu4e-colorize-str (str &optional unique herring) + "Apply a face from `+mu4e-header-colorized-faces' to STR. +If HERRING is set, it will be used to determine the face instead of STR. +Will try to make unique when non-nil UNIQUE, +a quoted symbol for a alist of current strings and faces provided." + (unless herring + (setq herring str)) + (put-text-property + 0 (length str) + 'face + (if (not unique) + (+mu4e--str-color-face herring str) + (let ((unique-alist (eval unique))) + (unless (assoc herring unique-alist) + (if (> (length unique-alist) (length +mu4e-header-colorized-faces)) + (push (cons herring (+mu4e--str-color-face herring)) unique-alist) + (let ((offset 0) color color?) + (while (not color) + (setq color? (+mu4e--str-color-face herring offset)) + (if (not (rassoc color? unique-alist)) + (setq color color?) + (setq offset (1+ offset)) + (when (> offset (length +mu4e-header-colorized-faces)) + (message "Warning: +mu4e-colorize-str was called with non-unique-alist UNIQUE-alist alist.") + (setq color (+mu4e--str-color-face herring))))) + (push (cons herring color) unique-alist))) + (set unique unique-alist)) + (cdr (assoc herring unique-alist)))) + str) + str) + +;;;###autoload +(defun +mu4e--str-color-face (str &optional offset) + "Select a face from `+mu4e-header-colorized-faces' based on +STR and any integer OFFSET." + (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) + (color (nth (% (+ str-sum (if offset offset 0)) + (length +mu4e-header-colorized-faces)) + +mu4e-header-colorized-faces))) + color)) + ;; Adding emails to the agenda ;; Perfect for when you see an email you want to reply to ;; later, but don't want to forget about diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 738a188c3..934c9102e 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -61,10 +61,10 @@ mu4e-headers-thread-connection-prefix '("│" . "│ ") ;; remove 'lists' column mu4e-headers-fields - '((:account . 12) + '((:account-stripe . 1) (:human-date . 8) (:flags . 6) ; 3 icon flags - (:from . 25) + (:from-or-to . 25) (:subject))) ;; set mail user agent @@ -94,39 +94,48 @@ (add-to-list 'mu4e-bookmarks '(:name "Flagged messages" :query "flag:flagged" :key ?f) t) - (defun +mu4e-header-colorize (str) - (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) - (colour (nth (% str-sum (length +mu4e-header-colorized-faces)) - +mu4e-header-colorized-faces))) - (put-text-property 0 (length str) 'face colour str) - str)) + (setq +mu4e-header-colorized-faces + '(all-the-icons-green + all-the-icons-lblue + all-the-icons-purple-alt + all-the-icons-blue-alt + all-the-icons-purple + all-the-icons-yellow)) - (defvar +mu4e-header-colorized-faces - '(all-the-icons-lblue - all-the-icons-purple - all-the-icons-blue-alt - all-the-icons-green - all-the-icons-maroon - all-the-icons-yellow - all-the-icons-orange)) - - ;; Add a column to display what email account the email belongs to. + ;; Add a column to display what email account the email belongs to, + ;; and an account color stripe column + (defvar +mu4e-header--maildir-colors nil) (setq mu4e-header-info-custom '((:account . - (:name "account" - :shortname "account" + (:name "Account" + :shortname "Account" :help "which account this email belongs to" :function (lambda (msg) - (let ((maildir - (mu4e-message-field msg :maildir))) - (+mu4e-header-colorize - (replace-regexp-in-string - "^gmail" - (propertize "g" 'face 'bold-italic) - (format "%s" - (substring maildir 1 - (string-match-p "/" maildir 1))))))))) + (+mu4e-colorize-str + (replace-regexp-in-string + "^gmail" + (propertize "g" 'face 'bold-italic) + (format "%s" + (substring maildir 1 + (string-match-p "/" maildir 1)))) + '+mu4e-header--maildir-colors + (replace-regexp-in-string + "\\`/\\([^/]+\\)/.*\\'" "\\1" + (mu4e-message-field msg :maildir)))))) + (:account-stripe . + (:name "Account" + :shortname "▐" + :help "Which account this email belongs to" + :function + (lambda (msg) + (let ((account + (replace-regexp-in-string + "\\`/?\\([^/]+\\)/.*\\'" "\\1" + (mu4e-message-field msg :maildir)))) + (propertize + (+mu4e-colorize-str "▌" '+mu4e-header--maildir-colors account) + 'help-echo account))))) (:recipnum . (:name "Number of recipients" :shortname " ⭷" From 42ee991f4a245322f76e1bbcb490f2045593673c Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 14 Oct 2020 17:49:16 +0800 Subject: [PATCH 058/119] Mu4e: Remove (now-)unused header colourise func --- modules/email/mu4e/autoload/email.el | 8 -------- 1 file changed, 8 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 7efe18789..966eb8b1a 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -123,14 +123,6 @@ will also be the width of all other printable characters." mu4e-headers-signed-mark (cons "s" (+mu4e-normalised-icon "certificate" :height 0.7 :color "dpurple")) mu4e-headers-unread-mark (cons "u" (+mu4e-normalised-icon "eye-slash" :v-adjust 0.05)))) -;;;###autoload -(defun +mu4e-header-colorize (str) - (let* ((str-sum (apply #'+ (mapcar (lambda (c) (% c 3)) str))) - (color (nth (% str-sum (length +mu4e-header-colorized-faces)) - +mu4e-header-colorized-faces))) - (put-text-property 0 (length str) 'face color str) - str)) - ;;;###autoload (defun +mu4e-colorize-str (str &optional unique herring) "Apply a face from `+mu4e-header-colorized-faces' to STR. From acab6a3cded790aaf16393ccd630e1bbc8b92c68 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 15 Oct 2020 22:30:23 +0800 Subject: [PATCH 059/119] Mu4e: Another variable missing the "+" prefix --- modules/email/mu4e/config.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 934c9102e..af237ca54 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -161,12 +161,12 @@ ;; actually show you all the information you want to see ;; so if the header view is entered from a narrow frame, ;; it's probably worth trying to expand it - (defvar mu4e-min-header-frame-width 120 + (defvar +mu4e-min-header-frame-width 120 "Minimum reasonable with for the header view.") (defun mu4e-widen-frame-maybe () - "Expand the frame with if it's less than `mu4e-min-header-frame-width'." - (when (< (frame-width) mu4e-min-header-frame-width) - (set-frame-width (selected-frame) mu4e-min-header-frame-width))) + "Expand the frame with if it's less than `+mu4e-min-header-frame-width'." + (when (< (frame-width) +mu4e-min-header-frame-width) + (set-frame-width (selected-frame) +mu4e-min-header-frame-width))) (add-hook 'mu4e-headers-mode-hook #'mu4e-widen-frame-maybe) (when (fboundp 'imagemagick-register-types) From 4561d8c29d983381026063bced4ff0f874226680 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 15 Oct 2020 22:30:46 +0800 Subject: [PATCH 060/119] Mu4e: Fix invalid icon hook removal --- modules/email/mu4e/config.el | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index af237ca54..8778a83cc 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -84,11 +84,13 @@ (if (display-graphic-p) (+mu4e-initialise-icons) ;; When it's the server, wait till the first graphical frame - (add-hook! 'server-after-make-frame-hook - (defun +mu4e-initialise-icons-hook () - (when (display-graphic-p) - (+mu4e-initialise-icons) - (remove-hook #'+mu4e-initialise-icons-hook))))) + (add-hook + 'server-after-make-frame-hook + (defun +mu4e-initialise-icons-hook () + (when (display-graphic-p) + (+mu4e-initialise-icons) + (remove-hook 'server-after-make-frame-hook + #'+mu4e-initialise-icons-hook))))) (plist-put (cdr (assoc :flags mu4e-header-info)) :shortname " Flags") ; default=Flgs (add-to-list 'mu4e-bookmarks From f2445eb6a032b7c2c64fffb832f08dacc3f0b3f7 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 16 Oct 2020 10:48:41 +0800 Subject: [PATCH 061/119] Mu4e: Gah. Typos --- modules/email/mu4e/autoload/email.el | 2 +- modules/email/mu4e/config.el | 4 ++-- modules/email/mu4e/doctor.el | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 966eb8b1a..e737ec994 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -15,7 +15,7 @@ OPTIONAL: + `mu4e-trash-folder' + `mu4e-refile-folder' + `mu4e-compose-signature' - + `+mu4e-personal-adresses' + + `+mu4e-personal-addresses' DEFAULT-P is a boolean. If non-nil, it marks that email account as the default/fallback account." diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 8778a83cc..733c64820 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -3,8 +3,8 @@ (defvar +mu4e-backend 'mbsync "Which backend to use. Can either be offlineimap, mbsync or nil (manual).") -(defvar +mu4e-personal-adresses 'nil - "Alternative to mu4e-personal-adresses that can be set for each account (mu4e context).") +(defvar +mu4e-personal-addresses 'nil + "Alternative to mu4e-personal-addresses that can be set for each account (mu4e context).") ;; diff --git a/modules/email/mu4e/doctor.el b/modules/email/mu4e/doctor.el index 3355e6021..d4c71cb4e 100644 --- a/modules/email/mu4e/doctor.el +++ b/modules/email/mu4e/doctor.el @@ -5,7 +5,7 @@ (unless (or (executable-find "mbsync") (executable-find "offlineimap")) - (wan! "Couldn't find mbsync or offlineimap command. \ + (warn! "Couldn't find mbsync or offlineimap command. \ You may not have a way of fetching mail.")) (when (and (featurep! +org) From 44c831ce59329cf9275397c8fa462e615be78a0e Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 17 Oct 2020 12:32:40 +0800 Subject: [PATCH 062/119] Mu4e: Missed a spot when func renamed --- modules/email/mu4e/config.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 733c64820..36c5332fb 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -182,7 +182,7 @@ :ne "h" #'+workspace/other) (map! :map mu4e-headers-mode-map - :vne "l" #'mu4e/refile-msg-to-agenda) + :vne "l" #'+mu4e/refile-msg-to-agenda) (map! :localleader :map mu4e-compose-mode-map From 8e4f559a525bfea15bae5426d9ae4fd45a400ea7 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 22 Oct 2020 00:23:25 +0800 Subject: [PATCH 063/119] Mu4e: Correct reference to unbound variable --- modules/email/mu4e/config.el | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 36c5332fb..304c51b9c 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -111,24 +111,23 @@ '((:account . (:name "Account" :shortname "Account" - :help "which account this email belongs to" + :help "which account/maildir this email belongs to" :function (lambda (msg) + (let ((maildir (replace-regexp-in-string + "\\`/?\\([^/]+\\)/.*\\'" "\\1" + (mu4e-message-field msg :maildir))))) (+mu4e-colorize-str (replace-regexp-in-string "^gmail" (propertize "g" 'face 'bold-italic) - (format "%s" - (substring maildir 1 - (string-match-p "/" maildir 1)))) + maildir) '+mu4e-header--maildir-colors - (replace-regexp-in-string - "\\`/\\([^/]+\\)/.*\\'" "\\1" - (mu4e-message-field msg :maildir)))))) + maildir)))) (:account-stripe . (:name "Account" :shortname "▐" - :help "Which account this email belongs to" + :help "Which account/maildir this email belongs to" :function (lambda (msg) (let ((account From b6f54946013cb6ef04745372dad0fdacb5e344a9 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 22 Oct 2020 00:24:26 +0800 Subject: [PATCH 064/119] Mu4e: Avoid conflict in mu4e view action name The HTML and PDF views already bind to v/V --- modules/email/mu4e/config.el | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 304c51b9c..79c6c9ecf 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -157,6 +157,8 @@ ;; Html mails might be better rendered in a browser (add-to-list 'mu4e-view-actions '("View in browser" . mu4e-action-view-in-browser)) + (when (fboundp 'make-xwidget) + (add-to-list 'mu4e-view-actions '("xwidgets view" . mu4e-action-view-with-xwidget))) ;; The header view needs a certain amount of horizontal space to ;; actually show you all the information you want to see @@ -173,10 +175,6 @@ (when (fboundp 'imagemagick-register-types) (imagemagick-register-types)) - (when (fboundp 'make-xwidget) - (push '("view with xwidgets" . mu4e-action-view-with-xwidget) - mu4e-view-actions)) - (map! :map mu4e-main-mode-map :ne "h" #'+workspace/other) From 16b4a31bf9d6c86cb22508c0ca84254ad38ebf72 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 30 Oct 2020 19:01:46 +0800 Subject: [PATCH 065/119] Mu4e: Recommend mbsync, and describe msmtp setup --- modules/email/mu4e/README.org | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 6fbcca032..e3d2b2fe2 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -46,7 +46,7 @@ via IMAP) and ~mu~ (to index my mail into a format ~mu4e~ can understand). * Prerequisites This module requires: -+ Either ~mbsync~ (default) or ~offlineimap~ (to sync mail with) ++ Either ~mbsync~ (recommended, default) or ~offlineimap~ (to sync mail with) + ~mu~, to index your downloaded messages and to provide the ~mu4e~ package. #+name: Install Matrix @@ -60,6 +60,20 @@ This module requires: The install either the =isync= (=mbsync=) or =offlineimap= package. +To send mail, mu4e uses [[https://www.gnu.org/software/emacs/manual/html_mono/smtpmail.html][smtpmail]] (an Emacs library) by default. +You can also run a local SMTP server like =sendmail= or =postfix=, or use an SMTP +forwarder such as =msmtp= (recommended). + +If you use =msmtp=, you'll likely want to add the following to your +=config.el=: +#+begin_src emacs-lisp +(setq sendmail-program "/usr/bin/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) +#+end_src + ** NixOS #+BEGIN_SRC nix environment.systemPackages = with pkgs; [ From 3c0df378a6f5c338566a5d478144bfa5aa05b0a3 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 31 Oct 2020 19:04:29 +0800 Subject: [PATCH 066/119] Mu4e: rename msg refile func, customisable target --- modules/email/mu4e/autoload/email.el | 16 ++++++++++------ modules/email/mu4e/config.el | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index e737ec994..410d85988 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -165,21 +165,25 @@ STR and any integer OFFSET." +mu4e-header-colorized-faces))) color)) +(defvar +org-capture-emails-file "todo.org" + "Default target for storing mu4e emails captured from within mu4e. +Requires a \"* Email\" heading be present in the file.") + ;; Adding emails to the agenda ;; Perfect for when you see an email you want to reply to ;; later, but don't want to forget about ;;;###autoload -(defun +mu4e/refile-msg-to-agenda (arg) - "Refile a message and add a entry in the agenda file with a +(defun +mu4e/capture-msg-to-agenda (arg) + "Refile a message and add a entry in `+org-capture-emails-file' with a deadline. Default deadline is today. With one prefix, deadline is tomorrow. With two prefixes, select the deadline." (interactive "p") - (let ((file (car org-agenda-files)) - (sec "^* Email") - (msg (mu4e-message-at-point))) + (let ((sec "^* Email") + (msg (mu4e-message-at-point))) (when msg ;; put the message in the agenda - (with-current-buffer (find-file-noselect file) + (with-current-buffer (find-file-noselect + (expand-file-name +org-capture-emails-file org-directory)) (save-excursion ;; find header section (goto-char (point-min)) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 79c6c9ecf..e4b21abd7 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -179,7 +179,7 @@ :ne "h" #'+workspace/other) (map! :map mu4e-headers-mode-map - :vne "l" #'+mu4e/refile-msg-to-agenda) + :vne "l" #'+mu4e/capture-msg-to-agenda) (map! :localleader :map mu4e-compose-mode-map From 089b4e6b04d8999962dc2072b20ccb80e1682b5e Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 31 Oct 2020 19:09:45 +0800 Subject: [PATCH 067/119] Mu4e: make msg compose advice more transparent ... to functions that call the original function --- modules/email/mu4e/config.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index e4b21abd7..c7fba5f85 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -245,11 +245,11 @@ Usefull for affecting HTML export config.") (setq +mu4e-compose-org-msg-toggle-next (not +mu4e-compose-org-msg-toggle-next)))) - (defadvice! mu4e-maybe-toggle-org-msg (orig-fn toggle-p) + (defadvice! mu4e-maybe-toggle-org-msg (orig-fn &optional toggle-p) :around #'mu4e-compose-new :around #'mu4e-compose-reply (interactive "p") - (mu4e-compose-org-msg-handle-toggle (/= 1 toggle-p)) + (mu4e-compose-org-msg-handle-toggle (/= 1 (or toggle-p 0))) (funcall orig-fn)) (defvar +org-msg-accent-color "#c01c28" From ba5dee4a194e49a3814424ab262b8e3546546841 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 31 Oct 2020 19:11:57 +0800 Subject: [PATCH 068/119] Mu4e: apply msg compose advice to more situations --- modules/email/mu4e/config.el | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index c7fba5f85..91425cb6f 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -248,6 +248,8 @@ Usefull for affecting HTML export config.") (defadvice! mu4e-maybe-toggle-org-msg (orig-fn &optional toggle-p) :around #'mu4e-compose-new :around #'mu4e-compose-reply + :around #'mu4e-compose-forward + :around #'mu4e-compose-resend (interactive "p") (mu4e-compose-org-msg-handle-toggle (/= 1 (or toggle-p 0))) (funcall orig-fn)) From e0d23551268a136332324c20ddd6a1d49ab64230 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 31 Oct 2020 19:12:24 +0800 Subject: [PATCH 069/119] Mu4e: make flycheck happier --- modules/email/mu4e/config.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 91425cb6f..216bc1b58 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -423,7 +423,7 @@ Should be treated as a gmail address.") (list :char '("D" . "✘") :prompt "Delete" - :show-target (lambda (target) "delete") + :show-target (lambda (_target) "delete") :action (lambda (docid msg target) (if (+mu4e-msg-gmail-p msg) (progn (message "The delete operation is invalid for Gmail accounts. Trashing instead.") @@ -480,13 +480,12 @@ Should be treated as a gmail address.") (mu4e-alert-set-default-style 'libnotify) (setq mu4e-alert-email-notification-types '(subjects)) - (defun +mu4e-alert-grouped-mail-notification-formatter-with-bell (mail-group all-mails) + (defun +mu4e-alert-grouped-mail-notification-formatter-with-bell (mail-group _all-mails) "Default function to format MAIL-GROUP for notification. ALL-MAILS are the all the unread emails" (shell-command "paplay /usr/share/sounds/freedesktop/stereo/message.oga") (if (> (length mail-group) 1) (let* ((mail-count (length mail-group)) - (total-mails (length all-mails)) (first-mail (car mail-group)) (title-prefix (format "You have %d unread emails" mail-count)) From eddbda66500819ab07e37d4979ac280e3e9bcaa8 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 31 Oct 2020 19:12:40 +0800 Subject: [PATCH 070/119] Mu4e: Add stub org-msg-mode in case called by func --- modules/email/mu4e/config.el | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 216bc1b58..2df71f34e 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -215,6 +215,12 @@ (advice-add 'mu4e~start :around #'+mu4e-lock-start) (advice-add 'mu4e-quit :after #'+mu4e-lock-file-delete-maybe)) +(unless (featurep! +org) + (after! mu4e + (defun org-msg-mode (&optional _) + "Dummy function." + (message "Enable the +org mu4e flag to use org-msg-mode.")))) + (use-package! org-msg :after mu4e :when (featurep! +org) From d945987b93f5909783f35b9ac50876ab5db838c6 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 31 Oct 2020 19:34:42 +0800 Subject: [PATCH 071/119] Mu4e: make attachments possible without pain --- modules/email/mu4e/autoload/email.el | 76 ++++++++++++++++++++++++++++ modules/email/mu4e/config.el | 7 ++- 2 files changed, 82 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 410d85988..73df19655 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -231,6 +231,82 @@ is tomorrow. With two prefixes, select the deadline." ((= arg 4) "tomorrow") (t "later")))))) +;;;###autoload +(defun +mu4e/attach-files (&optional files-to-attach) + "When called in a dired buffer, ask for a message to attach the marked files to. +When called in a mu4e:compose or org-msg buffer, open a dired window to select file attachments in, +and enable `dired-mu4e-attach-ctrl-c-ctrl-c' which adds C-c C-c as a keybinding to attach the files. + +When otherwise called, open a dired buffer." + ;; TODO add ability to attach files (+dirs) as a single (named) archive + (interactive "p") + (mu4e-compose-org-msg-handle-toggle (/= 1 files-to-attach)) + (pcase major-mode + ((or 'mu4e-compose-mode 'org-msg-edit-mode) + (let ((mail-buffer (current-buffer)) + (location (read-file-name "Attach: "))) + (if (not (file-directory-p location)) + (pcase major-mode + ('mu4e-compose-mode (mail-add-attachment location)) + ('org-msg-edit-mode (org-msg-attach-attach location))) + (split-window-sensibly) + (with-current-buffer (dired location) + (setq-local dired-mail-buffer mail-buffer) + (dired-mu4e-attach-ctrl-c-ctrl-c 1))))) + ('dired-mode + (unless (and files-to-attach (/= 1 files-to-attach)) + (setq files-to-attach + (delq nil + (mapcar + ;; don't attach directories + (lambda (f) (if (file-directory-p f) nil f)) + (nreverse (dired-map-over-marks (dired-get-filename) nil)))))) + (if (not files-to-attach) + (progn + (message "No files marked, aborting.") + (kill-buffer-and-window)) + (if-let ((mail-target-buffer (bound-and-true-p dired-mail-buffer))) + (progn (kill-buffer-and-window) + (switch-to-buffer mail-target-buffer)) + (if (and (+mu4e-current-buffers) + (y-or-n-p "Attach files to existing mail composition buffer? ")) + (progn (setf mail-target-buffer + (completing-read "Message: " (+mu4e-current-buffers))) + (kill-buffer-and-window) + (switch-to-buffer mail-target-buffer)) + (kill-buffer-and-window) + (mu4e-compose 'new))) + (mapcar + (pcase major-mode + ('mu4e-compose-mode #'mail-add-attachment) + ('org-msg-edit-mode #'org-msg-attach-attach)) + files-to-attach))) + (_ + (split-window-sensibly) + (with-current-buffer (call-interactively #'find-file) + (dired-mu4e-attach-ctrl-c-ctrl-c 1))))) + +;;;###autoload +(define-minor-mode dired-mu4e-attach-ctrl-c-ctrl-c + "Adds C-c C-c as an keybinding to attach files to a message." + :lighter "attach" + :keymap (let ((map (make-sparse-keymap))) + (define-key map (kbd "C-c C-c") '+mu4e/attach-files) + map)) + +;;;###autoload +(defun +mu4e-current-buffers () + "Return a list of active message buffers." + (let (buffers) + (save-current-buffer + (dolist (buffer (buffer-list t)) + (set-buffer buffer) + (when (or (and (derived-mode-p 'message-mode) + (null message-sent-message-via)) + (eq major-mode 'org-msg-edit-mode)) + (push (buffer-name buffer) buffers)))) + (nreverse buffers))) + ;; ;; Hooks diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 2df71f34e..8f39302a4 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -186,7 +186,7 @@ :desc "send and exit" "s" #'message-send-and-exit :desc "kill buffer" "d" #'message-kill-buffer :desc "save draft" "S" #'message-dont-send - :desc "attach" "a" #'mail-add-attachment) + :desc "attach" "a" #'+mu4e/attach-files) ;; Due to evil, none of the marking commands work when making a visual selection in ;; the headers view of mu4e. Without overriding any evil commands we may actually @@ -243,6 +243,11 @@ Usefull for affecting HTML export config.") (advice-add #'org-html-latex-fragment :override #'+org-html-latex-fragment-scaled-a) (advice-add #'org-html-latex-environment :override #'+org-html-latex-environment-scaled-a) + (map! :map org-msg-edit-mode-map + :desc "attach" "C-c C-a" #'+mu4e/attach-files + :localleader + :desc "attach" "a" #'+mu4e/attach-files) + (defvar +mu4e-compose-org-msg-toggle-next t ; t to initialise org-msg "Whether to toggle ") (defun mu4e-compose-org-msg-handle-toggle (toggle-p) From 2023eca45a2d297b1d4a6620f98e99830d9dcbc0 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 5 Nov 2020 02:16:27 +0800 Subject: [PATCH 072/119] Mu4e: ensure mu4e-compose-org-msg-handle-toggle ... is always defined --- modules/email/mu4e/config.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 8f39302a4..e14167c8c 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -219,7 +219,11 @@ (after! mu4e (defun org-msg-mode (&optional _) "Dummy function." - (message "Enable the +org mu4e flag to use org-msg-mode.")))) + (message "Enable the +org mu4e flag to use org-msg-mode.")) + (defun mu4e-compose-org-msg-handle-toggle (&rest _) + "Placeholder to allow for the assumtion that this function is defined. +Ignores all arguments and returns nil." + nil))) (use-package! org-msg :after mu4e From e760ba5540e5d59b4fd02d5f9c9081d00f0d8505 Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 18 Nov 2020 00:20:46 +0800 Subject: [PATCH 073/119] Mu4e: Blah. I messed up a let scope --- modules/email/mu4e/config.el | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index e14167c8c..55bd25b60 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -116,14 +116,14 @@ (lambda (msg) (let ((maildir (replace-regexp-in-string "\\`/?\\([^/]+\\)/.*\\'" "\\1" - (mu4e-message-field msg :maildir))))) - (+mu4e-colorize-str - (replace-regexp-in-string - "^gmail" - (propertize "g" 'face 'bold-italic) - maildir) - '+mu4e-header--maildir-colors - maildir)))) + (mu4e-message-field msg :maildir)))) + (+mu4e-colorize-str + (replace-regexp-in-string + "^gmail" + (propertize "g" 'face 'bold-italic) + maildir) + '+mu4e-header--maildir-colors + maildir))))) (:account-stripe . (:name "Account" :shortname "▐" From 941d3e36089b1124c5b692fd35382025aa447b5d Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 18 Nov 2020 00:24:27 +0800 Subject: [PATCH 074/119] Mu4e: Remove outdated content --- modules/email/mu4e/README.org | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index e3d2b2fe2..f76d1f8e4 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -179,8 +179,8 @@ an address to be treated as such but it meets neither conditions (e.g. with Gsuite). ** OrgMsg -By default, ~org-msg-mode~ is enabled before composing the first message. -To disable ~org-msg-mode~ by default, simply +With the =+org= flag, =org-msg= is installed, and ~org-msg-mode~ is enabled before +composing the first message. To disable ~org-msg-mode~ by default, simply #+BEGIN_SRC emacs-lisp :tangle no (setq mu4e-compose--org-msg-toggle-next nil) #+END_SRC @@ -191,16 +191,15 @@ compose or reply command (=SPC u= with ~evil~, =C-u= otherwise). The accent color that Doom uses can be customised by setting ~+org-msg-accent-color~ to a CSS color string. -*** Disabling -If you don't like OrgMsg, simply add +** mu4e-alert +This provides notifications through the [[https://github.com/jwiegley/alert][alert]] library. + +If you don't like this, simply add #+begin_src emacs-lisp -(package! org-msg :disable t) +(package! mu4e-alert :disable t) #+end_src to your [[elisp:(find-file (expand-file-name "packages.el" doom-private-dir))][packages.el]] and it will not be used. -** mu4e-alert -This is used by default. It can be disabled in the same manner as [[*OrgMsg][OrgMsg.]] - * Troubleshooting ** =No such file or directory, mu4e= You will get =No such file or directory, mu4e= errors if you don't run ~doom From f7438325d9551b4ceb31ae00a27eab7dec6b10f1 Mon Sep 17 00:00:00 2001 From: TEC Date: Mon, 30 Nov 2020 02:16:50 +0800 Subject: [PATCH 075/119] Mu4e: Nobody really likes format-flowed We have autofill, that's good enough. --- modules/email/mu4e/config.el | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 55bd25b60..c9df0af61 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -30,7 +30,6 @@ (setq mu4e-get-mail-command "offlineimap -o -q"))) (setq mu4e-update-interval nil - mu4e-compose-format-flowed t ; visual-line-mode + auto-fill upon sending mu4e-view-show-addresses t mu4e-sent-messages-behavior 'sent mu4e-hide-index-messages t From 6c2d68ea173a0bcfa6d424818ad2482087a379dc Mon Sep 17 00:00:00 2001 From: TEC Date: Wed, 16 Dec 2020 04:23:23 +0800 Subject: [PATCH 076/119] Mu4e: ensure that attachment isn't mixed with text Ensure that mail-add-attachment is called on a blank line at the end of the buffer. --- modules/email/mu4e/autoload/email.el | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 73df19655..08744e34f 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -247,7 +247,13 @@ When otherwise called, open a dired buffer." (location (read-file-name "Attach: "))) (if (not (file-directory-p location)) (pcase major-mode - ('mu4e-compose-mode (mail-add-attachment location)) + ('mu4e-compose-mode + (save-excursion + (goto-char (point-max)) + (unless (eq (current-column) 0) + (insert "\n\n") + (forward-line 2)) + (mail-add-attachment location))) ('org-msg-edit-mode (org-msg-attach-attach location))) (split-window-sensibly) (with-current-buffer (dired location) From 39442daeb2e4b55f9075bd623299acb769057349 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 5 Jan 2021 16:30:29 +0800 Subject: [PATCH 077/119] Bump org-msg jeremy-compostella/org-msg@2db6725 -> jeremy-compostella/org-msg@bb378c79 Also update `org-msg-text-plain-alternative` to new format --- modules/email/mu4e/config.el | 2 +- modules/email/mu4e/packages.el | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index c9df0af61..e4991e4e4 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -231,7 +231,7 @@ Ignores all arguments and returns nil." (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil tex:dvipng" org-msg-startup "hidestars indent inlineimages" org-msg-greeting-name-limit 3 - org-msg-text-plain-alternative t) + org-msg-default-alternatives '(html text)) (defvar +org-msg-currently-exporting nil "Helper variable to indicate whether org-msg is currently exporting the org buffer to HTML. diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index 3a448797e..482d72d3d 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -2,6 +2,6 @@ ;;; email/mu4e/packages.el (when (featurep! +org) - (package! org-msg :pin "2db6725c4a4f4342a9c61895b7c3c82795b01fee")) + (package! org-msg :pin "bb378c7942804b81ac9ddf4b14381cd9d84c993c")) (package! mu4e-alert :pin "91f0657c5b245a9de57aa38391221fb5d141d9bd") From 78cdb80d2cb57390664c6a9108023287d8b019b5 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 5 Jan 2021 16:29:44 +0800 Subject: [PATCH 078/119] Mu4e: Org-msg, prioritise HTML over plaintext --- modules/email/mu4e/config.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index e4991e4e4..f4d83ca35 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -231,7 +231,7 @@ Ignores all arguments and returns nil." (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil tex:dvipng" org-msg-startup "hidestars indent inlineimages" org-msg-greeting-name-limit 3 - org-msg-default-alternatives '(html text)) + org-msg-default-alternatives '(text html)) (defvar +org-msg-currently-exporting nil "Helper variable to indicate whether org-msg is currently exporting the org buffer to HTML. From 611e532d38f2e3883b1db3b215d64acaaa1d7a68 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 5 Jan 2021 16:31:16 +0800 Subject: [PATCH 079/119] Mu4e: Org-msg, convert "> ..." ascii quotations --- modules/email/mu4e/config.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index f4d83ca35..4d084fcf6 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -231,7 +231,8 @@ Ignores all arguments and returns nil." (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil tex:dvipng" org-msg-startup "hidestars indent inlineimages" org-msg-greeting-name-limit 3 - org-msg-default-alternatives '(text html)) + org-msg-default-alternatives '(text html) + org-msg-convert-citation t) (defvar +org-msg-currently-exporting nil "Helper variable to indicate whether org-msg is currently exporting the org buffer to HTML. From 2307ae564456f01dda26870f86b8d23b81226dfd Mon Sep 17 00:00:00 2001 From: TEC Date: Sun, 17 Jan 2021 13:49:10 -0600 Subject: [PATCH 080/119] Mu4e: More robust Gmail account checking Emails sent to an @gmail.com account may have been forwarded to a non-gmail mailbox. Thus the current approach is over-eager. Only checking @gmail on send, and then matching a user's maildir (not email) with received messages is a more robust approach. To accommodate this we switch `+mu4e-gmail-addresses' out for `+mu4e-gmail-accounts'. Along the way `mu4e-index-cleanup' and `mu4e-index-lazy-check' customisations were moved into the readme as a recommendation for Gmail-only users, to avoid causing adverse effects for users who have non-gmail accounts too. --- modules/email/mu4e/README.org | 28 +++++++++++++++++++---- modules/email/mu4e/config.el | 43 ++++++++++++----------------------- 2 files changed, 39 insertions(+), 32 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index f76d1f8e4..3da30fec7 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -173,10 +173,30 @@ Then configure Emacs to use your email address: With the =+gmail= flag, integrations are applied which account for the different behaviour of Gmail. -The integrations are applied when using addresses which contain =@gmail.com= or -have =gmail= in the maildir name. You can use ~+mu4e-gmail-addresses~ when you want -an address to be treated as such but it meets neither conditions (e.g. with -Gsuite). +The integrations are applied to addresses with /both/ "@gmail.com" in the +account address and "gmail" in the account maildir, as well as accounts listed +in ~+mu4e-gmail-accounts~. Any domain can be specified, so G Suite accounts can +benefit from the integrations: +#+begin_src emacs-lisp +;; if "gmail" is missing from the address or maildir, the account must be listed here +(setq +mu4e-gmail-accounts '(("hlissner@gmail.com" . "/hlissner") + ("example@example.com" . "/example"))) +#+end_src + +If you only use Gmail, you can improve performance due to the way Gmail +presents messages over IMAP: +#+begin_src emacs-lisp +;; don't need to run cleanup after indexing for gmail +(setq 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) +#+end_src + +Also, note that Gmail's IMAP settings must have "When I mark a message in IMAP +as deleted: Auto-Expunge off - Wait for the client to update the server." and +"When a message is marked as deleted and expunged from the last visible IMAP +folder: Move the message to the trash" for the integrations to work as expected. ** OrgMsg With the =+org= flag, =org-msg= is installed, and ~org-msg-mode~ is enabled before diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 4d084fcf6..1c2298550 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -387,45 +387,32 @@ Must be set before org-msg is loaded to take effect.") (when (featurep! +gmail) (after! mu4e - (defvar +mu4e-gmail-addresses nil - "A list of email addresses which, despite not: -- having '@gmail.com' in them, or -- being in a maildir where the name includes 'gmail' + (defvar +mu4e-gmail-accounts nil + "Gmail accounts that do not contain \"gmail\" in address and maildir. -Should be treated as a gmail address.") +An alist of Gmail addresses of the format \((\"username@domain.com\" . \"account-maildir\")) +to which Gmail integrations (behind the `+gmail' flag of the `mu4e' module) should be applied. + +See `+mu4e-msg-gmail-p' and `mu4e-sent-messages-behavior'.") ;; don't save message to Sent Messages, Gmail/IMAP takes care of this (setq mu4e-sent-messages-behavior (lambda () ;; TODO make use +mu4e-msg-gmail-p (if (or (string-match-p "@gmail.com\\'" (message-sendmail-envelope-from)) - (member (message-sendmail-envelope-from) +mu4e-gmail-addresses)) - 'delete 'sent)) - - ;; 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) + (member (message-sendmail-envelope-from) + (mapcar #'car +mu4e-gmail-accounts))) + 'delete 'sent))) (defun +mu4e-msg-gmail-p (msg) - (or - (string-match-p "@gmail.com" - (cond - ((member (mu4e-message-field msg :to) - (append (mu4e-personal-addresses) - +mu4e-gmail-addresses)) - (mu4e-message-field msg :to)) - ((member (mu4e-message-field msg :from) - (append (mu4e-personal-addresses) - +mu4e-gmail-addresses)) - (mu4e-message-field msg :from)) - (t ""))) - (string-match-p "gmail" (mu4e-message-field msg :maildir)))) + (let ((root-maildir + (replace-regexp-in-string "/.*" "" + (substring (mu4e-message-field msg :maildir) 1)))) + (or (string-match-p "gmail" root-maildir) + (member root-maildir (mapcar #'cdr +mu4e-gmail-accounts))))) ;; 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'. + ;; However, the real magic happens in `+mu4e-gmail-fix-flags-h'. ;; ;; Gmail will handle the rest. (defun +mu4e--mark-seen (docid _msg target) From 6af30b5d68995b0b3e471d85fa017fb191cdf5d2 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 4 Feb 2021 12:23:39 +0800 Subject: [PATCH 081/119] Mu4e: Handle no-name from case As seen in https://www.djcbsoftware.nl/code/mu/mu4e/Message-functions.html, the name can be nil, but an address will still be present. --- modules/email/mu4e/autoload/email.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 08744e34f..d4cd80aa5 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -190,7 +190,8 @@ is tomorrow. With two prefixes, select the deadline." (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)))) + (folded-p (invisible-p (point-at-eol))) + (from (plist-get msg :from))) ;; place the subheader (when folded-p (show-branches)) ; unfold if necessary (org-end-of-meta-data) ; skip property drawer @@ -202,7 +203,7 @@ is tomorrow. With two prefixes, select the deadline." "[[mu4e:msgid:" (plist-get msg :message-id) "][" (truncate-string-to-width - (caar (plist-get msg :from)) 25 nil nil t) + (or (caar from) (cadr from)) 25 nil nil t) " - " (truncate-string-to-width (plist-get msg :subject) 40 nil nil t) From b811376403e68c5c932322fc297c2919fd812f1a Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 25 Feb 2021 18:36:08 +0800 Subject: [PATCH 082/119] Mu4e: Org-msg, add missing tab binding --- modules/email/mu4e/config.el | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 1c2298550..8526c7a7a 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -269,6 +269,9 @@ Usefull for affecting HTML export config.") (mu4e-compose-org-msg-handle-toggle (/= 1 (or toggle-p 0))) (funcall orig-fn)) + (map! :map org-msg-edit-mode-map + "TAB" #'org-msg-tab) ; only bound by default + (defvar +org-msg-accent-color "#c01c28" "Accent color to use in org-msg's generated CSS. Must be set before org-msg is loaded to take effect.") From 16fd26e5ba8cfb25a05ce3067d0ea3334dd7068f Mon Sep 17 00:00:00 2001 From: TEC Date: Mon, 5 Apr 2021 02:20:10 +0800 Subject: [PATCH 083/119] Bump org-msg jeremy-compostella/org-msg@bb378c79 -> jeremy-compostella/org-msg@89e746c Update to v3.3 of org-msg introduces ">" quotes and styling. The styling has been copied over, but the palette tweaked. --- modules/email/mu4e/config.el | 23 ++++++++++++++++++++--- modules/email/mu4e/packages.el | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 8526c7a7a..1b80bbc69 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -303,7 +303,22 @@ Must be set before org-msg is loaded to take effect.") (mapcar (lambda (mode) `(code ,(intern (concat "src src-" (symbol-name mode))) ,inline-src)) - inline-modes))) + inline-modes)) + (base-quote '((padding-left . "5px") (margin-left . "10px") + (margin-top . "20px") (margin-bottom . "0") + (font-style . "italic") (background . "#f9f9f9"))) + (quote-palette '("#6A8FBF" "#bf8f6a" "#6abf8a" "#906abf" + "#6aaebf" "#bf736a" "#bfb66a" "#bf6a94" + "#6abf9b" "#bf6a7d" "#acbf6a" "#6a74bf")) + (quotes + (mapcar (lambda (x) + (let ((c (nth x quote-palette))) + `(div ,(intern (format "quote%d" (1+ x))) + (,@base-quote + (color . ,c) + (border-left . ,(concat "3px solid " + (org-msg-lighten c))))))) + (number-sequence 0 (1- (length quote-palette)))))) `((del nil ((color . "grey") (border-left . "none") (text-decoration . "line-through") (margin-bottom . "0px") (margin-top . "10px") (line-height . "11pt"))) @@ -314,8 +329,9 @@ Must be set before org-msg is loaded to take effect.") (margin-bottom . "20px"))) (span underline ((text-decoration . "underline"))) (li nil (,line-height (margin-bottom . "0px") - (margin-top . "2px"))) - (nil org-ul ((list-style-type . "square"))) + (margin-top . "2px") + (max-width . "84ch"))) + (nil org-ul ((list-style-type . "disc"))) (nil org-ol (,@font ,line-height (margin-bottom . "0px") (margin-top . "0px") (margin-left . "30px") (padding-top . "0px") (padding-left . "5px"))) @@ -326,6 +342,7 @@ Must be set before org-msg is loaded to take effect.") (font-style . "italic") (background . "#f9f9f9"))) (p blockquote ((margin . "0") (padding . "4px 0"))) + ,@quotes (code nil (,font-size ,monospace-font (background . "#f9f9f9"))) ,@code-src (nil linenr ((padding-right . "1em") diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index 482d72d3d..e4ff3e8b4 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -2,6 +2,6 @@ ;;; email/mu4e/packages.el (when (featurep! +org) - (package! org-msg :pin "bb378c7942804b81ac9ddf4b14381cd9d84c993c")) + (package! org-msg :pin "89e746c0a864031eef940758230bc7263a6f2289")) (package! mu4e-alert :pin "91f0657c5b245a9de57aa38391221fb5d141d9bd") From 32b07003fb7b424e3d6d6c0599969183eebf9522 Mon Sep 17 00:00:00 2001 From: TEC Date: Mon, 5 Apr 2021 02:59:57 +0800 Subject: [PATCH 084/119] Mu4e: start using thread folding package It does what it says on the tin, and mu4e doesn't (currently) do this. --- modules/email/mu4e/config.el | 29 +++++++++++++++++++++++++++++ modules/email/mu4e/packages.el | 3 +++ 2 files changed, 32 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 1b80bbc69..6a316c518 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -214,6 +214,35 @@ (advice-add 'mu4e~start :around #'+mu4e-lock-start) (advice-add 'mu4e-quit :after #'+mu4e-lock-file-delete-maybe)) +(use-package! mu4e-thread-folding + :after mu4e + :config + (setq mu4e-thread-folding-root-folded-prefix-string (propertize "▶ " 'face 'shadow) + mu4e-thread-folding-root-unfolded-prefix-string (propertize "▼ " 'face 'shadow)) + (custom-set-faces! + '(mu4e-thread-folding-root-unfolded-face :weight bold :slant italic :inherit hl-line :extend t) + '(mu4e-thread-folding-child-face :inherit hl-line :extend t)) + (map! :map mu4e-headers-mode-map + :ne "" #'mu4e-headers-toggle-at-point + :ne "" #'mu4e-headers-fold-at-point + :ne "" #'mu4e-headers-fold-all + :ne "" #'mu4e-headers-unfold-at-point + :ne "" #'mu4e-headers-unfold-all) + + (when (featurep! :editor evil) + (defadvice! +mu4e-thread-folding-move-to-column-1-a (&rest _) + "Move the point to column 1. +When using evil, having the cursor at column 0 causes issues, +so we make sure that it's put a column 1 so everything works nicely." + :before #'mu4e-headers-toggle-at-point + :before #'mu4e-headers-fold-at-point + :before #'mu4e-headers-unfold-at-point + :before #'mu4e-headers-view-message + :before #'mu4e-compose-reply + :before #'mu4e-compose-forward + (unless (= (current-column) 1) + (move-to-column 1 t))))) + (unless (featurep! +org) (after! mu4e (defun org-msg-mode (&optional _) diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index e4ff3e8b4..f5da7da87 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -5,3 +5,6 @@ (package! org-msg :pin "89e746c0a864031eef940758230bc7263a6f2289")) (package! mu4e-alert :pin "91f0657c5b245a9de57aa38391221fb5d141d9bd") + +(package! mu4e-thread-folding :recipe (:host github :repo "rougier/mu4e-thread-folding") + :pin "56bb25a1addba4c6ed79c4e5d1a580d80cc698f2") From 874f140a67a8867a2637934f8958ba6c0e0ad783 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 15 Apr 2021 00:41:27 +0800 Subject: [PATCH 085/119] Mu4e: (Linux only) make audible bell configurable --- modules/email/mu4e/config.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 6a316c518..6b60bf38c 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -530,11 +530,16 @@ See `+mu4e-msg-gmail-p' and `mu4e-sent-messages-behavior'.") (when IS-LINUX (mu4e-alert-set-default-style 'libnotify) + (defvar +mu4e-alert-bell-cmd '("paplay" . "/usr/share/sounds/freedesktop/stereo/message.oga") + "Cons list with command to play a sound, and the sound file to play. +Disabled when set to nil.") + (setq mu4e-alert-email-notification-types '(subjects)) (defun +mu4e-alert-grouped-mail-notification-formatter-with-bell (mail-group _all-mails) "Default function to format MAIL-GROUP for notification. ALL-MAILS are the all the unread emails" - (shell-command "paplay /usr/share/sounds/freedesktop/stereo/message.oga") + (when +mu4e-alert-bell-cmd + (start-process (car +mu4e-alert-bell-cmd) (cdr +mu4e-alert-bell-cmd))) (if (> (length mail-group) 1) (let* ((mail-count (length mail-group)) (first-mail (car mail-group)) From eebe2859cf3eb5fbc7e2e5f345f5e00be8fba899 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 15 Apr 2021 00:50:34 +0800 Subject: [PATCH 086/119] Mu4e: Replace shell-commands with call-process Shell-process actually initialises a shell, which is completely unnecessary here. --- modules/email/mu4e/autoload/advice.el | 7 +++---- modules/email/mu4e/autoload/mu-lock.el | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/modules/email/mu4e/autoload/advice.el b/modules/email/mu4e/autoload/advice.el index 9e29527f6..fbfa64253 100644 --- a/modules/email/mu4e/autoload/advice.el +++ b/modules/email/mu4e/autoload/advice.el @@ -36,10 +36,9 @@ clicked." (list :width (format "%.1fpx" (/ (string-to-number - (shell-command-to-string - ;; TODO change to use 'file' - (format "identify -format %%w %s" - (substring img-uri 7)))) ; 7=(length "file://") + ;; TODO change to use 'file' + (doom-call-process "identify" "-format" "%w" + (substring img-uri 7))) ; 7=(length "file://") (plist-get org-format-latex-options :scale)))) (list :style (format "transform: scale(%.3f)" (/ 1.0 (plist-get org-format-latex-options :scale)))))) diff --git a/modules/email/mu4e/autoload/mu-lock.el b/modules/email/mu4e/autoload/mu-lock.el index 845844757..9f4dffeb5 100644 --- a/modules/email/mu4e/autoload/mu-lock.el +++ b/modules/email/mu4e/autoload/mu-lock.el @@ -44,7 +44,7 @@ If STRICT only accept an unset lock file." "Check `+mu4e-lock-file', and if another process is responsible for it, abort starting. Else, write to this process' PID to the lock file" (unless (+mu4e-lock-available) - (shell-command (format "touch %s" +mu4e-lock-request-file)) + (call-process "touch" nil nil nil +mu4e-lock-request-file) (message "Lock file exists, requesting that it be given up") (sleep-for 0.1) (delete-file +mu4e-lock-request-file)) From 9e0c77eeb3df3ba7a2c6bb9dc1bcb389e388316a Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 16 Apr 2021 13:19:41 +0800 Subject: [PATCH 087/119] Bump org-msg jeremy-compostella/org-msg@89e746c -> jeremy-compostella/org-msg@b9b5b4e Update to v3.4 --- modules/email/mu4e/packages.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index f5da7da87..4fc24cc8a 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -2,7 +2,7 @@ ;;; email/mu4e/packages.el (when (featurep! +org) - (package! org-msg :pin "89e746c0a864031eef940758230bc7263a6f2289")) + (package! org-msg :pin "b9b5b4ee9469969db9f150911d93b96fe84080d1")) (package! mu4e-alert :pin "91f0657c5b245a9de57aa38391221fb5d141d9bd") From e76dcb328ad878ca3578536948feff57ae3c3eb2 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 16 Apr 2021 13:21:06 +0800 Subject: [PATCH 088/119] Mu4e: lock file, use temp file var instead of /tmp --- modules/email/mu4e/autoload/mu-lock.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/autoload/mu-lock.el b/modules/email/mu4e/autoload/mu-lock.el index 9f4dffeb5..421952a49 100644 --- a/modules/email/mu4e/autoload/mu-lock.el +++ b/modules/email/mu4e/autoload/mu-lock.el @@ -1,8 +1,8 @@ ;;; email/mu4e/autoload/mu-lock.el -*- lexical-binding: t; -*- -(defvar +mu4e-lock-file "/tmp/mu4e_lock" +(defvar +mu4e-lock-file (expand-file-name "mu4e_lock" temporary-file-directory) "Location of the lock file which stores the PID of the process currenty running mu4e") -(defvar +mu4e-lock-request-file "/tmp/mu4e_lock_request" +(defvar +mu4e-lock-request-file (expand-file-name "mu4e_lock_request" temporary-file-directory) "Location of the lock file for which creating indicated that another process wants the lock to be released") (defvar +mu4e-lock-greedy nil From d78cdc9a22701ffcc49fa84c3a6d4ee9fb588389 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 16 Apr 2021 13:21:55 +0800 Subject: [PATCH 089/119] Mu4e: Mask mu4e signature when composing org-msg --- modules/email/mu4e/config.el | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 6b60bf38c..852ceaaee 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -298,6 +298,12 @@ Usefull for affecting HTML export config.") (mu4e-compose-org-msg-handle-toggle (/= 1 (or toggle-p 0))) (funcall orig-fn)) + (defadvice! mu4e-draft-open-signature-a (orig-fn compose-type &optional msg) + "Prevent `mu4e-compose-signature' from being used with `org-msg-mode'." + :around #'mu4e-draft-open + (let ((mu4e-compose-signature (unless org-msg-mode mu4e-compose-signature))) + (funcall orig-fn compose-type msg))) + (map! :map org-msg-edit-mode-map "TAB" #'org-msg-tab) ; only bound by default From 2e49b16a6dd1d4ba65b7f8d74d79194090e4406e Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 16 Apr 2021 13:22:40 +0800 Subject: [PATCH 090/119] Mu4e: When only one personal addr is set, use it No need to prompt when there's a single entry in +mu4e-personal-addresses. --- modules/email/mu4e/autoload/email.el | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index d4cd80aa5..58a5fac5c 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -346,10 +346,12 @@ with the current context." (setq user-mail-address from) nil)))) (setq user-mail-address - (completing-read - "From: " - (if-let ((context-addresses - (when mu4e~context-current - (alist-get '+mu4e-personal-addresses (mu4e-context-vars mu4e~context-current))))) - context-addresses - (mu4e-personal-addresses)))))) + (if (= (length +mu4e-personal-addresses) 1) + (car +mu4e-personal-addresses) + (completing-read + "From: " + (if-let ((context-addresses + (when mu4e~context-current + (alist-get '+mu4e-personal-addresses (mu4e-context-vars mu4e~context-current))))) + context-addresses + (mu4e-personal-addresses))))))) From f49c7e6281556dd823b00c1fd4b3da3e8a3ebbef Mon Sep 17 00:00:00 2001 From: TEC Date: Mon, 26 Apr 2021 12:04:16 +0800 Subject: [PATCH 091/119] Mu4e: set attachment dir to user download folder --- modules/email/mu4e/config.el | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 852ceaaee..f6a9f05f3 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -51,6 +51,10 @@ ((featurep! :completion helm) #'completing-read) ((featurep! :completion vertico) #'completing-read) (t #'ido-completing-read)) + mu4e-attachment-dir + (expand-file-name (or (getenv "XDG_DOWNLOAD_DIR") + "Downloads") + "~") ;; no need to ask mu4e-confirm-quit nil mu4e-headers-thread-single-orphan-prefix '("─>" . "─▶") From e881ced14309a1576f2f4a8fe4434e8686166305 Mon Sep 17 00:00:00 2001 From: TEC Date: Mon, 26 Apr 2021 12:10:53 +0800 Subject: [PATCH 092/119] Mu4e: Improve the +mu4e/attach-files docstring --- modules/email/mu4e/autoload/email.el | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 58a5fac5c..b6689e50c 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -235,10 +235,11 @@ is tomorrow. With two prefixes, select the deadline." ;;;###autoload (defun +mu4e/attach-files (&optional files-to-attach) "When called in a dired buffer, ask for a message to attach the marked files to. -When called in a mu4e:compose or org-msg buffer, open a dired window to select file attachments in, -and enable `dired-mu4e-attach-ctrl-c-ctrl-c' which adds C-c C-c as a keybinding to attach the files. +When called in a mu4e:compose or org-msg buffer, `read-file-name'to either +attach a file, or select a folder to open dired in and select file attachments +(using `dired-mu4e-attach-ctrl-c-ctrl-c'). -When otherwise called, open a dired buffer." +When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c-ctrl-c'." ;; TODO add ability to attach files (+dirs) as a single (named) archive (interactive "p") (mu4e-compose-org-msg-handle-toggle (/= 1 files-to-attach)) From fadc5f1b352d5b08f15f68aaf135967939421c3f Mon Sep 17 00:00:00 2001 From: TEC Date: Mon, 26 Apr 2021 12:11:28 +0800 Subject: [PATCH 093/119] Mu4e: Add header line to dired buff when attaching --- modules/email/mu4e/autoload/email.el | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index b6689e50c..7aab501b3 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -300,7 +300,11 @@ When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c- :lighter "attach" :keymap (let ((map (make-sparse-keymap))) (define-key map (kbd "C-c C-c") '+mu4e/attach-files) - map)) + map) + (setq header-line-format + (when dired-mu4e-attach-ctrl-c-ctrl-c + (substitute-command-keys + "Mu4e attach active. `\\[+mu4e/attach-files]' to attach the marked files.")))) ;;;###autoload (defun +mu4e-current-buffers () From bfa888ced313e6f44aadb0c21d6e20e46b1ad598 Mon Sep 17 00:00:00 2001 From: TEC Date: Tue, 18 May 2021 00:06:46 +0800 Subject: [PATCH 094/119] Mu4e: Remove duplicated alert mode line call --- modules/email/mu4e/config.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index f6a9f05f3..ebc414fa8 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -584,6 +584,4 @@ ALL-MAILS are the all the unread emails" (subject (plist-get new-mail :subject)) (sender (caar (plist-get new-mail :from)))) (list :title sender :body subject)))) - (setq mu4e-alert-grouped-mail-notification-formatter #'+mu4e-alert-grouped-mail-notification-formatter-with-bell)) - - (mu4e-alert-enable-mode-line-display)) + (setq mu4e-alert-grouped-mail-notification-formatter #'+mu4e-alert-grouped-mail-notification-formatter-with-bell))) From 3778862a798306d14be27ef357db09059e545e4f Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 19 Jun 2021 03:20:50 +0800 Subject: [PATCH 095/119] mu4e: lock file may not be created by file watcher On some OS implementations (e.g. BSD uses kqueue), `file-notify-add-watch' might not create the file if it doesn't exist. This patch fixes that error. Arguably, emacs lisp should ensure the same behaviour exists across each implementation. --- modules/email/mu4e/autoload/mu-lock.el | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/email/mu4e/autoload/mu-lock.el b/modules/email/mu4e/autoload/mu-lock.el index 421952a49..c34329d6a 100644 --- a/modules/email/mu4e/autoload/mu-lock.el +++ b/modules/email/mu4e/autoload/mu-lock.el @@ -52,6 +52,7 @@ Else, write to this process' PID to the lock file" (user-error "Unfortunately another Emacs is already doing stuff with Mu4e, and you can only have one at a time") (write-region (number-to-string (emacs-pid)) nil +mu4e-lock-file) (delete-file +mu4e-lock-request-file) + (call-process "touch" nil nil nil +mu4e-lock-request-file) (funcall orig-fun callback) (setq +mu4e-lock--request-watcher (file-notify-add-watch +mu4e-lock-request-file From 8603a3c7d24517c16e37938af249ecb0e400494b Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 19 Jun 2021 03:22:53 +0800 Subject: [PATCH 096/119] mu4e: also prettify key-val string in main view --- modules/email/mu4e/autoload/advice.el | 5 +++++ modules/email/mu4e/config.el | 1 + 2 files changed, 6 insertions(+) diff --git a/modules/email/mu4e/autoload/advice.el b/modules/email/mu4e/autoload/advice.el index fbfa64253..191e8e921 100644 --- a/modules/email/mu4e/autoload/advice.el +++ b/modules/email/mu4e/autoload/advice.el @@ -27,6 +27,11 @@ clicked." (- (length newstr) 1) 'mouse-face 'highlight newstr) newstr)) +;;;###autoload +(defun +mu4e~main-keyval-str-prettier-a (str) + "Replace '*' with '⚫' in STR." + (replace-regexp-in-string "\t\\*" "\t⚫" str)) + ;; Org msg LaTeX image scaling ;;;###autoload diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index ebc414fa8..1012e771f 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -203,6 +203,7 @@ (add-hook 'mu4e-compose-pre-hook '+mu4e-set-from-address-h) + (advice-add #'mu4e~key-val :filter-return #'+mu4e~main-keyval-str-prettier-a) (advice-add #'mu4e~main-action-str :override #'+mu4e~main-action-str-prettier-a) (when (featurep! :editor evil) ;; As +mu4e~main-action-str-prettier replaces [k]ey with key q]uit should become quit From c9e816e9950d6fe9d49ba47d856523d091e89361 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 19 Jun 2021 03:28:25 +0800 Subject: [PATCH 097/119] Bump org-msg jeremy-compostella/org-msg@b9b5b4e -> jeremy-compostella/org-msg@4c92c62 Update to v3.8 --- modules/email/mu4e/packages.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index 4fc24cc8a..3215f5928 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -2,7 +2,7 @@ ;;; email/mu4e/packages.el (when (featurep! +org) - (package! org-msg :pin "b9b5b4ee9469969db9f150911d93b96fe84080d1")) + (package! org-msg :pin "4c92c627b6cfb234fd257b714a5dbfc72d7af8d2")) (package! mu4e-alert :pin "91f0657c5b245a9de57aa38391221fb5d141d9bd") From a72d533a24f8a17a187ddb9044658e41826675e0 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 24 Jun 2021 12:23:52 +0800 Subject: [PATCH 098/119] Mu4e: Fix inline LaTeX image scaling The structure of doom-call-process's return had changed. --- modules/email/mu4e/autoload/advice.el | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/modules/email/mu4e/autoload/advice.el b/modules/email/mu4e/autoload/advice.el index 191e8e921..c5ed2fddb 100644 --- a/modules/email/mu4e/autoload/advice.el +++ b/modules/email/mu4e/autoload/advice.el @@ -38,13 +38,14 @@ clicked." (defun +org-msg-img-scale-css (img-uri) "For a given IMG-URI, use imagemagik to find its width." (if +org-msg-currently-exporting - (list :width - (format "%.1fpx" - (/ (string-to-number - ;; TODO change to use 'file' - (doom-call-process "identify" "-format" "%w" - (substring img-uri 7))) ; 7=(length "file://") - (plist-get org-format-latex-options :scale)))) + ;; TODO change to use 'file' (NB: would only work for PNG though, apparently) + (let ((width-call (doom-call-process "identify" "-format" "%w" + (substring img-uri 7)))) ; 7=(length "file://") + (when (= (car width-call) 0) + (list :width + (format "%.1fpx" + (/ (string-to-number (cdr width-call)) + (plist-get org-format-latex-options :scale)))))) (list :style (format "transform: scale(%.3f)" (/ 1.0 (plist-get org-format-latex-options :scale)))))) From 695a67078504566642cf2ae71afaacb4f6a6ce98 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 23 Jul 2021 02:20:57 +0800 Subject: [PATCH 099/119] Bump mu4e-thread-folding rougier/mu4e-thread-folding@56bb25a -> rougier/mu4e-thread-folding@c691558 It would be good to get some bug fixes. --- modules/email/mu4e/packages.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index 3215f5928..6d8b6f047 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -7,4 +7,4 @@ (package! mu4e-alert :pin "91f0657c5b245a9de57aa38391221fb5d141d9bd") (package! mu4e-thread-folding :recipe (:host github :repo "rougier/mu4e-thread-folding") - :pin "56bb25a1addba4c6ed79c4e5d1a580d80cc698f2") + :pin "c6915585263a744b4da4a0e334393150603136dc") From e5c8cb747b5a64f044a2b001a61de2b473ced434 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 23 Jul 2021 02:48:39 +0800 Subject: [PATCH 100/119] Mu4e: Remove spurious autoloads None of these functions are called outside the file they're defined in. --- modules/email/mu4e/autoload/email.el | 8 -------- modules/email/mu4e/autoload/mu-lock.el | 5 ----- 2 files changed, 13 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 7aab501b3..965cc6570 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -77,9 +77,6 @@ default/fallback account." ;; TODO Interactively select email account (call-interactively #'mu4e-compose-new)) -;; Icons need a bit of work -;; Spacing needs to be determined and adjucted -;;;###autoload (defun +mu4e--get-string-width (str) "Return the width in pixels of a string in the current window's default font. If the font is mono-spaced, this @@ -93,7 +90,6 @@ will also be the width of all other printable characters." (insert str) (car (window-text-pixel-size))))) -;;;###autoload (cl-defun +mu4e-normalised-icon (name &key set color height v-adjust) "Convert :icon declaration to icon" (let* ((icon-set (intern (concat "all-the-icons-" (or set "faicon")))) @@ -123,7 +119,6 @@ will also be the width of all other printable characters." mu4e-headers-signed-mark (cons "s" (+mu4e-normalised-icon "certificate" :height 0.7 :color "dpurple")) mu4e-headers-unread-mark (cons "u" (+mu4e-normalised-icon "eye-slash" :v-adjust 0.05)))) -;;;###autoload (defun +mu4e-colorize-str (str &optional unique herring) "Apply a face from `+mu4e-header-colorized-faces' to STR. If HERRING is set, it will be used to determine the face instead of STR. @@ -155,7 +150,6 @@ a quoted symbol for a alist of current strings and faces provided." str) str) -;;;###autoload (defun +mu4e--str-color-face (str &optional offset) "Select a face from `+mu4e-header-colorized-faces' based on STR and any integer OFFSET." @@ -294,7 +288,6 @@ When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c- (with-current-buffer (call-interactively #'find-file) (dired-mu4e-attach-ctrl-c-ctrl-c 1))))) -;;;###autoload (define-minor-mode dired-mu4e-attach-ctrl-c-ctrl-c "Adds C-c C-c as an keybinding to attach files to a message." :lighter "attach" @@ -306,7 +299,6 @@ When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c- (substitute-command-keys "Mu4e attach active. `\\[+mu4e/attach-files]' to attach the marked files.")))) -;;;###autoload (defun +mu4e-current-buffers () "Return a list of active message buffers." (let (buffers) diff --git a/modules/email/mu4e/autoload/mu-lock.el b/modules/email/mu4e/autoload/mu-lock.el index c34329d6a..34ec9c476 100644 --- a/modules/email/mu4e/autoload/mu-lock.el +++ b/modules/email/mu4e/autoload/mu-lock.el @@ -10,7 +10,6 @@ (defvar +mu4e-lock-relaxed t "Whether if someone else wants the lock (signaled via `+mu4e-lock-request-file'), we should stop Mu4e and let go of it") -;;;###autoload (defun +mu4e-lock-pid-info () "Get info on the PID refered to in `+mu4e-lock-file' in the form (pid . process-attributes) If the file or process do not exist, the lock file is deleted an nil returned." @@ -24,7 +23,6 @@ (if process (cons pid process) (delete-file +mu4e-lock-file) nil)))) -;;;###autoload (defun +mu4e-lock-available (&optional strict) "If the `+mu4e-lock-file' is available (unset or owned by this emacs) return t. If STRICT only accept an unset lock file." @@ -63,7 +61,6 @@ Else, write to this process' PID to the lock file" (defvar +mu4e-lock--file-just-deleted nil) (defvar +mu4e-lock--request-watcher nil) -;;;###autoload (defun +mu4e-lock-add-watcher () (setq +mu4e-lock--file-just-deleted nil) (file-notify-rm-watch +mu4e-lock--file-watcher) @@ -72,7 +69,6 @@ Else, write to this process' PID to the lock file" '(change) #'+mu4e-lock-file-updated))) -;;;###autoload (defun +mu4e-lock-request (event) "Handle another process requesting the Mu4e lock." (when (equal (nth 1 event) 'created) @@ -84,7 +80,6 @@ Else, write to this process' PID to the lock file" (run-at-time 0.2 nil #'+mu4e-lock-add-watcher)) (delete-file +mu4e-lock-request-file))) -;;;###autoload (defun +mu4e-lock-file-updated (event) (if +mu4e-lock--file-just-deleted (+mu4e-lock-add-watcher) From 921157f8d762d4f9be6ddb5a39acf063c37aff5b Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 23 Jul 2021 03:00:29 +0800 Subject: [PATCH 101/119] Mu4e: Remove redundant check in cond statement The `t' case is already handled in the preceding condition. --- modules/email/mu4e/autoload/advice.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/autoload/advice.el b/modules/email/mu4e/autoload/advice.el index c5ed2fddb..1016ad19b 100644 --- a/modules/email/mu4e/autoload/advice.el +++ b/modules/email/mu4e/autoload/advice.el @@ -63,7 +63,7 @@ account for the value of :scale in `org-format-latex-options'." (cond ((memq processing-type '(t mathjax)) (org-html-format-latex latex-frag 'mathjax info)) - ((memq processing-type '(t html)) + ((eq processing-type 'html) (org-html-format-latex latex-frag 'html info)) ((assq processing-type org-preview-latex-process-alist) (let ((formula-link From b20b233986ce72f38f312b6b538656030a65ed69 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 23 Jul 2021 03:17:34 +0800 Subject: [PATCH 102/119] Mu4e: Avoid making assumptions about defuns result It's not guaranteed that `defun' will return the new function symbol, but add-hook! works around this. --- modules/email/mu4e/config.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 1012e771f..4cf161ed1 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -87,7 +87,7 @@ (if (display-graphic-p) (+mu4e-initialise-icons) ;; When it's the server, wait till the first graphical frame - (add-hook + (add-hook! 'server-after-make-frame-hook (defun +mu4e-initialise-icons-hook () (when (display-graphic-p) From abe2ac28c08c23b7f0def83f258966529a1c7486 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 23 Jul 2021 03:20:22 +0800 Subject: [PATCH 103/119] Mu4e: Replace stray setq with defvar and docstring --- modules/email/mu4e/config.el | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 4cf161ed1..4ecbe0b3c 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -99,13 +99,15 @@ (add-to-list 'mu4e-bookmarks '(:name "Flagged messages" :query "flag:flagged" :key ?f) t) - (setq +mu4e-header-colorized-faces - '(all-the-icons-green - all-the-icons-lblue - all-the-icons-purple-alt - all-the-icons-blue-alt - all-the-icons-purple - all-the-icons-yellow)) + ;; TODO avoid assuming that all-the-icons is present + (defvar +mu4e-header-colorized-faces + '(all-the-icons-green + all-the-icons-lblue + all-the-icons-purple-alt + all-the-icons-blue-alt + all-the-icons-purple + all-the-icons-yellow) + "Faces to use when coloring folders and account stripes.") ;; Add a column to display what email account the email belongs to, ;; and an account color stripe column From a4db56be2f214c12377c0985a1902422d98c8032 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 23 Jul 2021 03:22:36 +0800 Subject: [PATCH 104/119] Mu4e: Confirm that lockfile pid is an emacs proc Or else another app can be given the same PID and we'll be complaining another Emacs process is using mu4e when that simply isn't true. --- modules/email/mu4e/autoload/mu-lock.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/autoload/mu-lock.el b/modules/email/mu4e/autoload/mu-lock.el index 34ec9c476..f0b0bc673 100644 --- a/modules/email/mu4e/autoload/mu-lock.el +++ b/modules/email/mu4e/autoload/mu-lock.el @@ -20,7 +20,8 @@ (insert-file-contents +mu4e-lock-file) (buffer-string)))) (process (process-attributes pid))) - (if process (cons pid process) + (if (and process (string-match-p "emacs" (alist-get 'args process))) + (cons pid process) (delete-file +mu4e-lock-file) nil)))) (defun +mu4e-lock-available (&optional strict) From a39f7b0cedd1ec08c86e01af0cda0b87e981ffb1 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 29 Jul 2021 17:58:12 +0800 Subject: [PATCH 105/119] Mu4e: Don't set gnus/message face, leave to themes --- modules/email/mu4e/config.el | 9 --------- 1 file changed, 9 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 4ecbe0b3c..72f08f3df 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -74,15 +74,6 @@ (setq mail-user-agent 'mu4e-user-agent message-mail-user-agent 'mu4e-user-agent) - ;; Make reply coloring consistant, and striped for readability - (custom-set-faces! - '(gnus-cite-2 :foreground nil :inherit gnus-cite-10) - '(gnus-cite-3 :foreground nil :inherit gnus-cite-7) - '(message-cited-text-1 :foreground nil :inherit gnus-cite-1) - '(message-cited-text-2 :foreground nil :inherit gnus-cite-2) - '(message-cited-text-3 :foreground nil :inherit gnus-cite-3) - '(message-cited-text-4 :foreground nil :inherit gnus-cite-4)) - ;; Set the icons only when a graphical frame has been created (if (display-graphic-p) (+mu4e-initialise-icons) From 59178f2d7190a8aebeeccd73832bb31f57e4b08f Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 29 Jul 2021 17:58:54 +0800 Subject: [PATCH 106/119] Mu4e: Relocate min-frames-width statement --- modules/email/mu4e/config.el | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 72f08f3df..ff1375ae9 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -100,6 +100,9 @@ all-the-icons-yellow) "Faces to use when coloring folders and account stripes.") + (defvar +mu4e-min-header-frame-width 120 + "Minimum reasonable with for the header view.") + ;; Add a column to display what email account the email belongs to, ;; and an account color stripe column (defvar +mu4e-header--maildir-colors nil) @@ -160,8 +163,6 @@ ;; actually show you all the information you want to see ;; so if the header view is entered from a narrow frame, ;; it's probably worth trying to expand it - (defvar +mu4e-min-header-frame-width 120 - "Minimum reasonable with for the header view.") (defun mu4e-widen-frame-maybe () "Expand the frame with if it's less than `+mu4e-min-header-frame-width'." (when (< (frame-width) +mu4e-min-header-frame-width) From 6fae5ea3179a682103300385a1c4921687343727 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 29 Jul 2021 18:50:39 +0800 Subject: [PATCH 107/119] Mu4e: extend org-msg application to plaintext Recently org-msg gained the capability to change which exports/mime types are sent based on the email, and a new utf-8 type. We will make use of both of these additions. --- modules/email/mu4e/config.el | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index ff1375ae9..d87f716e5 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -259,7 +259,9 @@ Ignores all arguments and returns nil." (setq org-msg-options "html-postamble:nil H:5 num:nil ^:{} toc:nil author:nil email:nil tex:dvipng" org-msg-startup "hidestars indent inlineimages" org-msg-greeting-name-limit 3 - org-msg-default-alternatives '(text html) + org-msg-default-alternatives '((new . (utf-8 html)) + (reply-to-text . (utf-8)) + (reply-to-html . (utf-8 html))) org-msg-convert-citation t) (defvar +org-msg-currently-exporting nil From fe5e410b74ca1c267d64ddb644d0f0ff47c1d412 Mon Sep 17 00:00:00 2001 From: TEC Date: Thu, 29 Jul 2021 18:55:58 +0800 Subject: [PATCH 108/119] Mu4e: thread folding is too buggy, remove for now I bumped to get bugfixes and got more bugs. If the situation improves in future maybe we could add this back in. --- modules/email/mu4e/config.el | 29 ----------------------------- modules/email/mu4e/packages.el | 3 --- 2 files changed, 32 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index d87f716e5..90e95d8c8 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -213,35 +213,6 @@ (advice-add 'mu4e~start :around #'+mu4e-lock-start) (advice-add 'mu4e-quit :after #'+mu4e-lock-file-delete-maybe)) -(use-package! mu4e-thread-folding - :after mu4e - :config - (setq mu4e-thread-folding-root-folded-prefix-string (propertize "▶ " 'face 'shadow) - mu4e-thread-folding-root-unfolded-prefix-string (propertize "▼ " 'face 'shadow)) - (custom-set-faces! - '(mu4e-thread-folding-root-unfolded-face :weight bold :slant italic :inherit hl-line :extend t) - '(mu4e-thread-folding-child-face :inherit hl-line :extend t)) - (map! :map mu4e-headers-mode-map - :ne "" #'mu4e-headers-toggle-at-point - :ne "" #'mu4e-headers-fold-at-point - :ne "" #'mu4e-headers-fold-all - :ne "" #'mu4e-headers-unfold-at-point - :ne "" #'mu4e-headers-unfold-all) - - (when (featurep! :editor evil) - (defadvice! +mu4e-thread-folding-move-to-column-1-a (&rest _) - "Move the point to column 1. -When using evil, having the cursor at column 0 causes issues, -so we make sure that it's put a column 1 so everything works nicely." - :before #'mu4e-headers-toggle-at-point - :before #'mu4e-headers-fold-at-point - :before #'mu4e-headers-unfold-at-point - :before #'mu4e-headers-view-message - :before #'mu4e-compose-reply - :before #'mu4e-compose-forward - (unless (= (current-column) 1) - (move-to-column 1 t))))) - (unless (featurep! +org) (after! mu4e (defun org-msg-mode (&optional _) diff --git a/modules/email/mu4e/packages.el b/modules/email/mu4e/packages.el index 6d8b6f047..883596a8b 100644 --- a/modules/email/mu4e/packages.el +++ b/modules/email/mu4e/packages.el @@ -5,6 +5,3 @@ (package! org-msg :pin "4c92c627b6cfb234fd257b714a5dbfc72d7af8d2")) (package! mu4e-alert :pin "91f0657c5b245a9de57aa38391221fb5d141d9bd") - -(package! mu4e-thread-folding :recipe (:host github :repo "rougier/mu4e-thread-folding") - :pin "c6915585263a744b4da4a0e334393150603136dc") From 7e1f7915c0bcefb2794bf19f3ef4ec33c9c4f112 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 30 Jul 2021 01:49:18 +0800 Subject: [PATCH 109/119] Mu4e: use file when imagemagik not present We will also use this as an opportunity to clean up the use of +org-msg-img-scale-css. --- modules/email/mu4e/autoload/advice.el | 46 +++++++++++++++------------ 1 file changed, 25 insertions(+), 21 deletions(-) diff --git a/modules/email/mu4e/autoload/advice.el b/modules/email/mu4e/autoload/advice.el index 1016ad19b..eb1acb6d1 100644 --- a/modules/email/mu4e/autoload/advice.el +++ b/modules/email/mu4e/autoload/advice.el @@ -38,14 +38,19 @@ clicked." (defun +org-msg-img-scale-css (img-uri) "For a given IMG-URI, use imagemagik to find its width." (if +org-msg-currently-exporting - ;; TODO change to use 'file' (NB: would only work for PNG though, apparently) - (let ((width-call (doom-call-process "identify" "-format" "%w" - (substring img-uri 7)))) ; 7=(length "file://") - (when (= (car width-call) 0) - (list :width - (format "%.1fpx" - (/ (string-to-number (cdr width-call)) - (plist-get org-format-latex-options :scale)))))) + (when (and (not IS-WINDOWS)) ; relies on posix path + (let ((with-call (and (executable-find "identify") + (doom-call-process "identify" "-format" "%w" + (substring img-uri 7))))) ; 7=(length "file://") + (unless width-call + (setq width-call (doom-call-process "file" (substring img-uri 7))) + (setcdr width-call (replace-regexp-in-string "^.*image data, \\([0-9]+\\).*$" "\\1" (cdr width-call))) + (setcar width-call (if (< 0 (string-to-number (cdr width-call))) 0 1))) + (when (= (car width-call) 0) + (list :width + (format "%.1fpx" + (/ (string-to-number (cdr width-call)) + (plist-get org-format-latex-options :scale))))))) (list :style (format "transform: scale(%.3f)" (/ 1.0 (plist-get org-format-latex-options :scale)))))) @@ -70,14 +75,13 @@ account for the value of :scale in `org-format-latex-options'." (org-html-format-latex latex-frag processing-type info))) (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) (let ((source (org-export-file-uri (match-string 1 formula-link))) - (attributes (list :alt latex-frag - :class (concat "latex-fragment-" - (if (equal "\\(" (substring latex-frag 0 2)) - "inline" "block"))))) - (when (and (memq processing-type '(dvipng convert)) - (not IS-WINDOWS) ; relies on posix path - (executable-find "identify")) - (apply #'plist-put attributes (+org-msg-img-scale-css source))) + (attributes (append (list :alt latex-frag + :class + (concat "latex-fragment-" + (if (equal "\\(" (substring latex-frag 0 2)) + "inline" "block"))) + (when (memq processing-type '(dvipng convert)) + (+org-msg-img-scale-css source))))) (org-html--format-image source attributes info))))) (t latex-frag)))) @@ -118,11 +122,11 @@ scales the image to account for the value of :scale in `org-format-latex-options processing-type info))) (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) (let ((source (org-export-file-uri (match-string 1 formula-link)))) - (when (and (memq processing-type '(dvipng convert)) - (not IS-WINDOWS) ; relies on posix path - (executable-find "identify")) - (apply #'plist-put attributes (+org-msg-img-scale-css source))) (org-html--wrap-latex-environment - (org-html--format-image source attributes info) + (org-html--format-image source + (append attributes + (when (memq processing-type '(dvipng convert)) + (+org-msg-img-scale-css source))) + info) info caption label))))) (t (org-html--wrap-latex-environment latex-frag info caption label))))) From 2efeaa3bf2d2ec839c6ff5554452703d67675ad6 Mon Sep 17 00:00:00 2001 From: TEC Date: Fri, 30 Jul 2021 01:55:53 +0800 Subject: [PATCH 110/119] Mu4e: re-indent advice.el and fix docstring typo --- modules/email/mu4e/autoload/advice.el | 126 +++++++++++++------------- modules/email/mu4e/autoload/email.el | 2 +- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/modules/email/mu4e/autoload/advice.el b/modules/email/mu4e/autoload/advice.el index eb1acb6d1..d4474e0e8 100644 --- a/modules/email/mu4e/autoload/advice.el +++ b/modules/email/mu4e/autoload/advice.el @@ -55,78 +55,78 @@ clicked." (/ 1.0 (plist-get org-format-latex-options :scale)))))) ;;;###autoload -(defun +org-html-latex-fragment-scaled-a (latex-fragment _contents info) - "Transcode a LATEX-FRAGMENT object from Org to HTML. + (defun +org-html-latex-fragment-scaled-a (latex-fragment _contents info) + "Transcode a LATEX-FRAGMENT object from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information. This differs from `org-html-latex-fragment' in that it uses the LaTeX fragment as a meaningful alt value, applies a class to indicate what sort of fragment it is (latex-fragment-inline or latex-fragment-block), and (on Linux) scales the image to account for the value of :scale in `org-format-latex-options'." - (let ((latex-frag (org-element-property :value latex-fragment)) - (processing-type (plist-get info :with-latex))) - (cond - ((memq processing-type '(t mathjax)) - (org-html-format-latex latex-frag 'mathjax info)) - ((eq processing-type 'html) - (org-html-format-latex latex-frag 'html info)) - ((assq processing-type org-preview-latex-process-alist) - (let ((formula-link - (org-html-format-latex latex-frag processing-type info))) - (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) - (let ((source (org-export-file-uri (match-string 1 formula-link))) - (attributes (append (list :alt latex-frag - :class - (concat "latex-fragment-" - (if (equal "\\(" (substring latex-frag 0 2)) - "inline" "block"))) - (when (memq processing-type '(dvipng convert)) - (+org-msg-img-scale-css source))))) - (org-html--format-image source attributes info))))) - (t latex-frag)))) + (let ((latex-frag (org-element-property :value latex-fragment)) + (processing-type (plist-get info :with-latex))) + (cond + ((memq processing-type '(t mathjax)) + (org-html-format-latex latex-frag 'mathjax info)) + ((eq processing-type 'html) + (org-html-format-latex latex-frag 'html info)) + ((assq processing-type org-preview-latex-process-alist) + (let ((formula-link + (org-html-format-latex latex-frag processing-type info))) + (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) + (let ((source (org-export-file-uri (match-string 1 formula-link))) + (attributes (append (list :alt latex-frag + :class + (concat "latex-fragment-" + (if (equal "\\(" (substring latex-frag 0 2)) + "inline" "block"))) + (when (memq processing-type '(dvipng convert)) + (+org-msg-img-scale-css source))))) + (org-html--format-image source attributes info))))) + (t latex-frag)))) ;;;###autoload -(defun +org-html-latex-environment-scaled-a (latex-environment _contents info) - "Transcode a LATEX-ENVIRONMENT element from Org to HTML. + (defun +org-html-latex-environment-scaled-a (latex-environment _contents info) + "Transcode a LATEX-ENVIRONMENT element from Org to HTML. CONTENTS is nil. INFO is a plist holding contextual information. This differs from `org-html-latex-environment' in that (on Linux) it scales the image to account for the value of :scale in `org-format-latex-options'." - (let ((processing-type (plist-get info :with-latex)) - (latex-frag (org-remove-indentation - (org-element-property :value latex-environment))) - (attributes (org-export-read-attribute :attr_html latex-environment)) - (label (and (org-element-property :name latex-environment) - (org-export-get-reference latex-environment info))) - (caption (and (org-html--latex-environment-numbered-p latex-environment) - (number-to-string - (org-export-get-ordinal - latex-environment info nil - (lambda (l _) - (and (org-html--math-environment-p l) - (org-html--latex-environment-numbered-p l)))))))) - (plist-put attributes :class "latex-environment") - (cond - ((memq processing-type '(t mathjax)) - (org-html-format-latex - (if (org-string-nw-p label) - (replace-regexp-in-string "\\`.*" - (format "\\&\n\\\\label{%s}" label) - latex-frag) - latex-frag) - 'mathjax info)) - ((assq processing-type org-preview-latex-process-alist) - (let ((formula-link - (org-html-format-latex - (org-html--unlabel-latex-environment latex-frag) - processing-type info))) - (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) - (let ((source (org-export-file-uri (match-string 1 formula-link)))) - (org-html--wrap-latex-environment - (org-html--format-image source - (append attributes - (when (memq processing-type '(dvipng convert)) - (+org-msg-img-scale-css source))) - info) - info caption label))))) - (t (org-html--wrap-latex-environment latex-frag info caption label))))) + (let ((processing-type (plist-get info :with-latex)) + (latex-frag (org-remove-indentation + (org-element-property :value latex-environment))) + (attributes (org-export-read-attribute :attr_html latex-environment)) + (label (and (org-element-property :name latex-environment) + (org-export-get-reference latex-environment info))) + (caption (and (org-html--latex-environment-numbered-p latex-environment) + (number-to-string + (org-export-get-ordinal + latex-environment info nil + (lambda (l _) + (and (org-html--math-environment-p l) + (org-html--latex-environment-numbered-p l)))))))) + (plist-put attributes :class "latex-environment") + (cond + ((memq processing-type '(t mathjax)) + (org-html-format-latex + (if (org-string-nw-p label) + (replace-regexp-in-string "\\`.*" + (format "\\&\n\\\\label{%s}" label) + latex-frag) + latex-frag) + 'mathjax info)) + ((assq processing-type org-preview-latex-process-alist) + (let ((formula-link + (org-html-format-latex + (org-html--unlabel-latex-environment latex-frag) + processing-type info))) + (when (and formula-link (string-match "file:\\([^]]*\\)" formula-link)) + (let ((source (org-export-file-uri (match-string 1 formula-link)))) + (org-html--wrap-latex-environment + (org-html--format-image source + (append attributes + (when (memq processing-type '(dvipng convert)) + (+org-msg-img-scale-css source))) + info) + info caption label))))) + (t (org-html--wrap-latex-environment latex-frag info caption label))))) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 965cc6570..4f391100b 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -289,7 +289,7 @@ When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c- (dired-mu4e-attach-ctrl-c-ctrl-c 1))))) (define-minor-mode dired-mu4e-attach-ctrl-c-ctrl-c - "Adds C-c C-c as an keybinding to attach files to a message." + "Adds C-c C-c as a keybinding to attach files to a message." :lighter "attach" :keymap (let ((map (make-sparse-keymap))) (define-key map (kbd "C-c C-c") '+mu4e/attach-files) From 95971d2dc7d147041bd4f07937888c73e2ae5821 Mon Sep 17 00:00:00 2001 From: Liam Hupfer Date: Sat, 10 Jul 2021 13:43:26 -0500 Subject: [PATCH 111/119] Mu4e: Add xdg-user-dir directory finding method --- modules/email/mu4e/config.el | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 90e95d8c8..90b2419e3 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -52,9 +52,12 @@ ((featurep! :completion vertico) #'completing-read) (t #'ido-completing-read)) mu4e-attachment-dir - (expand-file-name (or (getenv "XDG_DOWNLOAD_DIR") - "Downloads") - "~") + (if (executable-find "xdg-user-dir") + ;; remove trailing newline + (substring (shell-command-to-string "xdg-user-dir DOWNLOAD") 0 -1) + (expand-file-name (or (getenv "XDG_DOWNLOAD_DIR") + "Downloads") + "~")) ;; no need to ask mu4e-confirm-quit nil mu4e-headers-thread-single-orphan-prefix '("─>" . "─▶") From 3d54471b2ad3df595855d7053a70646faea1a475 Mon Sep 17 00:00:00 2001 From: Liam Hupfer Date: Sat, 10 Jul 2021 13:50:20 -0500 Subject: [PATCH 112/119] Mu4e: Fix setting default context The default-p argument to `set-email-account!` now works as intended. mu4e checks the first context on startup to determine the default and uses functions for that, so we can't really get around it by setting the bare mu4e~context-current variable. --- modules/email/mu4e/autoload/email.el | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 4f391100b..ed0094f0d 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -23,6 +23,7 @@ default/fallback account." (when (version< mu4e-mu-version "1.4") (when-let (address (cdr (assq 'user-mail-address letvars))) (add-to-list 'mu4e-user-mail-address-list address))) + ;; remove existing context with same label (setq mu4e-contexts (cl-loop for context in mu4e-contexts unless (string= (mu4e-context-name context) label) @@ -37,9 +38,7 @@ default/fallback account." (string-prefix-p (format "/%s" label) (mu4e-message-field msg :maildir)))) :vars letvars))) - (push context mu4e-contexts) - (when default-p - (setq-default mu4e-context-current context)) + (add-to-list 'mu4e-contexts context (not default-p)) context))) From a75dea62819407770385f647a4d30e497208d6ce Mon Sep 17 00:00:00 2001 From: Liam Hupfer Date: Sat, 10 Jul 2021 13:51:31 -0500 Subject: [PATCH 113/119] Mu4e: Ignore case when matching mu4e context This allows users to have different casing in their mu4e context names and the corresponding directories. Since mu4e's context switching automatically selects the letter from the context name, this allows users to set two contexts starting with the same letter to uppercase and lowercase variants, while leaving the directories lowercase. --- modules/email/mu4e/autoload/email.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index ed0094f0d..e008310b4 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -36,7 +36,7 @@ default/fallback account." (lambda (msg) (when msg (string-prefix-p (format "/%s" label) - (mu4e-message-field msg :maildir)))) + (mu4e-message-field msg :maildir) t))) :vars letvars))) (add-to-list 'mu4e-contexts context (not default-p)) context))) From 2fd89a7ecadf6baba18fd36a5e4fd203d8b3ed07 Mon Sep 17 00:00:00 2001 From: Liam Hupfer Date: Sat, 10 Jul 2021 13:47:44 -0500 Subject: [PATCH 114/119] Mu4e: More contextual +mu4e-set-from-address-h This hook should only be used when users define email aliases, or no contexts are defined (in which case the list of personal addresses should be used). Otherwise, the `:match-func` contexts feature is sufficient. --- modules/email/mu4e/README.org | 16 ++++++++++ modules/email/mu4e/autoload/email.el | 45 +++++++++++++--------------- 2 files changed, 37 insertions(+), 24 deletions(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 3da30fec7..9c3cdcf01 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -169,6 +169,22 @@ Then configure Emacs to use your email address: t) #+END_SRC +If you use multiple email accounts, defining them with ~set-email-account!~ will +automatically set the appropriate account context when replying to emails in +that account's maildir. ~mu4e-context-policy~ and ~mu4e-compose-context-policy~ +can be modified to change context behavior when opening mu4e and composing +email: + +#+begin_src emacs-lisp +(setq mu4e-context-policy 'ask-if-none + mu4e-compose-context-policy 'always-ask) +#+end_src + +If you send mail from various email aliases for different services, +~+mu4e-personal-addresses~ can be set per-context with ~set-email-account!~. If +you are not replying to an email to or from one of the specified aliases, you +will be prompted for an alias to send from. + *** Gmail With the =+gmail= flag, integrations are applied which account for the different behaviour of Gmail. diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index e008310b4..5fc63f372 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -30,8 +30,11 @@ default/fallback account." collect context)) (let ((context (make-mu4e-context :name label - :enter-func (lambda () (mu4e-message "Switched to %s" label)) - :leave-func #'mu4e-clear-caches + :enter-func + (lambda () (mu4e-message "Switched to %s" label)) + :leave-func + (lambda () (progn (setq +mu4e-personal-addresses nil) + (mu4e-clear-caches))) :match-func (lambda (msg) (when msg @@ -328,26 +331,20 @@ When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c- ;;;###autoload (defun +mu4e-set-from-address-h () - "Set the account for composing a message. If a 'To' header is present, -and correspands to an email address, this address will be selected. -Otherwise, the user is prompted for the address they wish to use. Possible -selections come from the mu database or a list of email addresses associated -with the current context." - (unless (and mu4e-compose-parent-message - (let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to)))) - (from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from))))) - (if (member to (mu4e-personal-addresses)) - (setq user-mail-address to) - (if (member from (mu4e-personal-addresses)) - (setq user-mail-address from) - nil)))) + "If the user defines multiple `+mu4e-personal-addresses' for email aliases +within a context, set `user-mail-address' to an alias found in the 'To' or +'From' headers of the parent message if present, or prompt the user for a +preferred alias" + (when-let ((addresses (if (or mu4e-contexts+mu4e-personal-addresses) + (and (> (length +mu4e-personal-addresses) 1) + +mu4e-personal-addresses) + (mu4e-personal-addresses)))) (setq user-mail-address - (if (= (length +mu4e-personal-addresses) 1) - (car +mu4e-personal-addresses) - (completing-read - "From: " - (if-let ((context-addresses - (when mu4e~context-current - (alist-get '+mu4e-personal-addresses (mu4e-context-vars mu4e~context-current))))) - context-addresses - (mu4e-personal-addresses))))))) + (if mu4e-compose-parent-message + (let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to)))) + (from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from))))) + (cond + ((member to addresses) to) + ((member from addresses) from) + (t (completing-read "From: " addresses)))) + (completing-read "From: " addresses))))) From ffaed9f5d738554d476bc1693039c68c121d2b4a Mon Sep 17 00:00:00 2001 From: Liam Hupfer Date: Sat, 10 Jul 2021 13:59:03 -0500 Subject: [PATCH 115/119] Mu4e: Fix typos --- modules/email/mu4e/autoload/advice.el | 2 +- modules/email/mu4e/autoload/email.el | 3 +-- modules/email/mu4e/doctor.el | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/email/mu4e/autoload/advice.el b/modules/email/mu4e/autoload/advice.el index d4474e0e8..b38bffc59 100644 --- a/modules/email/mu4e/autoload/advice.el +++ b/modules/email/mu4e/autoload/advice.el @@ -36,7 +36,7 @@ clicked." ;;;###autoload (defun +org-msg-img-scale-css (img-uri) - "For a given IMG-URI, use imagemagik to find its width." + "For a given IMG-URI, use imagemagick to find its width." (if +org-msg-currently-exporting (when (and (not IS-WINDOWS)) ; relies on posix path (let ((with-call (and (executable-find "identify") diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 5fc63f372..7d93492a0 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -313,8 +313,7 @@ When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c- (push (buffer-name buffer) buffers)))) (nreverse buffers))) -;; -;; Hooks +;;; Hooks (defun +mu4e-init-h () (add-hook 'kill-buffer-hook #'+mu4e-kill-mu4e-h nil t)) diff --git a/modules/email/mu4e/doctor.el b/modules/email/mu4e/doctor.el index d4c71cb4e..a9a4a9586 100644 --- a/modules/email/mu4e/doctor.el +++ b/modules/email/mu4e/doctor.el @@ -11,5 +11,5 @@ You may not have a way of fetching mail.")) (when (and (featurep! +org) (not IS-WINDOWS)) (unless (executable-find "identify") - (warn! "Couldn't find the identify command from imagemagik. \ + (warn! "Couldn't find the identify command from imagemagick. \ LaTeX fragment re-scaling with org-msg will not work."))) From 6915490d212b7bb49e93aa3eaff160d780541259 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 31 Jul 2021 01:10:54 +0800 Subject: [PATCH 116/119] Mu4e: Better adhere to Doom naming conventions --- modules/email/mu4e/autoload/email.el | 2 +- modules/email/mu4e/config.el | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index 7d93492a0..d3167d21f 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -238,7 +238,7 @@ attach a file, or select a folder to open dired in and select file attachments When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c-ctrl-c'." ;; TODO add ability to attach files (+dirs) as a single (named) archive (interactive "p") - (mu4e-compose-org-msg-handle-toggle (/= 1 files-to-attach)) + (+mu4e-compose-org-msg-handle-toggle (/= 1 files-to-attach)) (pcase major-mode ((or 'mu4e-compose-mode 'org-msg-edit-mode) (let ((mail-buffer (current-buffer)) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 90b2419e3..65185e860 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -166,11 +166,11 @@ ;; actually show you all the information you want to see ;; so if the header view is entered from a narrow frame, ;; it's probably worth trying to expand it - (defun mu4e-widen-frame-maybe () + (defun +mu4e-widen-frame-maybe () "Expand the frame with if it's less than `+mu4e-min-header-frame-width'." (when (< (frame-width) +mu4e-min-header-frame-width) (set-frame-width (selected-frame) +mu4e-min-header-frame-width))) - (add-hook 'mu4e-headers-mode-hook #'mu4e-widen-frame-maybe) + (add-hook 'mu4e-headers-mode-hook #'+mu4e-widen-frame-maybe) (when (fboundp 'imagemagick-register-types) (imagemagick-register-types)) @@ -221,7 +221,7 @@ (defun org-msg-mode (&optional _) "Dummy function." (message "Enable the +org mu4e flag to use org-msg-mode.")) - (defun mu4e-compose-org-msg-handle-toggle (&rest _) + (defun +mu4e-compose-org-msg-handle-toggle (&rest _) "Placeholder to allow for the assumtion that this function is defined. Ignores all arguments and returns nil." nil))) @@ -241,10 +241,10 @@ Ignores all arguments and returns nil." (defvar +org-msg-currently-exporting nil "Helper variable to indicate whether org-msg is currently exporting the org buffer to HTML. Usefull for affecting HTML export config.") - (defadvice! +org-msg--now-exporting (&rest _) + (defadvice! +org-msg--now-exporting-a (&rest _) :before #'org-msg-org-to-xml (setq +org-msg-currently-exporting t)) - (defadvice! +org-msg--not-exporting (&rest _) + (defadvice! +org-msg--not-exporting-a (&rest _) :after #'org-msg-org-to-xml (setq +org-msg-currently-exporting nil)) @@ -258,22 +258,22 @@ Usefull for affecting HTML export config.") (defvar +mu4e-compose-org-msg-toggle-next t ; t to initialise org-msg "Whether to toggle ") - (defun mu4e-compose-org-msg-handle-toggle (toggle-p) + (defun +mu4e-compose-org-msg-handle-toggle (toggle-p) (when (xor toggle-p +mu4e-compose-org-msg-toggle-next) (org-msg-mode (if org-msg-mode -1 1)) (setq +mu4e-compose-org-msg-toggle-next (not +mu4e-compose-org-msg-toggle-next)))) - (defadvice! mu4e-maybe-toggle-org-msg (orig-fn &optional toggle-p) + (defadvice! +mu4e-maybe-toggle-org-msg-a (orig-fn &optional toggle-p) :around #'mu4e-compose-new :around #'mu4e-compose-reply :around #'mu4e-compose-forward :around #'mu4e-compose-resend (interactive "p") - (mu4e-compose-org-msg-handle-toggle (/= 1 (or toggle-p 0))) + (+mu4e-compose-org-msg-handle-toggle (/= 1 (or toggle-p 0))) (funcall orig-fn)) - (defadvice! mu4e-draft-open-signature-a (orig-fn compose-type &optional msg) + (defadvice! +mu4e-draft-open-signature-a (orig-fn compose-type &optional msg) "Prevent `mu4e-compose-signature' from being used with `org-msg-mode'." :around #'mu4e-draft-open (let ((mu4e-compose-signature (unless org-msg-mode mu4e-compose-signature))) From 3fd6b2df1d7fa0fdfe075016fcf002718cfe0913 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 31 Jul 2021 01:11:11 +0800 Subject: [PATCH 117/119] Mu4e: Ensure composing buffers are writable This should always be the case, yet it doesn't seem like it always is. Just to be safe we will ensure that the buffer is not read-only. --- modules/email/mu4e/config.el | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/email/mu4e/config.el b/modules/email/mu4e/config.el index 65185e860..81b0dcbb6 100644 --- a/modules/email/mu4e/config.el +++ b/modules/email/mu4e/config.el @@ -200,6 +200,15 @@ (add-hook 'mu4e-compose-pre-hook '+mu4e-set-from-address-h) + (defadvice! +mu4e-ensure-compose-writeable-a (&rest _) + "Ensure that compose buffers are writable. +This should already be the case yet it does not always seem to be." + :before #'mu4e-compose-new + :before #'mu4e-compose-reply + :before #'mu4e-compose-forward + :before #'mu4e-compose-resend + (read-only-mode -1)) + (advice-add #'mu4e~key-val :filter-return #'+mu4e~main-keyval-str-prettier-a) (advice-add #'mu4e~main-action-str :override #'+mu4e~main-action-str-prettier-a) (when (featurep! :editor evil) From 6b690547b060614e10a8a6a2e6f4660efb9a5124 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 31 Jul 2021 01:22:21 +0800 Subject: [PATCH 118/119] Mu4e: Add myself (tecosaur) as module maintainer --- modules/email/mu4e/README.org | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/email/mu4e/README.org b/modules/email/mu4e/README.org index 9c3cdcf01..78df081a8 100644 --- a/modules/email/mu4e/README.org +++ b/modules/email/mu4e/README.org @@ -3,8 +3,9 @@ #+SINCE: v2.0 #+STARTUP: inlineimages -* Table of Contents :TOC: +* Table of Contents :TOC:noexport: - [[#description][Description]] + - [[#maintainers][Maintainers]] - [[#module-flags][Module Flags]] - [[#plugins][Plugins]] - [[#prerequisites][Prerequisites]] @@ -32,6 +33,9 @@ It uses ~mu4e~ to read my email, but depends on ~offlineimap~ (to sync my email via IMAP) and ~mu~ (to index my mail into a format ~mu4e~ can understand). #+end_quote +** Maintainers ++ [[https://github.com/tecosaur][@tecosaur]] + ** Module Flags + =+gmail= Enables gmail-specific configuration for mail ~To~ or ~From~ a gmail address, or a maildir with ~gmail~ in the name. From 896f7dd3df05afc4c7f0e30cde3c2984610d8e32 Mon Sep 17 00:00:00 2001 From: TEC Date: Sat, 31 Jul 2021 01:32:57 +0800 Subject: [PATCH 119/119] Mu4e: Select reply account when multiple addrs set Modify +mu4e-set-from-address-h to account for messages with multiple to/from headers by finding the intersection between the headers and registered accounts. While I'm at it, there was a rather silly typo in the when-let line that's been corrected. --- modules/email/mu4e/autoload/email.el | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/modules/email/mu4e/autoload/email.el b/modules/email/mu4e/autoload/email.el index d3167d21f..72b867d45 100644 --- a/modules/email/mu4e/autoload/email.el +++ b/modules/email/mu4e/autoload/email.el @@ -334,16 +334,15 @@ When otherwise called, open a dired buffer and enable `dired-mu4e-attach-ctrl-c- within a context, set `user-mail-address' to an alias found in the 'To' or 'From' headers of the parent message if present, or prompt the user for a preferred alias" - (when-let ((addresses (if (or mu4e-contexts+mu4e-personal-addresses) + (when-let ((addresses (if (or mu4e-contexts +mu4e-personal-addresses) (and (> (length +mu4e-personal-addresses) 1) +mu4e-personal-addresses) (mu4e-personal-addresses)))) (setq user-mail-address (if mu4e-compose-parent-message - (let ((to (cdr (car (mu4e-message-field mu4e-compose-parent-message :to)))) - (from (cdr (car (mu4e-message-field mu4e-compose-parent-message :from))))) - (cond - ((member to addresses) to) - ((member from addresses) from) - (t (completing-read "From: " addresses)))) + (let ((to (mapcar #'cdr (mu4e-message-field mu4e-compose-parent-message :to))) + (from (mapcar #'cdr (mu4e-message-field mu4e-compose-parent-message :from)))) + (or (car (seq-intersection to addresses)) + (car (seq-intersection from addresses)) + (completing-read "From: " addresses))) (completing-read "From: " addresses)))))