mirror of https://github.com/djcb/mu.git
* mu4e: support extracting ranges of attachments (C-u e); contributed by
Stephen Eglen.
This commit is contained in:
parent
43785adbf1
commit
76e70185a2
|
@ -726,6 +726,42 @@ mu4e logs some of its internal workings to a log-buffer. See
|
||||||
(unless (buffer-live-p buf)
|
(unless (buffer-live-p buf)
|
||||||
(error "No debug log available"))
|
(error "No debug log available"))
|
||||||
(switch-to-buffer buf)))
|
(switch-to-buffer buf)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(defun mu4e-split-ranges-to-numbers (str n)
|
||||||
|
"Convert STR containing attachment numbers into a list of numbers.
|
||||||
|
STR is a string; N is the highest possible number in the list.
|
||||||
|
This includes expanding e.g. 3-5 into 3,4,5. If the letter
|
||||||
|
\"a\" ('all')) is given, that is expanded to a list with numbers [1..n]."
|
||||||
|
(let ((str-split (split-string str))
|
||||||
|
beg end list)
|
||||||
|
(dolist (elem str-split list)
|
||||||
|
;; special number "a" converts into all attachments 1-N.
|
||||||
|
(when (equal elem "a")
|
||||||
|
(setq elem (concat "1-" (int-to-string n))))
|
||||||
|
(if (string-match "\\([0-9]+\\)-\\([0-9]+\\)" elem)
|
||||||
|
;; we have found a range A-B, which needs converting
|
||||||
|
;; into the numbers A, A+1, A+2, ... B.
|
||||||
|
(progn
|
||||||
|
(setq beg (string-to-int (match-string 1 elem))
|
||||||
|
end (string-to-int (match-string 2 elem)))
|
||||||
|
(while (<= beg end)
|
||||||
|
(add-to-list 'list beg 'append)
|
||||||
|
(setq beg (1+ beg))))
|
||||||
|
;; else just a number
|
||||||
|
(add-to-list 'list (string-to-int elem) 'append)))
|
||||||
|
;; Check that all numbers are valid.
|
||||||
|
(mapc
|
||||||
|
'(lambda (x)
|
||||||
|
(cond
|
||||||
|
((> x n)
|
||||||
|
(error "Attachment %d bigger than maximum (%d)" x n))
|
||||||
|
((< x 1)
|
||||||
|
(error "Attachment number must be greater than 0 (%d)" x))))
|
||||||
|
list)))
|
||||||
|
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
(defvar mu4e-imagemagick-identify "identify"
|
(defvar mu4e-imagemagick-identify "identify"
|
||||||
|
|
|
@ -753,16 +753,23 @@ all messages in the thread at point in the headers view."
|
||||||
|
|
||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
;; attachment handling
|
;; attachment handling
|
||||||
(defun mu4e~view-get-attach-num (prompt msg)
|
(defun mu4e~view-get-attach-num (prompt msg &optional multi)
|
||||||
"Ask the user with PROMPT for an attachment number for MSG, and
|
"Ask the user with PROMPT for an attachment number for MSG, and
|
||||||
ensure it is valid. The number is [1..n] for attachments
|
ensure it is valid. The number is [1..n] for attachments
|
||||||
[0..(n-1)] in the message."
|
[0..(n-1)] in the message. If MULTI is nil, return the number for
|
||||||
(let* ((count (hash-table-count mu4e~view-attach-map)))
|
the attachment; otherwise (MULTI is non-nil), accept ranges of
|
||||||
|
attachment numbers, as per `mu4e-split-ranges-to-numbers', and
|
||||||
|
return the corresponding string."
|
||||||
|
(let* ((count (hash-table-count mu4e~view-attach-map)) (def))
|
||||||
(when (zerop count) (error "No attachments for this message"))
|
(when (zerop count) (error "No attachments for this message"))
|
||||||
(if (= count 1)
|
(if (not multi)
|
||||||
(read-number (mu4e-format "%s: " prompt) 1)
|
(if (= count 1)
|
||||||
(read-number (mu4e-format "%s (1-%d): " prompt count)))))
|
(read-number (mu4e-format "%s: " prompt) 1)
|
||||||
|
(read-number (mu4e-format "%s (1-%d): " prompt count)))
|
||||||
|
(progn
|
||||||
|
(setq def (if (= count 1) "1" (format "1-%d" count)))
|
||||||
|
(read-string (mu4e-format "%s (default %s): " prompt def) nil nil def)))))
|
||||||
|
|
||||||
(defun mu4e~view-get-attach (msg attnum)
|
(defun mu4e~view-get-attach (msg attnum)
|
||||||
"Return the attachment plist in MSG corresponding to attachment
|
"Return the attachment plist in MSG corresponding to attachment
|
||||||
number ATTNUM."
|
number ATTNUM."
|
||||||
|
@ -773,7 +780,7 @@ number ATTNUM."
|
||||||
(plist-get msg :parts))))
|
(plist-get msg :parts))))
|
||||||
|
|
||||||
|
|
||||||
(defun mu4e-view-save-attachment (&optional msg attnum)
|
(defun mu4e-view-save-attachment-single (&optional msg attnum)
|
||||||
"Save attachment number ATTNUM (or ask if nil) from MSG (or
|
"Save attachment number ATTNUM (or ask if nil) from MSG (or
|
||||||
message-at-point if nil) to disk."
|
message-at-point if nil) to disk."
|
||||||
(interactive)
|
(interactive)
|
||||||
|
@ -795,6 +802,31 @@ message-at-point if nil) to disk."
|
||||||
(mu4e~proc-extract
|
(mu4e~proc-extract
|
||||||
'save (plist-get msg :docid) index path)))
|
'save (plist-get msg :docid) index path)))
|
||||||
|
|
||||||
|
(defun mu4e-view-save-attachment-multi (&optional msg)
|
||||||
|
"Offer to save multiple email attachments from the current message.
|
||||||
|
Default is to save all messages, [1..n], where n is the number of
|
||||||
|
attachments. You can type multiple values separated by space, e.g.
|
||||||
|
1 3-6 8
|
||||||
|
will save attachments 1,3,4,5,6 and 8.
|
||||||
|
|
||||||
|
Furthermore, there is a shortcut \"a\" which so means all
|
||||||
|
attachments, but as this is the default, you may not need it."
|
||||||
|
(interactive)
|
||||||
|
(let* ((msg (or msg (mu4e-message-at-point)))
|
||||||
|
(attachstr (mu4e~view-get-attach-num
|
||||||
|
"Attachment number range (or 'a' for 'all')" msg t))
|
||||||
|
(attachnums (mu4e-split-ranges-to-numbers attachstr count)))
|
||||||
|
(dolist (num attachnums)
|
||||||
|
(mu4e-view-save-attachment-single msg num))))
|
||||||
|
|
||||||
|
(defun mu4e-view-save-attachment (&optional multi)
|
||||||
|
"Offer to save attachment(s). If MULTI (prefix-argument) is nil,
|
||||||
|
save a single one, otherwise, offer to save a range of
|
||||||
|
attachments."
|
||||||
|
(interactive "P")
|
||||||
|
(if multi
|
||||||
|
(mu4e-view-save-attachment-multi)
|
||||||
|
(mu4e-view-save-attachment-single)))
|
||||||
|
|
||||||
(defun mu4e-view-open-attachment (&optional msg attnum)
|
(defun mu4e-view-open-attachment (&optional msg attnum)
|
||||||
"Open attachment number ATTNUM (or ask if nil) from MSG (or
|
"Open attachment number ATTNUM (or ask if nil) from MSG (or
|
||||||
|
|
|
@ -734,6 +734,7 @@ g go to (visit) numbered URL (using `browse-url')
|
||||||
(or: <mouse-2> or RET with point on url)
|
(or: <mouse-2> or RET with point on url)
|
||||||
e extract (save) attachment (asks for number)
|
e extract (save) attachment (asks for number)
|
||||||
(or: <mouse-2> or RET with point on attachment)
|
(or: <mouse-2> or RET with point on attachment)
|
||||||
|
C-u e will extract multiple attachments
|
||||||
o open attachment (asks for number)
|
o open attachment (asks for number)
|
||||||
(or: <S-mouse-2> or S-RET with point on attachment)
|
(or: <S-mouse-2> or S-RET with point on attachment)
|
||||||
A execute some action on an attachment
|
A execute some action on an attachment
|
||||||
|
@ -761,6 +762,11 @@ variable @code{mu4e-attachment-dir}, for example:
|
||||||
(setq mu4e-attachment-dir (file-name-expand "~/Downloads"))
|
(setq mu4e-attachment-dir (file-name-expand "~/Downloads"))
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
|
If you want to extract multiple attachments at once, you can do so by
|
||||||
|
prefixing the extracting command by @key{C-u}; so @key{C-u e} will ask you for
|
||||||
|
a range of attachments to extract (for example, 1 3-6 8). Range @t{a} is a
|
||||||
|
shortcut for @emph{all} attachments.
|
||||||
|
|
||||||
@subsection Viewing images inline
|
@subsection Viewing images inline
|
||||||
@anchor{Viewing images inline}
|
@anchor{Viewing images inline}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue