mu4e: Added mu4e-compose-context-switch for draft messages

Allow updating the context for the current draft message.
This commit is contained in:
Al Haji-Ali 2021-02-20 12:04:08 +00:00 committed by Dirk-Jan C. Binnema
parent 775498937d
commit b094da8cd4
3 changed files with 131 additions and 90 deletions

View File

@ -62,7 +62,10 @@
~mu4e-personal-address-p~ to check whether a given string matches a personal
address.
- Completion for writing ~mu~ queries
- TAB-Completion for writing ~mu~ queries
- Switch the context for existing draft messages using
~mu4e-compose-context-switch~ or ~C-c C-;~ in ~mu4e-compose-mode~.
* 1.4 (released, as of April 18 2020)
@ -235,7 +238,7 @@
For now this is experimental ("tech preview"), but might replace the
current message-view in a future release. Enable it with:
(setq mu4e-view-use-gnus t)
(setq mu4e-view-use-gnus t)
Thanks to Christophe Troestler for his work on fixing various encoding
issues.

View File

@ -164,7 +164,7 @@ not a contradiction, but a redundant configuration.
All `sign-*' options have a `encrypt-*' analogue."
:type '(set :greedy t
(const :tag "Sign all messages" sign-all-messages)
(const :tag "Sign all messages" sign-all-messages)
(const :tag "Encrypt all messages" encrypt-all-messages)
(const :tag "Sign new messages" sign-new-messages)
(const :tag "Encrypt new messages" encrypt-new-messages)
@ -446,6 +446,7 @@ removing the In-Reply-To header."
(setq mu4e-compose-mode-map
(let ((map (make-sparse-keymap)))
(define-key map (kbd "C-S-u") 'mu4e-update-mail-and-index)
(define-key map (kbd "C-c C-;") 'mu4e-compose-context-switch)
(define-key map (kbd "C-c C-u") 'mu4e-update-mail-and-index)
(define-key map (kbd "C-c C-k") 'mu4e-message-kill-buffer)
(define-key map (kbd "M-q") 'mu4e-fill-paragraph)
@ -788,6 +789,42 @@ tempfile)."
;; if all else fails, back to the main view
(when (fboundp 'mu4e) (mu4e))))))
(defun mu4e-compose-context-switch (&optional force name)
"Change the context for the current draft message.
Same as `mu4e-context-switch' but does two things after switching
when the buffer is in `mu4e-compose-mode':
- Changes the \"From\" field to the email address of the new context
- Moves the current message to the draft folder of the new context"
(interactive "P")
(if (derived-mode-p 'mu4e-compose-mode)
(let ((old-context (mu4e-context-current))
(has-file (file-exists-p (buffer-file-name))))
(unless (and name (not force) (eq old-context name))
(when (or (not has-file)
(not (buffer-modified-p))
(y-or-n-p "Draft must be saved before switching context. Save?"))
(unless (and (not force) (eq old-context (mu4e-context-switch nil name)))
;; Change From field to user-mail-address
(message-replace-header "From" (or (mu4e~draft-from-construct) ""))
;; Move message to mu4e-draft-folder
(if has-file
(progn (save-buffer)
(let ((msg-id (message-fetch-field "Message-ID"))
(buf (current-buffer)))
;; Remove the <>
(when (and msg-id (string-match "<\\(.*\\)>" msg-id))
(save-window-excursion
(mu4e~proc-move (match-string 1 msg-id) mu4e-drafts-folder nil t)
(kill-buffer buf))))) ;; Kill previous buffer which points to wrong file
;; No file, just change the buffer file name
(setq buffer-file-name
(format "%s/%s/cur/%s"
(mu4e-root-maildir) (mu4e-get-drafts-folder)
(file-name-nondirectory (buffer-file-name)))))))))
;; Just do the standad switch
(mu4e-context-switch force name)))
(defun mu4e-sent-handler (docid path)
"Handler called with DOCID and PATH for the just-sent message.
For Forwarded ('Passed') and Replied messages, try to set the

View File

@ -753,34 +753,34 @@ The main view looks something like the following:
Basics
* [j]ump to some maildir
* enter a [s]earch query
* [C]ompose a new message
* [j]ump to some maildir
* enter a [s]earch query
* [C]ompose a new message
Bookmarks
* [bu] Unread messages (26119/26119)
* [bt] Today's messages (1/7)
* [bw] Last 7 days (30/126)
* [bp] Messages with images (268/2309)
* [bu] Unread messages (26119/26119)
* [bt] Today's messages (1/7)
* [bw] Last 7 days (30/126)
* [bp] Messages with images (268/2309)
Maildirs
* [ja] /archive (3174/17990)
* [ji] /inbox (0/2)
* [jm] /mu (1541/14884)
* [js] /sent
* [ja] /archive (3174/17990)
* [ji] /inbox (0/2)
* [jm] /mu (1541/14884)
* [js] /sent
Misc
* [;]Switch context
* [U]pdate email & database
* toggle [m]ail sending mode (currently direct)
* [;]Switch context
* [U]pdate email & database
* toggle [m]ail sending mode (currently direct)
* [N]ews
* [A]bout mu4e
* [H]elp
* [q]uit
* [N]ews
* [A]bout mu4e
* [H]elp
* [q]uit
Info
@ -1508,8 +1508,8 @@ long messages in some external browser (see `browse-url-generic-program')."
(let ((html (or (mu4e-message-field msg :body-html) "")))
(if (> (length html) 20000)
(progn
(mu4e-action-view-in-browser msg)
"[Viewing message in external browser]")
(mu4e-action-view-in-browser msg)
"[Viewing message in external browser]")
(mu4e-shr2text msg))))
(setq mu4e-html2text-command 'my-mu4e-html2text)
@ -1697,6 +1697,7 @@ C-c C-c send message
C-c C-d save to drafts and leave
C-c C-k kill the message buffer (the message remains in the draft folder)
C-c C-a attach a file (pro-tip: drag & drop works as well)
C-c C-; switch the context
(mu4e-specific)
C-S-u update mail & reindex
@ -1773,13 +1774,13 @@ Let's look at some examples. First, suppose we want to set the
"Set the From address based on the To address of the original."
(let ((msg mu4e-compose-parent-message)) ;; msg is shorter...
(when msg
(setq user-mail-address
(cond
((mu4e-message-contact-field-matches msg :to "me@@foo.example.com")
"me@@foo.example.com")
((mu4e-message-contact-field-matches msg :to "me@@bar.example.com")
"me@@bar.example.com")
(t "me@@cuux.example.com")))))))
(setq user-mail-address
(cond
((mu4e-message-contact-field-matches msg :to "me@@foo.example.com")
"me@@foo.example.com")
((mu4e-message-contact-field-matches msg :to "me@@bar.example.com")
"me@@bar.example.com")
(t "me@@cuux.example.com")))))))
@end lisp
Secondly, as mentioned, @code{mu4e-compose-mode-hook} is especially
@ -1810,12 +1811,12 @@ Or to something context-specific:
(add-hook 'mu4e-compose-mode-hook
(lambda()
(let* ((ctx (mu4e-context-current))
(name (if ctx (mu4e-context-name ctx))))
(name (if ctx (mu4e-context-name ctx))))
(when name
(cond
((string= name "account1")
(cond
((string= name "account1")
(save-excursion (message-add-header "Bcc: account1@@example.com\n")))
((string= name "account2")
((string= name "account2")
(save-excursion (message-add-header "Bcc: account2@@example.com\n"))))))))
@end lisp
@ -2434,7 +2435,7 @@ than @emph{n} recipients --- we could do this with the following recipe:
'("More than n recipients"
(lambda (msg n)
(> (+ (length (mu4e-message-field msg :to))
(length (mu4e-message-field msg :cc))) n))
(length (mu4e-message-field msg :cc))) n))
(lambda ()
(read-number "Match messages with more recipients than: "))) t)
@end lisp
@ -2498,7 +2499,7 @@ loading @t{mu4e}):
:prompt "gtag"
:ask-target (lambda () (read-string "What tag do you want to add?"))
:action (lambda (docid msg target)
(mu4e-action-retag-message msg (concat "+" target)))))
(mu4e-action-retag-message msg (concat "+" target)))))
@end lisp
As another example, suppose we would like to ``archive and mark read''
@ -2512,10 +2513,10 @@ loading @t{mu4e}):
:prompt "Archive"
:show-target (lambda (target) "archive")
:action (lambda (docid msg target)
;; must come before proc-move since retag runs
;; 'sed' on the file
(mu4e-action-retag-message msg "-\\Inbox")
(mu4e~proc-move docid nil "+S-u-N"))))
;; must come before proc-move since retag runs
;; 'sed' on the file
(mu4e-action-retag-message msg "-\\Inbox")
(mu4e~proc-move docid nil "+S-u-N"))))
@end lisp
Adding to @code{mu4e-marks} list allows to use the mark in bulk operations
@ -2666,48 +2667,48 @@ when starting; see the discussion in the previous section.
(setq mu4e-contexts
`( ,(make-mu4e-context
:name "Private"
:enter-func (lambda () (mu4e-message "Entering Private context"))
:name "Private"
:enter-func (lambda () (mu4e-message "Entering Private context"))
:leave-func (lambda () (mu4e-message "Leaving Private context"))
;; we match based on the contact-fields of the message
:match-func (lambda (msg)
(when msg
(mu4e-message-contact-field-matches msg
:to "aliced@@home.example.com")))
:vars '( ( user-mail-address . "aliced@@home.example.com" )
( user-full-name . "Alice Derleth" )
( mu4e-compose-signature .
(concat
"Alice Derleth\n"
"Lauttasaari, Finland\n"))))
;; we match based on the contact-fields of the message
:match-func (lambda (msg)
(when msg
(mu4e-message-contact-field-matches msg
:to "aliced@@home.example.com")))
:vars '( ( user-mail-address . "aliced@@home.example.com" )
( user-full-name . "Alice Derleth" )
( mu4e-compose-signature .
(concat
"Alice Derleth\n"
"Lauttasaari, Finland\n"))))
,(make-mu4e-context
:name "Work"
:enter-func (lambda () (mu4e-message "Switch to the Work context"))
;; no leave-func
;; we match based on the maildir of the message
;; this matches maildir /Arkham and its sub-directories
:match-func (lambda (msg)
(when msg
(string-match-p "^/Arkham" (mu4e-message-field msg :maildir))))
:vars '( ( user-mail-address . "aderleth@@miskatonic.example.com" )
( user-full-name . "Alice Derleth" )
( mu4e-compose-signature .
(concat
"Prof. Alice Derleth\n"
"Miskatonic University, Dept. of Occult Sciences\n"))))
:name "Work"
:enter-func (lambda () (mu4e-message "Switch to the Work context"))
;; no leave-func
;; we match based on the maildir of the message
;; this matches maildir /Arkham and its sub-directories
:match-func (lambda (msg)
(when msg
(string-match-p "^/Arkham" (mu4e-message-field msg :maildir))))
:vars '( ( user-mail-address . "aderleth@@miskatonic.example.com" )
( user-full-name . "Alice Derleth" )
( mu4e-compose-signature .
(concat
"Prof. Alice Derleth\n"
"Miskatonic University, Dept. of Occult Sciences\n"))))
,(make-mu4e-context
:name "Cycling"
:enter-func (lambda () (mu4e-message "Switch to the Cycling context"))
;; no leave-func
;; we match based on the maildir of the message; assume all
;; cycling-related messages go into the /cycling maildir
:match-func (lambda (msg)
(when msg
(string= (mu4e-message-field msg :maildir) "/cycling")))
:vars '( ( user-mail-address . "aderleth@@example.com" )
( user-full-name . "AliceD" )
( mu4e-compose-signature . nil)))))
:name "Cycling"
:enter-func (lambda () (mu4e-message "Switch to the Cycling context"))
;; no leave-func
;; we match based on the maildir of the message; assume all
;; cycling-related messages go into the /cycling maildir
:match-func (lambda (msg)
(when msg
(string= (mu4e-message-field msg :maildir) "/cycling")))
:vars '( ( user-mail-address . "aderleth@@example.com" )
( user-full-name . "AliceD" )
( mu4e-compose-signature . nil)))))
;; set `mu4e-context-policy` and `mu4e-compose-policy` to tweak when mu4e should
;; guess or ask the correct context, e.g.
@ -2797,19 +2798,19 @@ message. An example should clarify this:
(cond
;; messages to the mu mailing list go to the /mu folder
((mu4e-message-contact-field-matches msg :to
"mu-discuss@@googlegroups.com")
"/mu")
"mu-discuss@@googlegroups.com")
"/mu")
;; messages sent directly to some spefic address me go to /private
((mu4e-message-contact-field-matches msg :to "me@@example.com")
"/private")
"/private")
;; messages with football or soccer in the subject go to /football
((string-match "football\\|soccer"
(mu4e-message-field msg :subject))
"/football")
(mu4e-message-field msg :subject))
"/football")
;; messages sent by me go to the sent folder
((mu4e-message-sent-by-me msg
(mu4e-personal-addresses))
mu4e-sent-folder)
(mu4e-personal-addresses))
mu4e-sent-folder)
;; everything else goes to /archive
;; important to have a catch-all at the end!
(t "/archive"))))
@ -3126,7 +3127,7 @@ point. Requires the 'formail' tool from procmail."
(replace-regexp-in-string "\n$" ""
(shell-command-to-string
(concat "formail -x " hdr " -c < "
(shell-quote-argument (mu4e-message-field-at-point :path))))))
(shell-quote-argument (mu4e-message-field-at-point :path))))))
@end lisp
@subsection Rewriting the message body
@ -3529,10 +3530,10 @@ well; so put in your configuration:
(let (buffers)
(save-current-buffer
(dolist (buffer (buffer-list t))
(set-buffer buffer)
(when (and (derived-mode-p 'message-mode)
(null message-sent-message-via))
(push (buffer-name buffer) buffers))))
(set-buffer buffer)
(when (and (derived-mode-p 'message-mode)
(null message-sent-message-via))
(push (buffer-name buffer) buffers))))
(nreverse buffers)))
(setq gnus-dired-mail-mode 'mu4e-user-agent)