mu4e: support message-action when marking 'deferred'

When marking headers as 'deferred' (with '*'), and executing them ('x'),
you can now also apply arbitrary header actions to them.
This commit is contained in:
djcb 2015-04-26 17:09:06 +03:00
parent 7eb244b3b0
commit 976711c16c
3 changed files with 107 additions and 91 deletions

View File

@ -563,6 +563,7 @@ after the end of the search results."
(mu4e~headers-defun-mark-for untrash)
(mu4e~headers-defun-mark-for unmark)
(mu4e~headers-defun-mark-for unread)
(mu4e~headers-defun-mark-for action)
;;; headers-mode and mode-map ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -636,6 +637,7 @@ after the end of the search results."
(define-key map (kbd "?") 'mu4e-headers-mark-for-unread)
(define-key map (kbd "!") 'mu4e-headers-mark-for-read)
(define-key map (kbd "A") 'mu4e-headers-mark-for-action)
(define-key map (kbd "u") 'mu4e-headers-mark-for-unmark)
(define-key map (kbd "+") 'mu4e-headers-mark-for-flag)
@ -1514,13 +1516,15 @@ do nothing."
(interactive "P")
(mu4e-headers-split-view-grow (- (or n 1))))
(defun mu4e-headers-action ()
(defun mu4e-headers-action (&optional actionfunc)
"Ask user what to do with message-at-point, then do it.
The actions are specified in `mu4e-headers-actions'."
The actions are specified in `mu4e-headers-actions'. Optionally,
pass ACTIONFUNC, which is a function that takes a msg-plist
argument."
(interactive)
(let ((msg (mu4e-message-at-point))
(actionfunc (mu4e-read-option "Action: " mu4e-headers-actions)))
(funcall actionfunc msg)))
(afunc (or actionfunc (mu4e-read-option "Action: " mu4e-headers-actions))))
(funcall afunc msg)))
(defun mu4e-headers-mark-and-next (mark)
"Set mark MARK on the message at point or on all messages in the

View File

@ -141,7 +141,7 @@ properties are:
(unless mu4e-marks
(setq mu4e-marks
'((refile
'((refile
:char "r"
:prompt "refile"
:dyn-target (lambda (target msg) (mu4e-get-refile-folder msg))
@ -190,6 +190,14 @@ properties are:
:char " "
:prompt "unmark"
:action (mu4e-error "No action for unmarking"))
(action
:char "a"
:prompt "action"
:ask-target (lambda () (mu4e-read-option "Action: " mu4e-headers-actions))
:action (lambda (docid msg actionfunc)
(save-excursion
(when (mu4e~headers-goto-docid docid)
(mu4e-headers-action actionfunc)))))
(something
:char "*"
:prompt "*something"
@ -218,7 +226,8 @@ The following marks are available, and the corresponding props:
`unflag' n mark this message for unflagging
`untrash' n remove the 'trashed' flag from a message
`unmark' n unmark this message
`unread' n mark the message as unread"
`unread' n mark the message as unread
`action' y mark the message for some action."
(interactive)
(let* ((msg (mu4e-message-at-point))
(docid (mu4e-message-field msg :docid))
@ -231,7 +240,7 @@ The following marks are available, and the corresponding props:
(show-fct (plist-get markdesc :show-target))
(shown-target (if show-fct
(funcall show-fct target)
target)))
(if target (format "%S" target)))))
(unless docid (mu4e-warn "No message on this line"))
(unless (eq major-mode 'mu4e-headers-mode) (mu4e-error "Not in headers-mode"))
(save-excursion
@ -261,7 +270,7 @@ The following marks are available, and the corresponding props:
(defun mu4e~mark-get-move-target ()
"Ask for a move target, and propose to create it if it does not exist."
(interactive)
;; (mu4e-message-at-point) ;; raises error if there is none
;; (mu4e-message-at-point) ;; raises error if there is none
(let* ((target (mu4e-ask-maildir "Move message to: "))
(target (if (string= (substring target 0 1) "/")
target
@ -315,11 +324,13 @@ headers in the region. Optionally, provide TARGET (for moves)."
"Ask user for a mark; return (MARK . TARGET).
If ALLOW-SOMETHING is non-nil, allow the 'something' pseudo mark
as well."
(let* ((marks (mapcar (lambda (markdescr) (cons (plist-get (cdr markdescr) :prompt) (car markdescr))) mu4e-marks))
(let* ((marks (mapcar (lambda (markdescr)
(cons (plist-get (cdr markdescr) :prompt)
(car markdescr)))
mu4e-marks))
(marks
(if allow-something
marks
(assq-delete-all 'something marks)))
marks (remove-if (lambda (m) (eq 'something (cdr m))) marks)))
(mark (mu4e-read-option prompt marks))
(target (mu4e~mark-ask-target mark)))
(cons mark target)))
@ -351,7 +362,6 @@ user which one)."
(mu4e-error "Target dir %s does not exist " fulltarget)
target)))
(defun mu4e-mark-execute-all (&optional no-confirmation)
"Execute the actions for all marked messages in this buffer.
After the actions have been executed succesfully, the affected

View File

@ -2050,7 +2050,7 @@ mu4e-headers-mark-subthread}, respectively
@cartouche
@verbatim
mark for/as | keybinding | description
--------------+-------------+--------------------------
--------------+-------------+------------------------------
'something' | *, <insert> | mark now, decide later
delete | D, <delete> | delete
flag | + | mark as 'flagged' ('starred')
@ -2063,6 +2063,7 @@ mu4e-headers-mark-subthread}, respectively
unmark | u | remove mark at point
unmark all | U | remove all marks
unread | ? | marks as unread
action | a | apply some action
@end verbatim
@end cartouche
@ -2073,14 +2074,15 @@ messages, this slows things down significantly@footnote{this uses an
in a buffer}. For this reason, you can disable this by setting
@code{mu4e-headers-show-target} to @code{nil}.
@t{something} is a special kind of mark; you can use it to mark messages for
'something', and then decide later what the 'something' should
be@footnote{This kind of 'deferred marking' is similar to the facility in
@t{midnight commander} (@url{http://www.midnight-commander.org/}) and the
like, and uses the same key binding (@key{insert}).} Later, you can set the
actual mark using @kbd{M-x mu4e-mark-resolve-deferred-marks}
(@key{#}). Alternatively, @t{mu4e} will ask you when you try to execute the
marks (@key{x}).
@t{something} is a special kind of mark; you can use it to mark messages
for 'something', and then decide later what the 'something' should
be@footnote{This kind of 'deferred marking' is similar to the facility
in @t{dired}, @t{midnight commander}
(@url{http://www.midnight-commander.org/}) and the like, and uses the
same key binding (@key{insert}).} Later, you can set the actual mark
using @kbd{M-x mu4e-mark-resolve-deferred-marks}
(@key{#}). Alternatively, @t{mu4e} will ask you when you try to execute
the marks (@key{x}).
@node Executing the marks
@section Executing the marks