mu4e: use a simple x as the 'fancy' delete mark

The 'fancy' version had some interesting interactions (see #1245), so
this is the easiest way to avoid those.

Also some flycheck fixes.
This commit is contained in:
djcb 2019-03-02 11:46:34 +02:00
parent 31f73b32a7
commit f9b615c3bb
1 changed files with 38 additions and 44 deletions

View File

@ -1,6 +1,6 @@
;; mu4e-mark.el -- part of mu4e, the mu mail user agent ;; mu4e-mark.el -- part of mu4e, the mu mail user agent
;; ;;
;; Copyright (C) 2011-2016 Dirk-Jan C. Binnema ;; Copyright (C) 2011-2019 Dirk-Jan C. Binnema
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl> ;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
@ -25,7 +25,7 @@
;; In this file are function related to marking messages; they assume we are ;; In this file are function related to marking messages; they assume we are
;; currently in the headers buffer. ;; currently in the headers buffer.
;; Code: ;;; Code:
(require 'cl-lib) (require 'cl-lib)
(require 'mu4e-proc) (require 'mu4e-proc)
(require 'mu4e-utils) (require 'mu4e-utils)
@ -36,7 +36,6 @@
(declare-function mu4e~headers-goto-docid "mu4e-headers") (declare-function mu4e~headers-goto-docid "mu4e-headers")
(declare-function mu4e-headers-next "mu4e-headers") (declare-function mu4e-headers-next "mu4e-headers")
(defcustom mu4e-headers-leave-behavior 'ask (defcustom mu4e-headers-leave-behavior 'ask
"What to do when user leaves the headers view. "What to do when user leaves the headers view.
That is when he e.g. quits, refreshes or does a new search. That is when he e.g. quits, refreshes or does a new search.
@ -50,26 +49,27 @@ Value is one of the following symbols:
:group 'mu4e-headers) :group 'mu4e-headers)
(defcustom mu4e-mark-execute-pre-hook nil (defcustom mu4e-mark-execute-pre-hook nil
"Hook run just *before* a mark is applied to a message. The hook function "Hook run just *before* a mark is applied to a message.
is called with two arguments, the mark being executed and the message itself.") The hook function is called with two arguments, the mark being
executed and the message itself."
:type 'hook
:group 'mu4e-headers)
(defvar mu4e-headers-show-target t (defvar mu4e-headers-show-target t
"Whether to show targets (such as '-> delete', '-> /archive') "Whether to show targets (such as '-> delete', '-> /archive')
when marking message. Normally, this is useful information for the when marking message. Normally, this is useful information for the
user, however, when you often mark large numbers (thousands) of user, however, when you often mark large numbers (thousands) of
message, showing the target makes this quite a bit slower (showing message, showing the target makes this quite a bit slower (showing
the target uses an emacs feature called 'overlays', which aren't the target uses an Emacs feature called 'overlays', which aren't
particularly fast).") particularly fast).")
;;; insert stuff;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; insert stuff;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defvar mu4e~mark-map nil (defvar mu4e~mark-map nil
"Map (hash) of docid->markinfo; when a message is marked, the "Contains a mapping of docid->markinfo.
information is added here. When a message is marked, the information is added here. markinfo
markinfo is a cons cell consisting of the following: is a cons cell consisting of the following: \(mark . target)
\(mark . target) where MARK is the type of mark (move, trash, delete)
where TARGET (optional) is the target directory (for 'move')")
MARK is the type of mark (move, trash, delete)
TARGET (optional) is the target directory (for 'move')")
;; the mark-map is specific for the current header buffer ;; the mark-map is specific for the current header buffer
;; currently, there can't be more than one, but we never know what will ;; currently, there can't be more than one, but we never know what will
@ -86,11 +86,11 @@ where
"Format string to set a mark and leave remaining space.") "Format string to set a mark and leave remaining space.")
(defun mu4e~mark-initialize () (defun mu4e~mark-initialize ()
"Initialize the marks subsystem." "Initialize the marks-subsystem."
(set (make-local-variable 'mu4e~mark-map) (make-hash-table))) (set (make-local-variable 'mu4e~mark-map) (make-hash-table)))
(defun mu4e~mark-clear () (defun mu4e~mark-clear ()
"Clear the marks subsystem." "Clear the marks-subsystem."
(clrhash mu4e~mark-map)) (clrhash mu4e~mark-map))
(defun mu4e~mark-find-headers-buffer () (defun mu4e~mark-find-headers-buffer ()
@ -102,8 +102,8 @@ where
(buffer-list))) (buffer-list)))
(defmacro mu4e~mark-in-context (&rest body) (defmacro mu4e~mark-in-context (&rest body)
"Evaluate BODY in the context of the headers buffer in case this "Evaluate BODY in the context of the headers buffer.
is either a headers or view buffer." The current buffer must be either a headers or view buffer."
`(cond `(cond
((eq major-mode 'mu4e-headers-mode) ,@body) ((eq major-mode 'mu4e-headers-mode) ,@body)
((eq major-mode 'mu4e-view-mode) ((eq major-mode 'mu4e-view-mode)
@ -113,7 +113,7 @@ is either a headers or view buffer."
(with-current-buffer (mu4e-get-headers-buffer) (with-current-buffer (mu4e-get-headers-buffer)
(if (mu4e~headers-goto-docid docid) (if (mu4e~headers-goto-docid docid)
,@body ,@body
(mu4e-error "cannot find message in headers buffer.")))))) (mu4e-error "Cannot find message in headers buffer"))))))
(t (t
;; even in other modes (e.g. mu4e-main-mode we try to find ;; even in other modes (e.g. mu4e-main-mode we try to find
;; the headers buffer ;; the headers buffer
@ -122,7 +122,7 @@ is either a headers or view buffer."
(with-current-buffer hbuf ,@body) (with-current-buffer hbuf ,@body)
,@body))))) ,@body)))))
(defvar mu4e-marks (defconst mu4e-marks
'((refile '((refile
:char ("r" . "") :char ("r" . "")
:prompt "refile" :prompt "refile"
@ -130,7 +130,7 @@ is either a headers or view buffer."
:action (lambda (docid msg target) :action (lambda (docid msg target)
(mu4e~proc-move docid (mu4e~mark-check-target target) "-N"))) (mu4e~proc-move docid (mu4e~mark-check-target target) "-N")))
(delete (delete
:char ("D" . "") :char ("D" . "x")
:prompt "Delete" :prompt "Delete"
:show-target (lambda (target) "delete") :show-target (lambda (target) "delete")
:action (lambda (docid msg target) (mu4e~proc-remove docid))) :action (lambda (docid msg target) (mu4e~proc-remove docid)))
@ -195,7 +195,7 @@ properties are:
:char (string) or (basic . fancy) The character to display in :char (string) or (basic . fancy) The character to display in
the headers view. Either a single-character string, or a the headers view. Either a single-character string, or a
dotted-pair cons cell where the second item will be used if dotted-pair cons cell where the second item will be used if
`mu4e-use-fancy-chars' is `t', otherwise we'll use `mu4e-use-fancy-chars' is t, otherwise we'll use
the first one. It can also be a plain string for backwards the first one. It can also be a plain string for backwards
compatibility since we didn't always support compatibility since we didn't always support
`mu4e-use-fancy-chars' here. `mu4e-use-fancy-chars' here.
@ -212,7 +212,6 @@ properties are:
:action (function taking (DOCID MSG TARGET)). The action to :action (function taking (DOCID MSG TARGET)). The action to
apply on the message.") apply on the message.")
(defun mu4e-mark-at-point (mark 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
@ -281,7 +280,6 @@ The following marks are available, and the corresponding props:
(overlay-put overlay 'display targetstr) (overlay-put overlay 'display targetstr)
docid))))))) docid)))))))
(defun mu4e~mark-get-move-target () (defun mu4e~mark-get-move-target ()
"Ask for a move target, and propose to create it if it does not exist." "Ask for a move target, and propose to create it if it does not exist."
(interactive) (interactive)
@ -303,17 +301,16 @@ The following marks are available, and the corresponding props:
(and getter (funcall getter)))) (and getter (funcall getter))))
(defun mu4e~mark-get-dyn-target (mark target) (defun mu4e~mark-get-dyn-target (mark target)
"Get the dynamic target for MARK. The result may depend on the "Get the dynamic TARGET for MARK.
message at point." The result may depend on the message at point."
(let ((getter (plist-get (cdr (assq mark mu4e-marks)) :dyn-target))) (let ((getter (plist-get (cdr (assq mark mu4e-marks)) :dyn-target)))
(if getter (if getter
(funcall getter target (mu4e-message-at-point)) (funcall getter target (mu4e-message-at-point))
target))) 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 with MARK or all in the region.
headers in the region. Optionally, provide TARGET (for moves)." Optionally, provide TARGET (for moves)."
(unless target (unless target
(setq target (mu4e~mark-ask-target mark))) (setq target (mu4e~mark-ask-target mark)))
(if (not (use-region-p)) (if (not (use-region-p))
@ -336,7 +333,7 @@ headers in the region. Optionally, provide TARGET (for moves)."
(mu4e-mark-at-point (car markcell) (cdr markcell))))))) (mu4e-mark-at-point (car markcell) (cdr markcell)))))))
(defun mu4e~mark-get-markpair (prompt &optional allow-something) (defun mu4e~mark-get-markpair (prompt &optional allow-something)
"Ask user for a mark; return (MARK . TARGET). "Ask user with PROMPT for a mark and return (MARK . TARGET).
If ALLOW-SOMETHING is non-nil, allow the 'something' pseudo mark If ALLOW-SOMETHING is non-nil, allow the 'something' pseudo mark
as well." as well."
(let* ((marks (mapcar (lambda (markdescr) (let* ((marks (mapcar (lambda (markdescr)
@ -350,9 +347,8 @@ as well."
(target (mu4e~mark-ask-target mark))) (target (mu4e~mark-ask-target mark)))
(cons mark target))) (cons mark target)))
(defun mu4e-mark-resolve-deferred-marks () (defun mu4e-mark-resolve-deferred-marks ()
"Check if there are any deferred ('something') marks. "Check if there are any deferred ('something') mark-instances.
If there are such marks, replace them with a _real_ mark (ask the If there are such marks, replace them with a _real_ mark (ask the
user which one)." user which one)."
(interactive) (interactive)
@ -371,7 +367,7 @@ user which one)."
mu4e~mark-map)))) mu4e~mark-map))))
(defun mu4e~mark-check-target (target) (defun mu4e~mark-check-target (target)
"Check if the target exists; if not, offer to create it." "Check if TARGET exists; if not, offer to create it."
(let ((fulltarget (concat mu4e-maildir target))) (let ((fulltarget (concat mu4e-maildir target)))
(if (not (mu4e-create-maildir-maybe fulltarget)) (if (not (mu4e-create-maildir-maybe fulltarget))
(mu4e-error "Target dir %s does not exist " fulltarget) (mu4e-error "Target dir %s does not exist " fulltarget)
@ -391,14 +387,13 @@ work well.
If NO-CONFIRMATION is non-nil, don't ask user for confirmation." If NO-CONFIRMATION is non-nil, don't ask user for confirmation."
(interactive) (interactive)
(mu4e~mark-in-context (mu4e~mark-in-context
(let ((marknum (hash-table-count mu4e~mark-map))) (let* ((marknum (hash-table-count mu4e~mark-map))
(prompt (format "Are you sure you want to execute %d mark%s?"
marknum (if (> marknum 1) "s" ""))))
(if (zerop marknum) (if (zerop marknum)
(message "Nothing is marked") (mu4e-warn "Nothing is marked")
(mu4e-mark-resolve-deferred-marks) (mu4e-mark-resolve-deferred-marks)
(when (or no-confirmation (when (or no-confirmation (y-or-n-p prompt))
(y-or-n-p
(format "Are you sure you want to execute %d mark%s?"
marknum (if (> marknum 1) "s" ""))))
(maphash (maphash
(lambda (docid val) (lambda (docid val)
(let* ((mark (car val)) (target (cdr val)) (let* ((mark (car val)) (target (cdr val))
@ -435,18 +430,18 @@ If NO-CONFIRMATION is non-nil, don't ask user for confirmation."
(mu4e~mark-clear))) (mu4e~mark-clear)))
(defun mu4e-mark-docid-marked-p (docid) (defun mu4e-mark-docid-marked-p (docid)
"Is the given docid marked?" "Is the given DOCID marked?"
(when (gethash docid mu4e~mark-map) t)) (when (gethash docid mu4e~mark-map) t))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-mark-marks-num () (defun mu4e-mark-marks-num ()
"Return the number of marks in the current buffer." "Return the number of mark-instances in the current buffer."
(mu4e~mark-in-context (mu4e~mark-in-context
(if mu4e~mark-map (hash-table-count mu4e~mark-map) 0))) (if mu4e~mark-map (hash-table-count mu4e~mark-map) 0)))
(defun mu4e-mark-handle-when-leaving () (defun mu4e-mark-handle-when-leaving ()
"If there are any marks in the current buffer, handle those "Handle any mark-instances in the current buffer when leaving.
according to the value of `mu4e-headers-leave-behavior'. This This is done according to the value of `mu4e-headers-leave-behavior'. This
function is to be called before any further action (like searching, function is to be called before any further action (like searching,
quitting the buffer) is taken; returning t means 'take the following quitting the buffer) is taken; returning t means 'take the following
action', return nil means 'don't do anything'." action', return nil means 'don't do anything'."
@ -464,6 +459,5 @@ action', return nil means 'don't do anything'."
(when (eq what 'apply) (when (eq what 'apply)
(mu4e-mark-execute-all t)))))) (mu4e-mark-execute-all t))))))
(provide 'mu4e-mark) (provide 'mu4e-mark)
;; End of mu4e-mark.el ;;; mu4e-mark.el ends here