aboutsummaryrefslogtreecommitdiffstats
path: root/_spacemacs.d/local/mu4e
diff options
context:
space:
mode:
authorAaron LI <aaronly.me@outlook.com>2016-08-02 22:49:19 +0800
committerAaron LI <aaronly.me@outlook.com>2016-08-02 22:49:19 +0800
commit6814250a0c95e0849c191e7f5fe8e2a8bee31440 (patch)
treee48ff0faa822b1bb7f0d626d58732f40b6b97e8b /_spacemacs.d/local/mu4e
parent98083f04530335e8f98589373ecfad8948b86ae8 (diff)
downloaddotfiles-6814250a0c95e0849c191e7f5fe8e2a8bee31440.tar.bz2
spacemacs: update mu/mu4e to git20160802
Diffstat (limited to '_spacemacs.d/local/mu4e')
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-actions.el10
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-compose.el179
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-contrib.el3
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-draft.el61
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-headers.el111
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-main.el10
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-proc.el5
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-speedbar.el7
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-utils.el86
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-vars.el75
-rw-r--r--_spacemacs.d/local/mu4e/mu4e-view.el7
-rw-r--r--_spacemacs.d/local/mu4e/mu4e.el9
-rw-r--r--_spacemacs.d/local/mu4e/org-mu4e.el6
13 files changed, 395 insertions, 174 deletions
diff --git a/_spacemacs.d/local/mu4e/mu4e-actions.el b/_spacemacs.d/local/mu4e/mu4e-actions.el
index 7f145a1..0128c52 100644
--- a/_spacemacs.d/local/mu4e/mu4e-actions.el
+++ b/_spacemacs.d/local/mu4e/mu4e-actions.el
@@ -93,7 +93,7 @@ return the filename."
(if (plist-get attachment :temp)
(replace-match (format "src=\"%s\"" (plist-get attachment :temp)))
(replace-match (format "src=\"%s%s\"" temporary-file-directory (plist-get attachment :name)))
- (mu4e~proc-extract 'save (mu4e-message-field :docid) (plist-get attachment :index) mu4e-decryption-policy temporary-file-directory)
+ (mu4e~proc-extract 'save (mu4e-message-field msg :docid) (plist-get attachment :index) mu4e-decryption-policy temporary-file-directory)
(mu4e-remove-file-later (format "%s%s" temporary-file-directory (plist-get attachment :name))))))
attachments)
(save-buffer)
@@ -299,13 +299,17 @@ store your org-contacts."
(defun mu4e-action-show-thread (msg)
"Show all messages that are in the same thread as the message
-at point."
+at point. Point remains on the message with the message-id where
+the action was invoked. If invoked in view-mode, continue to
+display the message."
(let ((msgid (mu4e-message-field msg :message-id)))
(when msgid
(let ((mu4e-headers-show-threads t)
(mu4e-headers-include-related t))
(mu4e-headers-search
- (format "msgid:%s" msgid))))))
+ (format "msgid:%s" msgid)
+ nil nil nil
+ msgid (eq major-mode 'mu4e-view-mode))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
diff --git a/_spacemacs.d/local/mu4e/mu4e-compose.el b/_spacemacs.d/local/mu4e/mu4e-compose.el
index af2b34b..32d238d 100644
--- a/_spacemacs.d/local/mu4e/mu4e-compose.el
+++ b/_spacemacs.d/local/mu4e/mu4e-compose.el
@@ -140,8 +140,25 @@ Also see `mu4e-context-policy'."
(const :tag "Ask when there's no context yet" 'ask-if-none)
(const :tag "Pick the first context if none match" 'pick-first)
(const :tag "Don't change the context when none match" nil)
- :safe 'symbolp
- :group 'mu4e-compose))
+ :safe 'symbolp
+ :group 'mu4e-compose))
+
+
+(defcustom mu4e-compose-crypto-reply-policy 'sign-and-encrypt
+ "Policy for signing/encrypting replies to encrypted messages.
+We have the following choices:
+
+- `sign': sign the reply
+- `sign-and-encrypt': sign and encrypt the repy
+- `encrypt': encrypt the reply, but don't sign it.
+- anything else: do nothing."
+ :type '(choice
+ (const :tag "Sign the reply" 'sign)
+ (const :tag "Sign and encrypt the reply" 'sign-and-encrypt)
+ (const :tag "Encrypt the reply" 'encrypt)
+ (const :tag "Don't do anything" nil)
+ :safe 'symbolp
+ :group 'mu4e-compose))
(defcustom mu4e-compose-format-flowed nil
"Whether to compose messages to be sent as format=flowed (or
@@ -165,13 +182,14 @@ it has been constructed, `mu4e-compose-mode-hook' would be the
place to do that."
:type 'hook
:group 'mu4e-compose)
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-compose-attach-captured-message ()
"Insert the last captured message file as an attachment.
Messages are captured with `mu4e-action-capture-message'."
- (interactive)
+ (interactive)
(unless mu4e-captured-message
(mu4e-warn "No message has been captured"))
(let ((path (plist-get mu4e-captured-message :path)))
@@ -224,8 +242,8 @@ If needed, set the Fcc header, and register the handler function."
(when fccfile
(message-add-header (concat "Fcc: " fccfile "\n"))
;; sadly, we cannot define as 'buffer-local'... this will screw up gnus
- ;; etc. if you run it after mu4e so, (hack hack) we reset it to the old
- ;; handler after we've done our thing.
+ ;; etc. if you run it after mu4e so, (hack hack) we reset it to the old
+ ;; handler after we've done our thing.
(setq message-fcc-handler-function
(lexical-let ((maildir mdir) (old-handler message-fcc-handler-function))
(lambda (file)
@@ -276,7 +294,7 @@ appear on disk."
;; our contacts are already sorted - just need to tell the
;; completion machinery not to try to undo that...
'(metadata
- (display-sort-function . mu4e~sort-contacts-for-completion)
+ (display-sort-function . mu4e~sort-contacts-for-completion)
(cycle-sort-function . mu4e~sort-contacts-for-completion)))))
(defun mu4e~compose-complete-contact (&optional start)
@@ -335,18 +353,41 @@ simply executes `fill-paragraph'."
;; Inspired by https://www.emacswiki.org/emacs/UnfillParagraph
(interactive (progn (barf-if-buffer-read-only) '(t)))
(if mu4e-compose-format-flowed
- (let ((fill-column (point-max))
- (use-hard-newlines nil)); rfill "across" hard newlines
- (fill-paragraph nil region))
+ (let ((fill-column (point-max))
+ (use-hard-newlines nil)); rfill "across" hard newlines
+ (fill-paragraph nil region))
(fill-paragraph nil region)))
(defun mu4e-toggle-use-hard-newlines ()
(interactive)
(setq use-hard-newlines (not use-hard-newlines))
(if use-hard-newlines
- (turn-off-auto-fill)
+ (turn-off-auto-fill)
(turn-on-auto-fill)))
+(defun mu4e~compose-remap-faces ()
+ "Our parent `message-mode' uses font-locking for the compose
+buffers; lets remap its faces so it uses the ones for mu4e."
+ ;; normal headers
+ (face-remap-add-relative 'message-header-name
+ '((:inherit mu4e-header-key-face)))
+ (face-remap-add-relative 'message-header-other
+ '((:inherit mu4e-header-value-face)))
+ ;; special headers
+ (face-remap-add-relative 'message-header-from
+ '((:inherit mu4e-contact-face)))
+ (face-remap-add-relative 'message-header-to
+ '((:inherit mu4e-contact-face)))
+ (face-remap-add-relative 'message-header-cc
+ '((:inherit mu4e-contact-face)))
+ (face-remap-add-relative 'message-header-bcc
+ '((:inherit mu4e-contact-face)))
+ (face-remap-add-relative 'message-header-subject
+ '((:inherit mu4e-special-header-value-face)))
+ ;; citation
+ (face-remap-add-relative 'message-cited-text
+ '((:inherit mu4e-cited-1-face))))
+
(defvar mu4e-compose-mode-abbrev-table nil)
(define-derived-mode mu4e-compose-mode message-mode "mu4e:compose"
@@ -354,13 +395,14 @@ simply executes `fill-paragraph'."
\\{message-mode-map}."
(progn
(use-local-map mu4e-compose-mode-map)
-
(set (make-local-variable 'global-mode-string) '(:eval (mu4e-context-label)))
-
(set (make-local-variable 'message-signature) mu4e-compose-signature)
;; set this to allow mu4e to work when gnus-agent is unplugged in gnus
(set (make-local-variable 'message-send-mail-real-function) nil)
(make-local-variable 'message-default-charset)
+ ;; message-mode has font-locking, but uses its own faces. Let's
+ ;; use the mu4e-specific ones instead
+ (mu4e~compose-remap-faces)
;; if the default charset is not set, use UTF-8
(unless message-default-charset
(setq message-default-charset 'utf-8))
@@ -372,7 +414,6 @@ simply executes `fill-paragraph'."
;; useful e.g. when finding an attachment file the directory the current
;; mail files lives in...
(setq default-directory (expand-file-name "~/"))
-
;; offer completion for e-mail addresses
(when mu4e-compose-complete-addresses
(mu4e~compose-setup-completion))
@@ -380,31 +421,33 @@ simply executes `fill-paragraph'."
(when mu4e-compose-format-flowed
(turn-off-auto-fill)
(setq truncate-lines nil
- word-wrap t
- use-hard-newlines t)
+ word-wrap t
+ use-hard-newlines t)
;; Set the marks in the fringes before activating visual-line-mode
(set (make-local-variable 'visual-line-fringe-indicators)
- '(left-curly-arrow right-curly-arrow))
+ '(left-curly-arrow right-curly-arrow))
(visual-line-mode t))
- (define-key-after
- (lookup-key message-mode-map [menu-bar text])
- [mu4e-hard-newlines]
- '(menu-item "Format=flowed" mu4e-toggle-use-hard-newlines
- :button (:toggle . use-hard-newlines)
- :help "Toggle format=flowed"
- :visible (eq major-mode 'mu4e-compose-mode)
- :enable mu4e-compose-format-flowed)
- 'sep)
-
- (define-key-after
- (lookup-key mml-mode-map [menu-bar Attachments])
- [mu4e-compose-attach-captured-message]
- '(menu-item "Attach captured message"
- mu4e-compose-attach-captured-message
- :help "Attach message captured in Headers View (with 'a c')"
- :visible (eq major-mode 'mu4e-compose-mode))
- (quote Attach\ External...))
+ (when (lookup-key message-mode-map [menu-bar text])
+ (define-key-after
+ (lookup-key message-mode-map [menu-bar text])
+ [mu4e-hard-newlines]
+ '(menu-item "Format=flowed" mu4e-toggle-use-hard-newlines
+ :button (:toggle . use-hard-newlines)
+ :help "Toggle format=flowed"
+ :visible (eq major-mode 'mu4e-compose-mode)
+ :enable mu4e-compose-format-flowed)
+ 'sep))
+
+ (when (lookup-key mml-mode-map [menu-bar Attachments])
+ (define-key-after
+ (lookup-key mml-mode-map [menu-bar Attachments])
+ [mu4e-compose-attach-captured-message]
+ '(menu-item "Attach captured message"
+ mu4e-compose-attach-captured-message
+ :help "Attach message captured in Headers View (with 'a c')"
+ :visible (eq major-mode 'mu4e-compose-mode))
+ (quote Attach\ External...)))
;; setup the fcc-stuff, if needed
(add-hook 'message-send-hook
@@ -455,6 +498,21 @@ simply executes `fill-paragraph'."
mu4e~compose-buffer-max-name-length
nil nil t)))))
+
+(defun mu4e~compose-crypto-reply (parent compose-type)
+ "When composing a reply to an encrypted message, we can
+automatically encrypt that reply."
+ (message "%S %S" parent compose-type)
+ (when (and (eq compose-type 'reply)
+ (and parent (member 'encrypted (mu4e-message-field parent :flags))))
+ (case mu4e-compose-crypto-reply-policy
+ (sign (mml-secure-message-sign))
+ (encrypt (mml-secure-message-encrypt))
+ (sign-and-encrypt (mml-secure-message-sign-encrypt))
+ (message "Do nothing"))))
+
+
+
(defun* mu4e~compose-handler (compose-type &optional original-msg includes)
"Create a new draft message, or open an existing one.
@@ -480,17 +538,21 @@ tempfile)."
(put 'mu4e-compose-parent-message 'permanent-local t)
;; maybe switch the context
(mu4e~context-autoswitch mu4e-compose-parent-message
- mu4e-compose-context-policy)
+ mu4e-compose-context-policy)
(run-hooks 'mu4e-compose-pre-hook)
;; this opens (or re-opens) a messages with all the basic headers set.
- (condition-case nil
+ (let ((winconf (current-window-configuration)))
+ (condition-case nil
(mu4e-draft-open compose-type original-msg)
- (quit (kill-buffer) (mu4e-message "Operation aborted")
- (return-from mu4e~compose-handler)))
+ (quit (set-window-configuration winconf)
+ (mu4e-message "Operation aborted")
+ (return-from mu4e~compose-handler))))
;; insert mail-header-separator, which is needed by message mode to separate
;; headers and body. will be removed before saving to disk
(mu4e~draft-insert-mail-header-separator)
+ ;; maybe encrypt/sign replies
+ (mu4e~compose-crypto-reply original-msg compose-type)
;; include files -- e.g. when forwarding a message with attachments,
;; we take those from the original.
(save-excursion
@@ -502,7 +564,7 @@ tempfile)."
(mu4e~compose-set-friendly-buffer-name compose-type)
(set-buffer-modified-p nil)
;; now jump to some useful positions, and start writing that mail!
-
+
(if (member compose-type '(new forward))
(message-goto-to)
(message-goto-body))
@@ -512,8 +574,8 @@ tempfile)."
;; remember the compose-type
(set (make-local-variable 'mu4e~compose-type) compose-type)
(put 'mu4e~compose-type 'permanent-local t)
-
- ;; hide some headers
+
+ ;; hide some headers
(mu4e~compose-hide-headers)
;; switch on the mode
(mu4e-compose-mode)
@@ -534,17 +596,17 @@ the appropriate flag at the message forwarded or replied-to."
;; this seems a bit hamfisted...
(dolist (buf (buffer-list))
(when (and (buffer-file-name buf)
- (string= (buffer-file-name buf) path))
+ (string= (buffer-file-name buf) path))
(if message-kill-buffer-on-exit
- (kill-buffer buf))))
+ (kill-buffer buf))))
;; now, try to go back to some previous buffer, in the order
;; view->headers->main
(if (buffer-live-p mu4e~view-buffer)
- (switch-to-buffer mu4e~view-buffer)
- (if (buffer-live-p mu4e~headers-buffer)
- (switch-to-buffer mu4e~headers-buffer)
- ;; if all else fails, back to the main view
- (when (fboundp 'mu4e) (mu4e))))
+ (switch-to-buffer mu4e~view-buffer)
+ (if (buffer-live-p mu4e~headers-buffer)
+ (switch-to-buffer mu4e~headers-buffer)
+ ;; if all else fails, back to the main view
+ (when (fboundp 'mu4e) (mu4e))))
(mu4e-message "Message sent"))
(defun mu4e-message-kill-buffer ()
@@ -557,11 +619,11 @@ It restores mu4e window layout after killing the compose-buffer."
(when (not (equal current-buffer (current-buffer)))
;; Restore mu4e
(if mu4e-compose-in-new-frame
- (delete-frame)
+ (delete-frame)
(if (buffer-live-p mu4e~view-buffer)
- (switch-to-buffer mu4e~view-buffer)
+ (switch-to-buffer mu4e~view-buffer)
(if (buffer-live-p mu4e~headers-buffer)
- (switch-to-buffer mu4e~headers-buffer)
+ (switch-to-buffer mu4e~headers-buffer)
;; if all else fails, back to the main view
(when (fboundp 'mu4e) (mu4e))))))))
@@ -627,12 +689,12 @@ is a symbol, one of `reply', `forward', `edit', `resend'
(mu4e~compose-handler 'new)
;; otherwise, we need the doc-id
(let* ((docid (mu4e-message-field msg :docid))
- ;; decrypt (or not), based on `mu4e-decryption-policy'.
- (decrypt
- (and (member 'encrypted (mu4e-message-field msg :flags))
- (if (eq mu4e-decryption-policy 'ask)
- (yes-or-no-p (mu4e-format "Decrypt message?"))
- mu4e-decryption-policy))))
+ ;; decrypt (or not), based on `mu4e-decryption-policy'.
+ (decrypt
+ (and (member 'encrypted (mu4e-message-field msg :flags))
+ (if (eq mu4e-decryption-policy 'ask)
+ (yes-or-no-p (mu4e-format "Decrypt message?"))
+ mu4e-decryption-policy))))
;; if there's a visible view window, select that before starting composing
;; a new message, so that one will be replaced by the compose window. The
;; 10-or-so line headers buffer is not a good place to write it...
@@ -669,7 +731,6 @@ draft message."
(interactive)
(mu4e-compose 'new))
-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; mu4e-compose-func and mu4e-send-func are wrappers so we can set ourselves
@@ -761,7 +822,7 @@ Go to the end of the message (before signature) or, if already there, go to the
end of the buffer."
(interactive)
(let ((old-position (point))
- (message-position (save-excursion (message-goto-body) (point))))
+ (message-position (save-excursion (message-goto-body) (point))))
(goto-char (point-max))
(when (re-search-backward message-signature-separator message-position t)
(forward-line -1))
diff --git a/_spacemacs.d/local/mu4e/mu4e-contrib.el b/_spacemacs.d/local/mu4e/mu4e-contrib.el
index 8952401..156f5b6 100644
--- a/_spacemacs.d/local/mu4e/mu4e-contrib.el
+++ b/_spacemacs.d/local/mu4e/mu4e-contrib.el
@@ -67,7 +67,8 @@
'mu4e-view-bookmark-make-record)))
(defun mu4e-view-bookmark-make-record ()
- "Make a bookmark entry for a mu4e buffer."
+ "Make a bookmark entry for a mu4e buffer. Note that this is an
+emacs bookmark, not to be confused with `mu4e-bookmarks'."
(let* ((msg (mu4e-message-at-point))
(maildir (plist-get msg :maildir))
(date (format-time-string "%Y%m%d" (plist-get msg :date)))
diff --git a/_spacemacs.d/local/mu4e/mu4e-draft.el b/_spacemacs.d/local/mu4e/mu4e-draft.el
index c41e38d..d7df6e0 100644
--- a/_spacemacs.d/local/mu4e/mu4e-draft.el
+++ b/_spacemacs.d/local/mu4e/mu4e-draft.el
@@ -99,7 +99,6 @@ its settings apply."
(funcall mu4e-compose-cite-function))
(pop-mark)
(goto-char (point-min))
- (mu4e~fontify-cited)
(buffer-string))))
(defun mu4e~draft-header (hdr val)
@@ -109,7 +108,17 @@ If VAL is nil, return nil."
;; later.
(when val (format "%s: %s\n"
(propertize hdr 'face 'mu4e-header-key-face)
- (propertize val 'face 'mu4e-header-val-face))))
+ (propertize val 'face 'mu4e-header-value-face))))
+
+(defconst mu4e~max-reference-num 21
+ "Maximum number of References:, as suggested by
+`message-shorten-references'.")
+
+(defun mu4e~shorten-1 (list cut surplus)
+ "Cut SURPLUS elements out of LIST, beginning with CUTth
+one. Code borrowed from `message-shorten-1'."
+ (setcdr (nthcdr (- cut 2) list)
+ (nthcdr (+ (- cut 2) surplus 1) list)))
(defun mu4e~draft-references-construct (msg)
"Construct the value of the References: header based on MSG as a
@@ -125,10 +134,16 @@ References. If both are empty, return nil."
(refs (if (and msgid (not (string= msgid "")))
(append refs (list msgid)) refs))
;; no doubles
- (refs (delete-duplicates refs :test #'equal)))
+ (refs (delete-duplicates refs :test #'equal))
+ (refnum (length refs))
+ (cut 2))
+ ;; remove some refs when there are too many
+ (when (> refnum mu4e~max-reference-num)
+ (let ((surplus (- refnum mu4e~max-reference-num)))
+ (mu4e~shorten-1 refs cut surplus)))
(mapconcat (lambda (id) (format "<%s>" id)) refs " ")))
-
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; determine the recipient fields for new messages
@@ -311,7 +326,7 @@ You can append flags."
(format-time-string "%s" (current-time))
(random 65535) (random 65535) (random 65535) (random 65535)
hostname (or flagstr ""))))
-
+
(defun mu4e~draft-common-construct ()
"Construct the common headers for each message."
(concat
@@ -346,11 +361,12 @@ fields will be the same as in the original."
(mu4e~draft-header "To" (mu4e~draft-recipients-list-to-string
(mu4e-message-field origmsg :to)))
(mu4e~draft-header "Cc" (mu4e~draft-recipients-list-to-string
- (mu4e-message-field origmsg :cc))))
-
+ (mu4e-message-field origmsg :cc))))
+
;; if there's no-one in To, copy the CC-list
(if (zerop (length (mu4e~draft-create-to-lst origmsg)))
- (mu4e~draft-header "To" (mu4e~draft-recipients-construct :cc origmsg reply-all))
+ (mu4e~draft-header "To" (mu4e~draft-recipients-construct
+ :cc origmsg reply-all))
;; otherwise...
(concat
(mu4e~draft-header "To" (mu4e~draft-recipients-construct :to origmsg))
@@ -415,9 +431,10 @@ fields will be the same as in the original."
(defun mu4e-draft-open (compose-type &optional msg)
- "Open a draft file for a new message (when COMPOSE-TYPE is `reply', `forward' or `new'),
-open an existing draft (when COMPOSE-TYPE is `edit'), or re-send
-an existing message (when COMPOSE-TYPE is `resend').
+ "Open a draft file for a new message (when COMPOSE-TYPE is `reply',
+ `forward' or `new'), open an existing draft (when COMPOSE-TYPE
+is `edit'), or re-send an existing message (when COMPOSE-TYPE is
+`resend').
The name of the draft folder is constructed from the
concatenation of `mu4e-maildir' and `mu4e-drafts-folder' (the
@@ -428,10 +445,11 @@ will be created from either `mu4e~draft-reply-construct', or
(unless mu4e-maildir (mu4e-error "mu4e-maildir not set"))
(let ((draft-dir nil))
(case compose-type
-
+
(edit
- ;; case-1: re-editing a draft messages. in this case, we do know the full
- ;; path, but we cannot really know 'drafts folder'... we make a guess
+ ;; case-1: re-editing a draft messages. in this case, we do know the
+ ;; full path, but we cannot really know 'drafts folder'... we make a
+ ;; guess
(setq draft-dir (mu4e~guess-maildir (mu4e-message-field msg :path)))
(mu4e~draft-open-file (mu4e-message-field msg :path)))
@@ -442,9 +460,9 @@ will be created from either `mu4e~draft-reply-construct', or
(let ((draft-path (mu4e~draft-determine-path draft-dir)))
(copy-file (mu4e-message-field msg :path) draft-path)
(mu4e~draft-open-file draft-path)))
-
+
((reply forward new)
- ;; case-3: creating a new message; in this case, we can determing
+ ;; case-3: creating a new message; in this case, we can determine
;; mu4e-get-drafts-folder
(setq draft-dir (mu4e-get-drafts-folder msg))
(let ((draft-path (mu4e~draft-determine-path draft-dir))
@@ -454,7 +472,7 @@ will be created from either `mu4e~draft-reply-construct', or
(forward (mu4e~draft-forward-construct msg))
(new (mu4e~draft-newmsg-construct)))))
(mu4e~draft-open-file draft-path)
- (insert initial-contents)
+ (insert initial-contents)
(newline)
;; include the message signature (if it's set)
(if (and mu4e-compose-signature-auto-include mu4e-compose-signature)
@@ -463,12 +481,15 @@ will be created from either `mu4e~draft-reply-construct', or
(message-insert-signature)
(mu4e~fontify-signature))))))
(t (mu4e-error "unsupported compose-type %S" compose-type)))
- ;; evaluate mu4e~drafts-drafts-folder once, here, and use that value
- ;; throughout.
+ ;; if we didn't find a draft folder yet, try some default
+ (unless draft-dir
+ (setq draft-dir (mu4e-get-drafts-folder msg)))
+ ;; evaluate mu4e~drafts-drafts-folder once, here, and use that value
+ ;; throughout.
(set (make-local-variable 'mu4e~draft-drafts-folder) draft-dir)
(put 'mu4e~draft-drafts-folder 'permanent-local t)
(unless mu4e~draft-drafts-folder
(mu4e-error "failed to determine drafts folder"))))
-
+
(provide 'mu4e-draft)
diff --git a/_spacemacs.d/local/mu4e/mu4e-headers.el b/_spacemacs.d/local/mu4e/mu4e-headers.el
index f45d7b4..e137c02 100644
--- a/_spacemacs.d/local/mu4e/mu4e-headers.el
+++ b/_spacemacs.d/local/mu4e/mu4e-headers.el
@@ -135,6 +135,21 @@ sent messages into message threads."
:type 'boolean
:group 'mu4e-headers)
+
+(defvar mu4e-headers-hide-predicate nil
+ "Predicate function applied to headers before they are shown;
+if function is nil or evaluates to nil, show the header,
+otherwise don't. function takes one parameter MSG, which is the
+message plist for the message to be hidden or not.
+
+Example that hides all 'trashed' messages:
+ (setq mu4e-headers-hide-predicate
+ (lambda (msg)
+ (member 'trashed (mu4e-message-field msg :flags))))
+
+Note that this is merely a display filter.")
+
+
(defcustom mu4e-headers-visible-flags
'(draft flagged new passed replied seen trashed attach encrypted signed unread)
"An ordered list of flags to show in the headers buffer. Each
@@ -215,7 +230,7 @@ Field must be a symbol, one of: :date, :subject, :size, :prio,
(defvar mu4e-headers-default-prefix '("|" . "│ ") "Default.")
(defvar mu4e-headers-actions
- '( ("capture message" . mu4e-action-capture-message)
+ '( ("capture message" . mu4e-action-capture-message)
("show this thread" . mu4e-action-show-thread))
"List of actions to perform on messages in the headers list.
The actions are of the form (NAME SHORTCUT FUNC) where:
@@ -311,22 +326,23 @@ headers."
(when (buffer-live-p mu4e~headers-buffer)
(with-current-buffer mu4e~headers-buffer
(let* ((docid (mu4e-message-field msg :docid))
- (initial-message-at-point (mu4e~headers-docid-at-point))
- (initial-column (current-column))
- (point (mu4e~headers-docid-pos docid)))
+ (initial-message-at-point (mu4e~headers-docid-at-point))
+ (initial-column (current-column))
+ (point (mu4e~headers-docid-pos docid)))
+
(when point ;; is the message present in this list?
;; if it's marked, unmark it now
(when (mu4e-mark-docid-marked-p docid)
(mu4e-mark-set 'unmark))
- ;; re-use the thread info from the old one; this is needed because
- ;; *update* messages don't have thread info by themselves (unlike
- ;; search results)
+ ;; re-use the thread info from the old one; this is needed because
+ ;; *update* messages don't have thread info by themselves (unlike
+ ;; search results)
;; since we still have the search results, re-use
- ;; those
- (plist-put msg :thread
- (mu4e~headers-field-for-docid docid :thread))
+ ;; those
+ (plist-put msg :thread
+ (mu4e~headers-field-for-docid docid :thread))
;; first, remove the old one (otherwise, we'd have two headers with
;; the same docid...
@@ -337,11 +353,10 @@ headers."
;; (which is useful for viewing the raw message)
(when (mu4e~headers-view-this-message-p docid)
(mu4e-view msg mu4e~headers-buffer))
-
;; now, if this update was about *moving* a message, we don't show it
;; anymore (of course, we cannot be sure if the message really no
- ;; longer matches the query, but this seem a good heuristic.
- ;; if it was only a flag-change, show the message with its updated flags.
+ ;; longer matches the query, but this seem a good heuristic. if it
+ ;; was only a flag-change, show the message with its updated flags.
(unless is-move
(mu4e~headers-header-handler msg point))
@@ -351,8 +366,7 @@ headers."
(move-to-column initial-column)
(mu4e~headers-highlight initial-message-at-point))
;; attempt to highlight the corresponding line and make it visible
- (mu4e~headers-highlight docid))
- )))))
+ (mu4e~headers-highlight docid)))))))
(defun mu4e~headers-remove-handler (docid)
"Remove handler, will be called when a message with DOCID has
@@ -382,7 +396,7 @@ into a string."
(let ((name (car ct)) (email (cdr ct)))
(or name email "?"))) contacts ", "))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defsubst mu4e~headers-thread-prefix (thread)
"Calculate the thread prefix based on thread info THREAD."
(when thread
@@ -430,7 +444,7 @@ while our display may be different)."
('signed (funcall get-prefix mu4e-headers-signed-mark))
('unread (funcall get-prefix mu4e-headers-unread-mark)))))))
str))
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defconst mu4e-headers-from-or-to-prefix '("" . "To ")
@@ -493,7 +507,8 @@ found."
(let* ((item (or (assoc field mu4e-header-info-custom)
(mu4e-error "field %S not found" field)))
(func (or (plist-get (cdr-safe item) :function)
- (mu4e-error "no :function defined for field %S %S" field (cdr item)))))
+ (mu4e-error "no :function defined for field %S %S"
+ field (cdr item)))))
(funcall func msg)))
(defun mu4e~headers-field-apply-basic-properties (msg field val width)
@@ -571,12 +586,14 @@ found."
(defun mu4e~headers-header-handler (msg &optional point)
"Create a one line description of MSG in this buffer, at POINT,
if provided, or at the end of the buffer otherwise."
- (let ((docid (mu4e-message-field msg :docid))
- (line (mapconcat (lambda (f-w)
- (mu4e~headers-field-handler f-w msg))
- mu4e-headers-fields " ")))
- (setq line (mu4e~headers-line-handler msg line))
- (mu4e~headers-add-header line docid point msg)))
+ (unless (and mu4e-headers-hide-predicate
+ (funcall mu4e-headers-hide-predicate msg))
+ (let ((docid (mu4e-message-field msg :docid))
+ (line (mapconcat (lambda (f-w)
+ (mu4e~headers-field-handler f-w msg))
+ mu4e-headers-fields " ")))
+ (setq line (mu4e~headers-line-handler msg line))
+ (mu4e~headers-add-header line docid point msg))))
(defconst mu4e~no-matches "No matching messages found")
(defconst mu4e~end-of-results "End of search results")
@@ -598,14 +615,15 @@ after the end of the search results."
(goto-char (point-min))
(when mu4e~headers-msgid-target
(mu4e-headers-goto-message-id mu4e~headers-msgid-target))
- (when mu4e~headers-view-target
- (mu4e-headers-view-message)) ;; view the message at point
+ (when (and mu4e~headers-view-target (mu4e-message-at-point 'noerror))
+ ;; view the message at point when there is one.
+ (mu4e-headers-view-message))
(setq mu4e~headers-view-target nil
mu4e~headers-msgid-target nil))
(when (mu4e~headers-docid-at-point)
(mu4e~headers-highlight (mu4e~headers-docid-at-point)))
;; run-hooks
- (run-hooks 'mu4e-headers-found-hook)))
+ (run-hooks 'mu4e-headers-found-hook)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -679,7 +697,7 @@ after the end of the search results."
(define-key map (kbd "[") 'mu4e-headers-prev-unread)
(define-key map (kbd "]") 'mu4e-headers-next-unread)
-
+
;; change the number of headers
(define-key map (kbd "C-+") 'mu4e-headers-split-view-grow)
(define-key map (kbd "C--") 'mu4e-headers-split-view-shrink)
@@ -687,7 +705,7 @@ after the end of the search results."
(define-key map (kbd "<C-kp-subtract>") 'mu4e-headers-split-view-shrink)
(define-key map ";" 'mu4e-context-switch)
-
+
;; switching to view mode (if it's visible)
(define-key map "y" 'mu4e-select-other-view)
@@ -748,20 +766,24 @@ after the end of the search results."
(define-key menumap [sepa0] '("--"))
(define-key menumap [toggle-include-related]
- '(menu-item "Toggle related messages" mu4e-headers-toggle-include-related
- :button (:toggle . (and (boundp 'mu4e-headers-include-related)
- mu4e-headers-include-related))))
+ '(menu-item "Toggle related messages"
+ mu4e-headers-toggle-include-related
+ :button (:toggle .
+ (and (boundp 'mu4e-headers-include-related)
+ mu4e-headers-include-related))))
(define-key menumap [toggle-threading]
'(menu-item "Toggle threading" mu4e-headers-toggle-threading
- :button (:toggle . (and (boundp 'mu4e-headers-show-threads)
- mu4e-headers-show-threads))))
+ :button (:toggle .
+ (and (boundp 'mu4e-headers-show-threads)
+ mu4e-headers-show-threads))))
(define-key menumap [sepa1] '("--"))
(define-key menumap [execute-marks] '("Execute marks"
. mu4e-mark-execute-all))
(define-key menumap [unmark-all] '("Unmark all" . mu4e-mark-unmark-all))
- (define-key menumap [unmark] '("Unmark" . mu4e-headers-mark-for-unmark))
+ (define-key menumap [unmark]
+ '("Unmark" . mu4e-headers-mark-for-unmark))
(define-key menumap [mark-pattern] '("Mark pattern" .
mu4e-headers-mark-pattern))
@@ -783,11 +805,12 @@ after the end of the search results."
(define-key menumap [forward] '("Forward" . mu4e-compose-forward))
(define-key menumap [reply] '("Reply" . mu4e-compose-reply))
(define-key menumap [compose-new] '("Compose new" . mu4e-compose-new))
-
-
+
+
(define-key menumap [sepa3] '("--"))
- (define-key menumap [query-next] '("Next query" . mu4e-headers-query-next))
+ (define-key menumap [query-next]
+ '("Next query" . mu4e-headers-query-next))
(define-key menumap [query-prev] '("Previous query" .
mu4e-headers-query-prev))
(define-key menumap [narrow-search] '("Narrow search" .
@@ -979,7 +1002,7 @@ message plist, or nil if not found."
(let ((this-msgid (mu4e-message-field msg :message-id)))
(when (and this-msgid (string= msgid this-msgid))
msg)))))
-
+
;;;; markers mark headers for
(defun mu4e~headers-mark (docid mark)
"(Visually) mark the header for DOCID with character MARK."
@@ -1062,7 +1085,7 @@ the query history stack."
'face 'mu4e-modeline-face)
" "
(mu4e-context-label)))))
-
+
(switch-to-buffer buf)
(run-hook-with-args 'mu4e-headers-search-hook expr)
(mu4e~proc-find
@@ -1229,7 +1252,7 @@ descendants."
(last-marked-point))
(mu4e-headers-for-each
(lambda (mymsg)
- (let ((my-thread-id (mu4e~headers-get-thread-info mymsg 'thread-id)))
+ (let ((my-thread-id (mu4e~headers-get-thread-info mymsg 'thread-id)))
(if subthread
;; subthread matching; mymsg's thread path should have path as its
;; prefix
@@ -1375,8 +1398,8 @@ the last search expression. Note that you can go back to previous
query (effectively, 'widen' it), with `mu4e-headers-query-prev'."
(interactive
(let ((filter
- (read-string (mu4e-format "Narrow down to: ")
- nil 'mu4e~headers-search-hist nil t)))
+ (read-string (mu4e-format "Narrow down to: ")
+ nil 'mu4e~headers-search-hist nil t)))
(list filter)))
(unless mu4e~headers-last-query
(mu4e-warn "There's nothing to filter"))
@@ -1586,7 +1609,7 @@ untrashed). If BACKWARDS is non-`nil', move backwards."
(interactive)
(or (mu4e-headers-find-if-next
(lambda (msg)
- (let ((flags (mu4e-message-field msg :flags)))
+ (let ((flags (mu4e-message-field msg :flags)))
(and (member 'unread flags) (not (member 'trashed flags)))))
backwards)
(mu4e-message (format "No %s unread message found"
diff --git a/_spacemacs.d/local/mu4e/mu4e-main.el b/_spacemacs.d/local/mu4e/mu4e-main.el
index 0f4dc78..a647a2d 100644
--- a/_spacemacs.d/local/mu4e/mu4e-main.el
+++ b/_spacemacs.d/local/mu4e/mu4e-main.el
@@ -137,11 +137,11 @@ clicked."
;; TODO: it's a bit uncool to hard-code the "b" shortcut...
(mapconcat
(lambda (bm)
- (let* ((query (nth 0 bm)) (title (nth 1 bm)) (key (nth 2 bm)))
- (mu4e~main-action-str
- (concat "\t* [b" (make-string 1 key) "] " title)
- (concat "b" (make-string 1 key)))))
- mu4e-bookmarks "\n")
+ (mu4e~main-action-str
+ (concat "\t* [b" (make-string 1 (mu4e-bookmark-key bm)) "] "
+ (mu4e-bookmark-name bm))
+ (concat "b" (make-string 1 (mu4e-bookmark-key bm)))))
+ (mu4e-bookmarks) "\n")
"\n\n"
(propertize " Misc\n\n" 'face 'mu4e-title-face)
diff --git a/_spacemacs.d/local/mu4e/mu4e-proc.el b/_spacemacs.d/local/mu4e/mu4e-proc.el
index d93af5d..d6d90e1 100644
--- a/_spacemacs.d/local/mu4e/mu4e-proc.el
+++ b/_spacemacs.d/local/mu4e/mu4e-proc.el
@@ -401,14 +401,15 @@ or (:error ) sexp, which are handled my `mu4e-update-func' and
idparam (or flagstr "") (or path "")
(format "newname:%s" rename))))
-(defun mu4e~proc-index (path my-addresses)
+(defun mu4e~proc-index (path my-addresses cleanup lazy-check)
"Update the message database for filesystem PATH, which should
point to some maildir directory structure. MY-ADDRESSES is a list
of 'my' email addresses (see `mu4e-user-mail-address-list')."
(let ((path (mu4e~proc-escape path))
(addrs (when my-addresses (mapconcat 'identity my-addresses ","))))
(if addrs
- (mu4e~proc-send-command "cmd:index path:%s my-addresses:%s" path addrs)
+ (mu4e~proc-send-command "cmd:index path:%s my-addresses:%s cleanup:%s lazy-check:%s"
+ path addrs (if cleanup "true" : "false") (if lazy-check "true"))
(mu4e~proc-send-command "cmd:index path:%s" path))))
(defun mu4e~proc-add (path maildir)
diff --git a/_spacemacs.d/local/mu4e/mu4e-speedbar.el b/_spacemacs.d/local/mu4e/mu4e-speedbar.el
index b359511..09a4c49 100644
--- a/_spacemacs.d/local/mu4e/mu4e-speedbar.el
+++ b/_spacemacs.d/local/mu4e/mu4e-speedbar.el
@@ -34,6 +34,7 @@
(require 'speedbar)
(require 'mu4e-vars)
(require 'mu4e-headers)
+(require 'mu4e-utils)
(defvar mu4e-main-speedbar-key-map nil
"Keymap used when in mu4e display mode.")
@@ -90,12 +91,12 @@
(interactive)
(mapcar (lambda (bookmark)
(speedbar-insert-button
- (concat " " (nth 1 bookmark))
+ (concat " " (mu4e-bookmark-name bookmark))
'mu4e-highlight-face
'highlight
'mu4e~speedbar-bookmark
- (nth 0 bookmark)))
- mu4e-bookmarks))
+ (mu4e-bookmark-query bookmark)))
+ (mu4e-bookmarks)))
(defun mu4e~speedbar-bookmark (&optional text token ident)
"Run bookmarked query TOKEN. TEXT and INDENT are not used."
diff --git a/_spacemacs.d/local/mu4e/mu4e-utils.el b/_spacemacs.d/local/mu4e/mu4e-utils.el
index a969c44..f8110b5 100644
--- a/_spacemacs.d/local/mu4e/mu4e-utils.el
+++ b/_spacemacs.d/local/mu4e/mu4e-utils.el
@@ -396,46 +396,80 @@ and offer to create it if it does not exist yet."
(mu4e~proc-mkdir fullpath)))
mdir))
+
+(defstruct mu4e-bookmark
+ "A mu4e bookmarl object with the following members:
+- `name': the user-visible name of the bookmark
+- `key': a single key to search for this bookmark
+- `query': the query for this bookmark. Either a literal string or a function
+ that evaluates to a string."
+ name ;; name/description of the bookmark
+ query ;; a query (a string or a function evaluation to string)
+ key ;; key to activate the bookmark
+ )
+
+(defun mu4e-bookmarks ()
+ "Get `mu4e-bookmarks' in the (new) format, converting from the old
+format if needed."
+ (map 'list
+ (lambda (item)
+ (if (mu4e-bookmark-p item)
+ item ;; already in the right format
+ (if (and (listp item) (= (length item) 3))
+ (make-mu4e-bookmark
+ :name (nth 1 item)
+ :query (nth 0 item)
+ :key (nth 2 item))
+ (mu4e-error "Invalid bookmark in mu4e-bookmarks"))))
+ mu4e-bookmarks))
+
+
(defun mu4e-ask-bookmark (prompt &optional kar)
"Ask the user for a bookmark (using PROMPT) as defined in
`mu4e-bookmarks', then return the corresponding query."
- (unless mu4e-bookmarks (mu4e-error "No bookmarks defined"))
+ (unless (mu4e-bookmarks) (mu4e-error "No bookmarks defined"))
(let* ((prompt (mu4e-format "%s" prompt))
(bmarks
(mapconcat
(lambda (bm)
- (let ((query (nth 0 bm)) (title (nth 1 bm)) (key (nth 2 bm)))
- (concat
- "[" (propertize (make-string 1 key)
- 'face 'mu4e-highlight-face)
- "]"
- title))) mu4e-bookmarks ", "))
- (kar (read-char (concat prompt bmarks))))
+ (concat
+ "[" (propertize (make-string 1 (mu4e-bookmark-key bm))
+ 'face 'mu4e-highlight-face)
+ "]"
+ (mu4e-bookmark-name bm))) (mu4e-bookmarks) ", "))
+ (kar (read-char (concat prompt bmarks))))
(mu4e-get-bookmark-query kar)))
-
(defun mu4e-get-bookmark-query (kar)
"Get the corresponding bookmarked query for shortcut character
KAR, or raise an error if none is found."
(let* ((chosen-bm
(or (find-if
(lambda (bm)
- (= kar (nth 2 bm)))
- mu4e-bookmarks)
+ (= kar (mu4e-bookmark-key bm)))
+ (mu4e-bookmarks))
(mu4e-warn "Unknown shortcut '%c'" kar)))
- (expr (nth 0 chosen-bm))
+ (expr (mu4e-bookmark-query chosen-bm))
(query (eval expr)))
(if (stringp query)
query
(mu4e-warn "Expression must evaluate to query string ('%S')" expr))))
-(defun mu4e-bookmark-define (query descr key)
- "Define a bookmark for QUERY with description DESCR and short
-character KEY in the list of `mu4e-bookmarks'. This replaces any
-existing bookmark with KEY."
- (setq mu4e-bookmarks (remove-if (lambda (bm) (= (nth 2 bm) key)) mu4e-bookmarks))
- (add-to-list 'mu4e-bookmarks (list query descr key) t))
+(defun mu4e-bookmark-define (query name key)
+ "Define a bookmark for QUERY with name NAME and
+shortcut-character KEY in the list of `mu4e-bookmarks'. This
+replaces any existing bookmark with KEY."
+ (setq mu4e-bookmarks
+ (remove-if
+ (lambda (bm)
+ (= (mu4e-bookmark-key bm) key))
+ (mu4e-bookmarks)))
+ (add-to-list 'mu4e-bookmarks
+ (make-mu4e-bookmark
+ :name name
+ :query query
+ :key key) t))
;;; converting flags->string and vice-versa ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -834,7 +868,8 @@ successful, call FUNC (if non-nil) afterwards."
(setq mu4e~update-timer
(run-at-time
0 mu4e-update-interval
- (lambda () (mu4e-update-mail-and-index mu4e-index-update-in-background)))))
+ (lambda () (mu4e-update-mail-and-index
+ mu4e-index-update-in-background)))))
(mu4e-message "Started mu4e with %d message%s in store"
doccount (if (= doccount 1) "" "s"))))))
;; wake up server
@@ -894,7 +929,11 @@ Also scrolls to the final line, and update the progress throbber."
;; Insert at end of buffer. Leave point alone.
(with-current-buffer (process-buffer proc)
(goto-char (point-max))
- (insert msg))
+ (if (string-match ".*\r\\(.*\\)" msg)
+ (progn
+ (kill-line 0)
+ (insert (match-string 1 msg)))
+ (insert msg)))
;; Auto-scroll unless user is interacting with the window.
(when (and (window-live-p procwin)
(not (eq (selected-window) procwin)))
@@ -906,7 +945,10 @@ Also scrolls to the final line, and update the progress throbber."
(interactive)
(unless mu4e-maildir
(mu4e-error "`mu4e-maildir' is not defined"))
- (mu4e~proc-index mu4e-maildir mu4e-user-mail-address-list))
+ (mu4e~proc-index mu4e-maildir
+ mu4e-user-mail-address-list
+ mu4e-index-cleanup
+ mu4e-index-lazy-check))
(defvar mu4e~update-buffer nil
"Internal, store the buffer of the update process when
@@ -1211,7 +1253,7 @@ used in the view and compose modes."
(when (search-forward-regexp "^\n" nil t) ;; search the first empty line
(while (re-search-forward mu4e-cited-regexp nil t)
(let* ((level (string-width (replace-regexp-in-string
- " " "" (match-string 1))))
+ "[^>]" "" (match-string 0))))
(face (unless (zerop level)
(intern-soft (format "mu4e-cited-%d-face" level)))))
(when face
diff --git a/_spacemacs.d/local/mu4e/mu4e-vars.el b/_spacemacs.d/local/mu4e/mu4e-vars.el
index 94c3a86..e07b196 100644
--- a/_spacemacs.d/local/mu4e/mu4e-vars.el
+++ b/_spacemacs.d/local/mu4e/mu4e-vars.el
@@ -90,6 +90,27 @@ background."
:group 'mu4e
:safe 'booleanp)
+(defcustom mu4e-index-cleanup t
+ "Whether to run a cleanup face after indexing -- that is, see
+if the is a message in the filesystem for each file in the
+message store. Having this option as `t' ensures that no
+non-existing mesages are shown but can also be quite slow with
+large message stores."
+ :type 'boolean
+ :group 'mu4e
+ :safe 'booleanp)
+
+(defcustom mu4e-index-lazy-check nil
+ "Whether to run do a 'lazy check' for deciding whether to
+indexing a message. When this is set to `t', mu only uses the
+directory timestamps to decide on whether it needs to check the
+messages beneath it, which would miss messages that are modified
+outside mu. On the other hand, it's significantly faster."
+ :type 'boolean
+ :group 'mu4e
+ :safe 'booleanp)
+
+
(defcustom mu4e-update-interval nil
"Number of seconds between automatic calls to retrieve mail and
update the database. If nil, don't update automatically. Note,
@@ -105,9 +126,11 @@ mu4e."
You can use this hook for example to `mu4e-get-mail-command' with
some specific setting.")
-(defvar mu4e-hide-index-messages nil
- "If non-nil, mu4e does not show the \"Indexing...\" messages, or
- any messages relating to updated contacts.")
+(defcustom mu4e-hide-index-messages nil
+ "Whether to hide the \"Indexing...\" messages, or any messages
+relating to updated contacts."
+ :type 'boolean
+ :group 'mu4e)
(defcustom mu4e-change-filenames-when-moving nil
"When moving messages to different folders, normally mu/mu4e keep
@@ -177,6 +200,33 @@ is a shortcut key for the query."
character))
:group 'mu4e)
+(defvar mu4e-bookmarks
+ `( ,(make-mu4e-bookmark
+ :name "Unread messages"
+ :query "flag:unread AND NOT flag:trashed"
+ :key ?u)
+ ,(make-mu4e-bookmark
+ :name "Today's messages"
+ :query "date:today..now"
+ :key ?t)
+ ,(make-mu4e-bookmark
+ :name "Last 7 days"
+ :query "date:7d..now"
+ :key ?w)
+ ,(make-mu4e-bookmark
+ :name "Messages with images"
+ :query "mime:image/*"
+ :key ?p))
+ "A list of pre-defined queries. Each query is represented by a
+mu4e-bookmark structure with parameters @t{:name} with the name
+of the bookmark, @t{:query} with the query expression (a query
+string or an s-expression that evaluates to query string) and a
+@t{:key}, which is the shortcut-key for the query.
+
+An older form of bookmark, a 3-item list with (QUERY DESCRIPTION
+KEY) is still recognized as well, for backward-compatibility.")
+
+
(defcustom mu4e-split-view 'horizontal
"How to show messages / headers.
A symbol which is either:
@@ -205,8 +255,10 @@ view buffer."
:type 'boolean
:group 'mu4e)
-(defcustom mu4e-cited-regexp "^ *\\(\\(>+ ?\\)+\\)"
- "Regular expression that determines whether a line is a citation."
+(defcustom mu4e-cited-regexp "^\\(\\([[:alpha:]]+\\)\\|\\( *\\)\\)\\(\\(>+ ?\\)+\\)"
+ "Regular expression that determines whether a line is a
+ citation. This recognizes lines starting with numbers of '>'
+ and spaces as well as citations of the type \"John> ... \"."
:type 'string
:group 'mu4e)
@@ -502,12 +554,12 @@ I.e. a message with the draft flag set."
:group 'mu4e-faces)
(defface mu4e-header-value-face
- '((t :inherit font-lock-doc-face))
+ '((t :inherit font-lock-type-face))
"Face for a header value (such as \"Re: Hello!\")."
:group 'mu4e-faces)
(defface mu4e-special-header-value-face
- '((t :inherit font-lock-variable-name-face))
+ '((t :inherit font-lock-builtin-face))
"Face for special header values."
:group 'mu4e-faces)
@@ -562,7 +614,7 @@ I.e. a message with the draft flag set."
:group 'mu4e-faces)
(defface mu4e-cited-2-face
- '((t :inherit font-lock-type-face :bold nil :italic t))
+ '((t :inherit font-lock-preprocessor-face :bold nil :italic t))
"Face for cited message parts (level 2)."
:group 'mu4e-faces)
@@ -587,7 +639,7 @@ I.e. a message with the draft flag set."
:group 'mu4e-faces)
(defface mu4e-cited-7-face
- '((t :inherit font-lock-preprocessor-face :bold nil :italic t))
+ '((t :inherit font-lock-type-face :bold nil :italic t))
"Face for cited message parts (level 7)."
:group 'mu4e-faces)
@@ -719,6 +771,11 @@ mu4e-compose-mode."
( :name "To"
:shortname "To"
:help "Recipient of the message"
+ :sortable t))
+ (:user-agent .
+ ( :name "User-Agent"
+ :shortname "UA"
+ :help "Program used for writing this message"
:sortable t)))
"An alist of all possible header fields and information about them.
This is used in the user-interface (the column headers in the header list, and
diff --git a/_spacemacs.d/local/mu4e/mu4e-view.el b/_spacemacs.d/local/mu4e/mu4e-view.el
index 75fc79f..564835d 100644
--- a/_spacemacs.d/local/mu4e/mu4e-view.el
+++ b/_spacemacs.d/local/mu4e/mu4e-view.el
@@ -203,9 +203,10 @@ found."
(lambda (field)
(let ((fieldval (mu4e-message-field msg field)))
(case field
- (:subject (mu4e~view-construct-header field fieldval))
- (:path (mu4e~view-construct-header field fieldval))
- (:maildir (mu4e~view-construct-header field fieldval))
+ (:subject (mu4e~view-construct-header field fieldval))
+ (:path (mu4e~view-construct-header field fieldval))
+ (:maildir (mu4e~view-construct-header field fieldval))
+ (:user-agent (mu4e~view-construct-header field fieldval))
((:flags :tags) (mu4e~view-construct-flags-tags-header
field fieldval))
diff --git a/_spacemacs.d/local/mu4e/mu4e.el b/_spacemacs.d/local/mu4e/mu4e.el
index fd01875..b605cb9 100644
--- a/_spacemacs.d/local/mu4e/mu4e.el
+++ b/_spacemacs.d/local/mu4e/mu4e.el
@@ -38,6 +38,15 @@
(require 'mu4e-context) ;; support for contexts
(require 'mu4e-speedbar) ;; support for speedbar
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; we can't properly use compose buffers that are revived using
+;; desktop-save-mode; so let's turn that off
+(require 'desktop)
+(add-to-list 'desktop-modes-not-to-save 'mu4e-compose-mode)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; register our handler functions; these connect server messages to functions
diff --git a/_spacemacs.d/local/mu4e/org-mu4e.el b/_spacemacs.d/local/mu4e/org-mu4e.el
index b9e9688..545f566 100644
--- a/_spacemacs.d/local/mu4e/org-mu4e.el
+++ b/_spacemacs.d/local/mu4e/org-mu4e.el
@@ -192,8 +192,6 @@ and images in a multipart/related part."
"Convert the current body to html."
(unless (fboundp 'org-export-string-as)
(mu4e-error "require function 'org-export-string-as not found."))
- (unless (executable-find "dvipng")
- (mu4e-error "Required program dvipng not found"))
(let* ((begin
(save-excursion
(goto-char (point-min))
@@ -209,7 +207,9 @@ and images in a multipart/related part."
;; makes the replies with ">"s look nicer
(org-export-preserve-breaks t)
;; dvipng for inline latex because MathJax doesn't work in mail
- (org-export-with-LaTeX-fragments 'dvipng)
+ (org-export-with-LaTeX-fragments
+ (if (executable-find "dvipng") 'dvipng
+ (mu4e-message "Cannot find dvipng, ignore inline LaTeX") nil))
;; to hold attachments for inline html images
(html-and-images
(org~mu4e-mime-replace-images