* 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 ;; 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 ;; since `mu4e~headers-defun-mark-func' is a macro, the argument must be a
;; literal value. ;; 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 delete)
(mu4e~headers-defun-mark-func flag)
(mu4e~headers-defun-mark-func move) (mu4e~headers-defun-mark-func move)
(mu4e~headers-defun-mark-func read) (mu4e~headers-defun-mark-func read)
(mu4e~headers-defun-mark-func unread) (mu4e~headers-defun-mark-func trash)
(mu4e~headers-defun-mark-func flag)
(mu4e~headers-defun-mark-func unflag) (mu4e~headers-defun-mark-func unflag)
(mu4e~headers-defun-mark-func deferred)
(mu4e~headers-defun-mark-func unmark) (mu4e~headers-defun-mark-func unmark)
(mu4e~headers-defun-mark-func unread)
;;; headers-mode and mode-map ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 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 "<deletechar>") 'mu4e~headers-mark-delete)
(define-key map (kbd "D") '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 "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 "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 "u") 'mu4e~headers-mark-unmark)
(define-key map (kbd "+") 'mu4e~headers-mark-flag) (define-key map (kbd "+") 'mu4e~headers-mark-flag)
(define-key map (kbd "-") 'mu4e~headers-mark-unflag) (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 "x" 'mu4e-mark-execute-all)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(define-key map "a" 'mu4e-headers-action) (define-key map "A" 'mu4e-headers-action)
;; message composition ;; message composition
(define-key map "R" 'mu4e-compose-reply) (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 MARK TARGET description
---------------------------------------------------------- ----------------------------------------------------------
`move' y move the message to some folder `refile' y mark this message for archiving
`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
`deferred' n mark this message for *something* (decided later) `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) (interactive)
(let* ((msg (mu4e-message-at-point)) (let* ((msg (mu4e-message-at-point))
(docid (mu4e-message-field msg :docid)) (docid (mu4e-message-field msg :docid))
@ -110,15 +111,16 @@ The following marks are available, and the corresponding props:
;; info for the user. ;; info for the user.
(markcell (markcell
(case mark (case mark
(move `("m" . ,target)) (refile `("r" . ,target))
(trash `("d" . ,target))
(delete '("D" . "delete"))
(unread '("o" . "unread"))
(read '("r" . "read"))
(flag '("+" . "flag"))
(unflag '("-" . "unflag"))
(deferred '("*" . "deferred")) (deferred '("*" . "deferred"))
(delete '("D" . "delete"))
(flag '("+" . "flag"))
(move `("m" . ,target))
(read '("r" . "read"))
(trash `("d" . ,target))
(unflag '("-" . "unflag"))
(unmark '(" " . nil)) (unmark '(" " . nil))
(unread '("o" . "unread"))
(otherwise (mu4e-error "Invalid mark %S" mark)))) (otherwise (mu4e-error "Invalid mark %S" mark))))
(markkar (car markcell)) (markkar (car markcell))
(target (cdr markcell))) (target (cdr markcell)))
@ -148,7 +150,6 @@ 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 (&optional target)
"Mark message at point or, if region is active, all messages in "Mark message at point or, if region is active, all messages in
the region, for moving to maildir TARGET. If target is not 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)." headers in the region. Optionally, provide TARGET (for moves)."
(let ((target ;; ask or check the target if it's a move (let ((target ;; ask or check the target if it's a move
(case mark (case mark
('move (mu4e~mark-get-move-target target)) ('refile (mu4e-get-refile-folder (mu4e-message-at-point)))
('trash (mu4e-get-trash-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)) (if (not (use-region-p))
;; single message ;; single message
(mu4e-mark-at-point mark target) (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))) (let ((b (region-beginning)) (e (region-end)))
(goto-char b) (goto-char b)
(while (<= (line-beginning-position) e) (while (<= (line-beginning-position) e)
;; trash folder is determined for each message (setq target ;; refile/trash targets are determined per-message
(when (eq mark 'trash) ;; determine the message-specific trash folder (case mark
(setq target (mu4e-get-trash-folder (mu4e-message-at-point)))) (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) (mu4e-mark-at-point mark target)
(forward-line 1))))))) (forward-line 1)))))))
@ -196,11 +200,11 @@ headers in the region. Optionally, provide TARGET (for moves)."
(when (mu4e~headers-goto-docid docid) (when (mu4e~headers-goto-docid docid)
(mu4e-mark-at-point (car markcell) (cdr markcell))))))) (mu4e-mark-at-point (car markcell) (cdr markcell)))))))
(defun mu4e~mark-get-markpair (prompt &optional allow-deferred) (defun mu4e~mark-get-markpair (prompt &optional allow-deferred)
"Ask user for a mark; return (MARK . TARGET). If ALLOW-DEFERRED "Ask user for a mark; return (MARK . TARGET). If ALLOW-DEFERRED
is non-nil, allow the 'deferred' pseudo mark as well." is non-nil, allow the 'deferred' pseudo mark as well."
(let* ((marks '(("move" . move) (let* ((marks '( ("refile" . refile)
("move" . move)
("dtrash" . trash) ("dtrash" . trash)
("Delete" . delete) ("Delete" . delete)
("ounread" . unread) ("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, ;; note: whenever you do something with the message,
;; it looses its N (new) flag ;; it looses its N (new) flag
(case mark (case mark
(move (mu4e~proc-move docid target "-N")) (refile (mu4e~proc-move docid target "-N"))
(read (mu4e~proc-move docid nil "+S-u-N")) (delete (mu4e~proc-remove docid))
(unread (mu4e~proc-move docid nil "-S+u-N")) (flag (mu4e~proc-move docid nil "+F-u-N"))
(flag (mu4e~proc-move docid nil "+F-u-N")) (move (mu4e~proc-move docid target "-N"))
(unflag (mu4e~proc-move docid nil "-F-N")) (read (mu4e~proc-move docid nil "+S-u-N"))
(trash (mu4e~proc-move docid target "+T-N")) (trash (mu4e~proc-move docid target "+T-N"))
(delete (mu4e~proc-remove docid)) (unflag (mu4e~proc-move docid nil "-F-N"))
(unread (mu4e~proc-move docid nil "-S+u-N"))
(otherwise (mu4e-error "Unrecognized mark %S" mark))))) (otherwise (mu4e-error "Unrecognized mark %S" mark)))))
mu4e~mark-map)) mu4e~mark-map))
(mu4e-mark-unmark-all) (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 ;; the standard folders can be functions too
(defun mu4e~get-folder (foldervar msg) (defun mu4e~get-folder (foldervar msg)
"Get message folder FOLDER. If FOLDER is a string, return it, if "Get message folder FOLDER. If FOLDER is a string, return it, if
it is a function, evaluate this function with MSG as it is a function, evaluate this function with MSG as
parameter (which may be `nil'), and return the result." parameter (which may be `nil'), and return the result."
(unless (member foldervar '(mu4e-sent-folder mu4e-drafts-folder (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-error "Folder must be either mu4e-sent-folder,
mu4e-drafts-folder or mu4e-trash-folder (not %S)" foldervar)) mu4e-drafts-folder or mu4e-trash-folder (not %S)" foldervar))
(let* ((folder (symbol-value 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))))) (t (error "unsupported type for %S" folder)))))
(or val (mu4e-error "%S evaluates to nil" foldervar)))) (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) (defun mu4e-get-drafts-folder (msg)
"Get the sent folder. See `mu4e-drafts-folder'." "Get the sent folder. See `mu4e-drafts-folder'."
(mu4e~get-folder 'mu4e-drafts-folder msg)) (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) (defun mu4e-get-trash-folder (msg)
"Get the sent folder. See `mu4e-trash-folder'." "Get the sent folder. See `mu4e-trash-folder'."
(mu4e~get-folder 'mu4e-trash-folder msg)) (mu4e~get-folder 'mu4e-trash-folder msg))

View File

@ -209,18 +209,27 @@ regexp."
"Special folders." "Special folders."
:group 'mu4e) :group 'mu4e)
(defcustom mu4e-sent-folder "/sent" (defcustom mu4e-drafts-folder "/drafts"
"Your folder for sent messages, relative to `mu4e-maildir', "Your folder for draft messages, relative to `mu4e-maildir',
e.g. \"/Sent Items\". Instead of a string, may also be a function e.g. \"/drafts\". Instead of a string, may also be a function
that takes a msg (see `mu4e-message-get-field'), and returns a that takes a msg (see `mu4e-message-get-field'), and returns a
folder." folder."
:type 'string :type 'string
:safe 'stringp :safe 'stringp
:group 'mu4e-folders) :group 'mu4e-folders)
(defcustom mu4e-drafts-folder "/drafts" (defcustom mu4e-refile-folder "/archive"
"Your folder for draft messages, relative to `mu4e-maildir', "Your folder for refiling messages, relative to `mu4e-maildir',
e.g. \"/drafts\". Instead of a string, may also be a function 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 that takes a msg (see `mu4e-message-get-field'), and returns a
folder." folder."
:type 'string :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 "<deletechar>") 'mu4e-mark-for-delete)
(define-key map (kbd "D") 'mu4e-view-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 "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-custom)
(define-key map (kbd "+") 'mu4e-view-mark-flag) (define-key map (kbd "+") 'mu4e-view-mark-flag)
@ -557,9 +559,7 @@ at POINT, or if nil, at (point)."
;; misc ;; misc
(define-key map "w" 'longlines-mode) (define-key map "w" 'longlines-mode)
(define-key map "h" 'mu4e-view-toggle-hide-cited) (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 ;; 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)
(define-key map "U" 'mu4e-view-unmark-all) (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-mark-set 'trash)
(mu4e-view-headers-next)) (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 () (defun mu4e-view-mark-for-delete ()
"Mark the current message for deletion." "Mark the current message for deletion."
(interactive) (interactive)