mirror of https://github.com/djcb/mu.git
* mu4e: implement automatic refiling with 'r'
This commit is contained in:
parent
bd0cba007b
commit
dde75fbb86
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue