* mu4e: implement automatic refiling with 'r'

This commit is contained in:
djcb 2012-09-27 12:53:16 +03:00
parent bd0cba007b
commit dde75fbb86
5 changed files with 78 additions and 52 deletions

View File

@ -401,15 +401,16 @@ after the end of the search results."
;; define our mark functions; there must be some way to do this in a loop but
;; since `mu4e~headers-defun-mark-func' is a macro, the argument must be a
;; literal value.
(mu4e~headers-defun-mark-func trash)
(mu4e~headers-defun-mark-func refile)
(mu4e~headers-defun-mark-func deferred)
(mu4e~headers-defun-mark-func delete)
(mu4e~headers-defun-mark-func flag)
(mu4e~headers-defun-mark-func move)
(mu4e~headers-defun-mark-func read)
(mu4e~headers-defun-mark-func unread)
(mu4e~headers-defun-mark-func flag)
(mu4e~headers-defun-mark-func trash)
(mu4e~headers-defun-mark-func unflag)
(mu4e~headers-defun-mark-func deferred)
(mu4e~headers-defun-mark-func unmark)
(mu4e~headers-defun-mark-func unread)
;;; headers-mode and mode-map ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -473,9 +474,11 @@ after the end of the search results."
(define-key map (kbd "<deletechar>") 'mu4e~headers-mark-delete)
(define-key map (kbd "D") 'mu4e~headers-mark-delete)
(define-key map (kbd "m") 'mu4e~headers-mark-move)
(define-key map (kbd "r") 'mu4e~headers-mark-refile)
(define-key map (kbd "o") 'mu4e~headers-mark-unread)
(define-key map (kbd "r") 'mu4e~headers-mark-read)
(define-key map (kbd "s") 'mu4e~headers-mark-read)
(define-key map (kbd "u") 'mu4e~headers-mark-unmark)
(define-key map (kbd "+") 'mu4e~headers-mark-flag)
(define-key map (kbd "-") 'mu4e~headers-mark-unflag)
@ -490,7 +493,7 @@ after the end of the search results."
(define-key map "x" 'mu4e-mark-execute-all)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-key map "a" 'mu4e-headers-action)
(define-key map "A" 'mu4e-headers-action)
;; message composition
(define-key map "R" 'mu4e-compose-reply)

View File

@ -93,15 +93,16 @@ The following marks are available, and the corresponding props:
MARK TARGET description
----------------------------------------------------------
`move' y move the message to some folder
`trash' y thrash the message to some folder
`delete' n remove the message
`read' n mark the message as read
`unread' n mark the message as unread
`flag' n mark this message for flagging
`unflag' n mark this message for unflagging
`refile' y mark this message for archiving
`deferred' n mark this message for *something* (decided later)
`unmark' n unmark this message"
`delete' n remove the message
`flag' n mark this message for flagging
`move' y move the message to some folder
`read' n mark the message as read
`trash' y thrash the message to some folder
`unflag' n mark this message for unflagging
`unmark' n unmark this message
`unread' n mark the message as unread"
(interactive)
(let* ((msg (mu4e-message-at-point))
(docid (mu4e-message-field msg :docid))
@ -110,15 +111,16 @@ The following marks are available, and the corresponding props:
;; info for the user.
(markcell
(case mark
(move `("m" . ,target))
(trash `("d" . ,target))
(delete '("D" . "delete"))
(unread '("o" . "unread"))
(read '("r" . "read"))
(flag '("+" . "flag"))
(unflag '("-" . "unflag"))
(refile `("r" . ,target))
(deferred '("*" . "deferred"))
(delete '("D" . "delete"))
(flag '("+" . "flag"))
(move `("m" . ,target))
(read '("r" . "read"))
(trash `("d" . ,target))
(unflag '("-" . "unflag"))
(unmark '(" " . nil))
(unread '("o" . "unread"))
(otherwise (mu4e-error "Invalid mark %S" mark))))
(markkar (car markcell))
(target (cdr markcell)))
@ -148,7 +150,6 @@ The following marks are available, and the corresponding props:
docid)))))))
(defun mu4e~mark-get-move-target (&optional target)
"Mark message at point or, if region is active, all messages in
the region, for moving to maildir TARGET. If target is not
@ -172,8 +173,9 @@ provided, function asks for it."
headers in the region. Optionally, provide TARGET (for moves)."
(let ((target ;; ask or check the target if it's a move
(case mark
('move (mu4e~mark-get-move-target target))
('trash (mu4e-get-trash-folder (mu4e-message-at-point))))))
('refile (mu4e-get-refile-folder (mu4e-message-at-point)))
('move (mu4e~mark-get-move-target target))
('trash (mu4e-get-trash-folder (mu4e-message-at-point))) )))
(if (not (use-region-p))
;; single message
(mu4e-mark-at-point mark target)
@ -182,9 +184,11 @@ headers in the region. Optionally, provide TARGET (for moves)."
(let ((b (region-beginning)) (e (region-end)))
(goto-char b)
(while (<= (line-beginning-position) e)
;; trash folder is determined for each message
(when (eq mark 'trash) ;; determine the message-specific trash folder
(setq target (mu4e-get-trash-folder (mu4e-message-at-point))))
(setq target ;; refile/trash targets are determined per-message
(case mark
(refile (mu4e-get-refile-folder (mu4e-message-at-point)))
(trash (mu4e-get-trash-folder (mu4e-message-at-point)))
(t target)))
(mu4e-mark-at-point mark target)
(forward-line 1)))))))
@ -196,11 +200,11 @@ headers in the region. Optionally, provide TARGET (for moves)."
(when (mu4e~headers-goto-docid docid)
(mu4e-mark-at-point (car markcell) (cdr markcell)))))))
(defun mu4e~mark-get-markpair (prompt &optional allow-deferred)
"Ask user for a mark; return (MARK . TARGET). If ALLOW-DEFERRED
is non-nil, allow the 'deferred' pseudo mark as well."
(let* ((marks '(("move" . move)
(let* ((marks '( ("refile" . refile)
("move" . move)
("dtrash" . trash)
("Delete" . delete)
("ounread" . unread)
@ -263,13 +267,14 @@ If NO-CONFIRMATION is non-nil, don't ask user for confirmation."
;; note: whenever you do something with the message,
;; it looses its N (new) flag
(case mark
(move (mu4e~proc-move docid target "-N"))
(read (mu4e~proc-move docid nil "+S-u-N"))
(unread (mu4e~proc-move docid nil "-S+u-N"))
(flag (mu4e~proc-move docid nil "+F-u-N"))
(unflag (mu4e~proc-move docid nil "-F-N"))
(trash (mu4e~proc-move docid target "+T-N"))
(delete (mu4e~proc-remove docid))
(refile (mu4e~proc-move docid target "-N"))
(delete (mu4e~proc-remove docid))
(flag (mu4e~proc-move docid nil "+F-u-N"))
(move (mu4e~proc-move docid target "-N"))
(read (mu4e~proc-move docid nil "+S-u-N"))
(trash (mu4e~proc-move docid target "+T-N"))
(unflag (mu4e~proc-move docid nil "-F-N"))
(unread (mu4e~proc-move docid nil "-S+u-N"))
(otherwise (mu4e-error "Unrecognized mark %S" mark)))))
mu4e~mark-map))
(mu4e-mark-unmark-all)

View File

@ -67,13 +67,12 @@ hour and minute fields will be nil if not given."
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; the standard folders can be functions too
(defun mu4e~get-folder (foldervar msg)
"Get message folder FOLDER. If FOLDER is a string, return it, if
it is a function, evaluate this function with MSG as
parameter (which may be `nil'), and return the result."
(unless (member foldervar '(mu4e-sent-folder mu4e-drafts-folder
mu4e-trash-folder))
mu4e-trash-folder mu4e-refile-folder))
(mu4e-error "Folder must be either mu4e-sent-folder,
mu4e-drafts-folder or mu4e-trash-folder (not %S)" foldervar))
(let* ((folder (symbol-value foldervar))
@ -84,14 +83,18 @@ parameter (which may be `nil'), and return the result."
(t (error "unsupported type for %S" folder)))))
(or val (mu4e-error "%S evaluates to nil" foldervar))))
(defun mu4e-get-sent-folder (msg)
"Get the sent folder. See `mu4e-sent-folder'."
(mu4e~get-folder 'mu4e-sent-folder msg))
(defun mu4e-get-drafts-folder (msg)
"Get the sent folder. See `mu4e-drafts-folder'."
(mu4e~get-folder 'mu4e-drafts-folder msg))
(defun mu4e-get-refile-folder (msg)
"Get the folder for refiling. See `mu4e-refile-folder'."
(mu4e~get-folder 'mu4e-refile-folder msg))
(defun mu4e-get-sent-folder (msg)
"Get the sent folder. See `mu4e-sent-folder'."
(mu4e~get-folder 'mu4e-sent-folder msg))
(defun mu4e-get-trash-folder (msg)
"Get the sent folder. See `mu4e-trash-folder'."
(mu4e~get-folder 'mu4e-trash-folder msg))

View File

@ -209,18 +209,27 @@ regexp."
"Special folders."
:group 'mu4e)
(defcustom mu4e-sent-folder "/sent"
"Your folder for sent messages, relative to `mu4e-maildir',
e.g. \"/Sent Items\". Instead of a string, may also be a function
(defcustom mu4e-drafts-folder "/drafts"
"Your folder for draft messages, relative to `mu4e-maildir',
e.g. \"/drafts\". Instead of a string, may also be a function
that takes a msg (see `mu4e-message-get-field'), and returns a
folder."
:type 'string
:safe 'stringp
:group 'mu4e-folders)
(defcustom mu4e-drafts-folder "/drafts"
"Your folder for draft messages, relative to `mu4e-maildir',
e.g. \"/drafts\". Instead of a string, may also be a function
(defcustom mu4e-refile-folder "/archive"
"Your folder for refiling messages, relative to `mu4e-maildir',
e.g. \"/Archive\". Instead of a string, may also be a function
that takes a msg (see `mu4e-message-get-field'), and returns a
folder."
:type 'string
:safe 'stringp
:group 'mu4e-folders)
(defcustom mu4e-sent-folder "/sent"
"Your folder for sent messages, relative to `mu4e-maildir',
e.g. \"/Sent Items\". Instead of a string, may also be a function
that takes a msg (see `mu4e-message-get-field'), and returns a
folder."
:type 'string

View File

@ -545,6 +545,8 @@ at POINT, or if nil, at (point)."
(define-key map (kbd "<deletechar>") 'mu4e-mark-for-delete)
(define-key map (kbd "D") 'mu4e-view-mark-for-delete)
(define-key map (kbd "m") 'mu4e-view-mark-for-move)
(define-key map (kbd "r") 'mu4e-view-mark-for-refile)
(define-key map (kbd "&") 'mu4e-view-mark-custom)
(define-key map (kbd "+") 'mu4e-view-mark-flag)
@ -557,9 +559,7 @@ at POINT, or if nil, at (point)."
;; misc
(define-key map "w" 'longlines-mode)
(define-key map "h" 'mu4e-view-toggle-hide-cited)
(define-key map "r" 'mu4e-view-refresh)
;; next 3 only warn user when attempt in the message view
(define-key map "u" 'mu4e-view-unmark)
(define-key map "U" 'mu4e-view-unmark-all)
@ -1104,6 +1104,12 @@ user that unmarking only works in the header list."
(mu4e~view-mark-set 'trash)
(mu4e-view-headers-next))
(defun mu4e-view-mark-for-refile ()
"Mark the current message for refiling."
(interactive)
(mu4e~view-mark-set 'refile)
(mu4e-view-headers-next))
(defun mu4e-view-mark-for-delete ()
"Mark the current message for deletion."
(interactive)