mirror of https://github.com/djcb/mu.git
mu4e: marks: clarify the way targets are obtained.
:get-target is split into: - :ask-target (run once per bulk operation) - :dyn-target (run once per message) A side benefit is that the existence of the target of a move is not checked for every message when doing bulk moves.
This commit is contained in:
parent
3981f5412f
commit
818eedf59f
|
@ -127,22 +127,24 @@ properties are:
|
||||||
:char The character to display in the headers view
|
:char The character to display in the headers view
|
||||||
:prompt The prompt to use when asking for marks (used for
|
:prompt The prompt to use when asking for marks (used for
|
||||||
example when marking a whole thread)
|
example when marking a whole thread)
|
||||||
:get-target The function to obtain the target for the mark
|
:ask-target Get the target. This function run once per
|
||||||
action, or nil if the action requires no target.
|
bulk-operation, and thus is suitable for user-interaction.
|
||||||
|
If nil, the target is nil.
|
||||||
|
:dyn-target Compute the dynamic target. This is run once per
|
||||||
|
message, which is passed as an argument. If nil, the target
|
||||||
|
is not touched.
|
||||||
:show-target How to display the target.
|
:show-target How to display the target.
|
||||||
:action The action to apply on the message.
|
:action The action to apply on the message.
|
||||||
")
|
")
|
||||||
|
|
||||||
;; TODO: the arguments taken by the various functions should probably
|
;; TODO: The actions should probably get the
|
||||||
;; be different. 1. It appears that the TARGET argument of
|
|
||||||
;; :get-target is always nil. 2. The actions should probably get the
|
|
||||||
;; message: it contains more info than the docid.
|
;; message: it contains more info than the docid.
|
||||||
(unless mu4e-marks
|
(unless mu4e-marks
|
||||||
(setq mu4e-marks
|
(setq mu4e-marks
|
||||||
`((refile
|
'((refile
|
||||||
:char "r"
|
:char "r"
|
||||||
:prompt "refile"
|
:prompt "refile"
|
||||||
:get-target (lambda (target msg) (mu4e-get-refile-folder msg))
|
:dyn-target (lambda (target msg) (mu4e-get-refile-folder msg))
|
||||||
:show-target (lambda (target) target)
|
:show-target (lambda (target) target)
|
||||||
:action (lambda (docid target) (mu4e~proc-move docid (mu4e~mark-check-target target) "-N")))
|
:action (lambda (docid target) (mu4e~proc-move docid (mu4e~mark-check-target target) "-N")))
|
||||||
(delete
|
(delete
|
||||||
|
@ -158,7 +160,7 @@ properties are:
|
||||||
(move
|
(move
|
||||||
:char "m"
|
:char "m"
|
||||||
:prompt "move"
|
:prompt "move"
|
||||||
:get-target (lambda (target msg) (mu4e~mark-get-move-target target))
|
:ask-target mu4e~mark-get-move-target
|
||||||
:show-target (lambda (target) target)
|
:show-target (lambda (target) target)
|
||||||
:action (lambda (docid target) (mu4e~proc-move docid (mu4e~mark-check-target target) "-N")))
|
:action (lambda (docid target) (mu4e~proc-move docid (mu4e~mark-check-target target) "-N")))
|
||||||
(read
|
(read
|
||||||
|
@ -169,7 +171,7 @@ properties are:
|
||||||
(trash
|
(trash
|
||||||
:char "d"
|
:char "d"
|
||||||
:prompt "dtrash"
|
:prompt "dtrash"
|
||||||
:get-target (lambda (target msg) (mu4e-get-trash-folder msg))
|
:dyn-target (lambda (target msg) (mu4e-get-trash-folder msg))
|
||||||
:show-target (lambda (target) target)
|
:show-target (lambda (target) target)
|
||||||
:action (lambda (docid target) (mu4e~proc-move docid (mu4e~mark-check-target target) "+T-N")))
|
:action (lambda (docid target) (mu4e~proc-move docid (mu4e~mark-check-target target) "+T-N")))
|
||||||
(unflag
|
(unflag
|
||||||
|
@ -200,10 +202,10 @@ properties are:
|
||||||
)))
|
)))
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-mark-at-point (mark &optional target)
|
(defun mu4e-mark-at-point (mark target)
|
||||||
"Mark (or unmark) message at point.
|
"Mark (or unmark) message at point.
|
||||||
MARK specifies the mark-type. For `move'-marks and `trash'-marks
|
MARK specifies the mark-type. For `move'-marks and `trash'-marks
|
||||||
there is also the TARGET argument, which specifies to which
|
the TARGET argument is non-nil and specifies to which
|
||||||
maildir the message is to be moved/trashed. The function works in
|
maildir the message is to be moved/trashed. The function works in
|
||||||
both headers buffers and message buffers.
|
both headers buffers and message buffers.
|
||||||
|
|
||||||
|
@ -230,7 +232,8 @@ The following marks are available, and the corresponding props:
|
||||||
;; info for the user.
|
;; info for the user.
|
||||||
(markdesc (cdr (or (assq mark mu4e-marks) (mu4e-error "Invalid mark %S" mark))))
|
(markdesc (cdr (or (assq mark mu4e-marks) (mu4e-error "Invalid mark %S" mark))))
|
||||||
(markkar (plist-get markdesc :char))
|
(markkar (plist-get markdesc :char))
|
||||||
(target (funcall (plist-get markdesc :show-target) target)))
|
(target (mu4e~mark-get-dyn-target mark target))
|
||||||
|
(shown-target (funcall (plist-get markdesc :show-target) target)))
|
||||||
(unless docid (mu4e-warn "No message on this line"))
|
(unless docid (mu4e-warn "No message on this line"))
|
||||||
(unless (eq major-mode 'mu4e-headers-mode) (mu4e-error "Not in headers-mode"))
|
(unless (eq major-mode 'mu4e-headers-mode) (mu4e-error "Not in headers-mode"))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
|
@ -246,7 +249,7 @@ The following marks are available, and the corresponding props:
|
||||||
;; when we have a target (ie., when moving), show the target folder in
|
;; when we have a target (ie., when moving), show the target folder in
|
||||||
;; an overlay
|
;; an overlay
|
||||||
(when (and target mu4e-headers-show-target)
|
(when (and target mu4e-headers-show-target)
|
||||||
(let* ((targetstr (propertize (concat "-> " target " ")
|
(let* ((targetstr (propertize (concat "-> " shown-target " ")
|
||||||
'face 'mu4e-system-face))
|
'face 'mu4e-system-face))
|
||||||
;; mu4e~headers-goto-docid docid t \will take us just after the
|
;; mu4e~headers-goto-docid docid t \will take us just after the
|
||||||
;; docid cookie and then we skip the mu4e~mark-fringe
|
;; docid cookie and then we skip the mu4e~mark-fringe
|
||||||
|
@ -257,34 +260,40 @@ The following marks are available, and the corresponding props:
|
||||||
docid)))))))
|
docid)))))))
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e~mark-get-move-target (&optional target)
|
(defun mu4e~mark-get-move-target ()
|
||||||
"Ask for a move target, and propose to create it if it does not exist. If TARGET is provided,
|
"Ask for a move target, and propose to create it if it does not exist."
|
||||||
this function merely checks the validity of the move."
|
|
||||||
(interactive)
|
(interactive)
|
||||||
;; (mu4e-message-at-point) ;; raises error if there is none
|
;; (mu4e-message-at-point) ;; raises error if there is none
|
||||||
(let* ((target (or target (mu4e-ask-maildir "Move message to: ")))
|
(let* ((target (mu4e-ask-maildir "Move message to: "))
|
||||||
(target (if (string= (substring target 0 1) "/")
|
(target (if (string= (substring target 0 1) "/")
|
||||||
target
|
target
|
||||||
(concat "/" target)))
|
(concat "/" target)))
|
||||||
(fulltarget (concat mu4e-maildir target)))
|
(fulltarget (concat mu4e-maildir target)))
|
||||||
(when (or (file-directory-p fulltarget)
|
(when (or (file-directory-p fulltarget)
|
||||||
(and (yes-or-no-p
|
(and (yes-or-no-p
|
||||||
(format "%s does not exist. Create now?" fulltarget))
|
(format "%s does not exist. Create now?" fulltarget))
|
||||||
(mu4e~proc-mkdir fulltarget)))
|
(mu4e~proc-mkdir fulltarget)))
|
||||||
target)))
|
target)))
|
||||||
|
|
||||||
(defun mu4e~mark-get-target (mark &optional target)
|
(defun mu4e~mark-ask-target (mark)
|
||||||
"Get the target for MARK, if it is a mark that has a target;
|
"Ask the target for MARK, if the user should be asked the target."
|
||||||
otherwise return nil."
|
(let ((getter (plist-get (cdr (assq mark mu4e-marks)) :ask-target)))
|
||||||
(let ((getter (plist-get (cdr (assq mark mu4e-marks)) :get-target)))
|
(and getter (funcall getter))))
|
||||||
(and getter (funcall getter target (mu4e-message-at-point)))))
|
|
||||||
|
(defun mu4e~mark-get-dyn-target (mark target)
|
||||||
|
"Get the dynamic target for MARK. The result may depend on the
|
||||||
|
message at point."
|
||||||
|
(let ((getter (plist-get (cdr (assq mark mu4e-marks)) :dyn-target)))
|
||||||
|
(if getter
|
||||||
|
(funcall getter target (mu4e-message-at-point))
|
||||||
|
target)))
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-mark-set (mark &optional target)
|
(defun mu4e-mark-set (mark &optional target)
|
||||||
"Mark the header at point, or, if region is active, mark all
|
"Mark the header at point, or, if region is active, mark all
|
||||||
headers in the region. Optionally, provide TARGET (for moves)."
|
headers in the region. Optionally, provide TARGET (for moves)."
|
||||||
(unless target
|
(unless target
|
||||||
(setq target (mu4e~mark-get-target mark target)))
|
(setq target (mu4e~mark-ask-target mark)))
|
||||||
(if (not (use-region-p))
|
(if (not (use-region-p))
|
||||||
;; single message
|
;; single message
|
||||||
(mu4e-mark-at-point mark target)
|
(mu4e-mark-at-point mark target)
|
||||||
|
@ -293,7 +302,6 @@ headers in the region. Optionally, provide TARGET (for moves)."
|
||||||
(let ((cant-go-further) (eor (region-end)))
|
(let ((cant-go-further) (eor (region-end)))
|
||||||
(goto-char (region-beginning))
|
(goto-char (region-beginning))
|
||||||
(while (and (<= (point) eor) (not cant-go-further))
|
(while (and (<= (point) eor) (not cant-go-further))
|
||||||
(setq target (mu4e~mark-get-target mark target))
|
|
||||||
(mu4e-mark-at-point mark target)
|
(mu4e-mark-at-point mark target)
|
||||||
(setq cant-go-further (not (mu4e-headers-next))))))))
|
(setq cant-go-further (not (mu4e-headers-next))))))))
|
||||||
|
|
||||||
|
@ -315,7 +323,7 @@ as well."
|
||||||
marks
|
marks
|
||||||
(assq-delete-all 'something marks)))
|
(assq-delete-all 'something marks)))
|
||||||
(mark (mu4e-read-option prompt marks))
|
(mark (mu4e-read-option prompt marks))
|
||||||
(target (mu4e~mark-get-target mark)))
|
(target (mu4e~mark-ask-target mark)))
|
||||||
(cons mark target)))
|
(cons mark target)))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue