* mu4e: mu4e-message part 3

This commit is contained in:
djcb 2012-09-26 17:28:30 +03:00
parent 97c13d0920
commit 5c2025a12c
7 changed files with 80 additions and 92 deletions

View File

@ -30,8 +30,10 @@
(require 'cl) (require 'cl)
(require 'mu4e-utils) (require 'mu4e-utils)
(require 'mu4e-message)
(require 'mu4e-meta) (require 'mu4e-meta)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e-action-count-lines (msg) (defun mu4e-action-count-lines (msg)
@ -39,7 +41,7 @@
headers view and message-view." headers view and message-view."
(message "Number of lines: %s" (message "Number of lines: %s"
(shell-command-to-string (shell-command-to-string
(concat "wc -l < " (shell-quote-argument (plist-get msg :path)))))) (concat "wc -l < " (shell-quote-argument (mu4e-message-field msg :path))))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -58,13 +60,12 @@ view."
(let* ((pdf (let* ((pdf
(shell-command-to-string (shell-command-to-string
(concat mu4e-msg2pdf " " (concat mu4e-msg2pdf " "
(shell-quote-argument (mu4e-msg-field msg :path)) (shell-quote-argument (mu4e-message-field msg :path))
" 2> /dev/null"))) " 2> /dev/null")))
(pdf (and pdf (> (length pdf) 5) (pdf (and pdf (> (length pdf) 5)
(substring pdf 0 -1)))) ;; chop \n (substring pdf 0 -1)))) ;; chop \n
(unless (and pdf (file-exists-p pdf)) (unless (and pdf (file-exists-p pdf))
(message "==> %S %S" pdf (mu4e-msg-field msg :path)) (mu4e-warn "Failed to create PDF file"))
(mu4e-error "Failed to create PDF file"))
(find-file pdf))) (find-file pdf)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -75,8 +76,8 @@ view."
(defun mu4e-action-view-in-browser (msg) (defun mu4e-action-view-in-browser (msg)
"View the body of the message in a web browser. You can influence "View the body of the message in a web browser. You can influence
the browser to use with the variable `browse-url-generic-program'." the browser to use with the variable `browse-url-generic-program'."
(let* ((html (mu4e-msg-field msg :body-html)) (let* ((html (mu4e-message-field msg :body-html))
(txt (mu4e-msg-field msg :body-txt)) (txt (mu4e-message-field msg :body-txt))
(tmpfile (format "%s%x.html" temporary-file-directory (random t)))) (tmpfile (format "%s%x.html" temporary-file-directory (random t))))
(unless (or html txt) (unless (or html txt)
(mu4e-error "No body part for this message")) (mu4e-error "No body part for this message"))
@ -96,10 +97,10 @@ the browser to use with the variable `browse-url-generic-program'."
(defun mu4e-action-message-to-speech (msg) (defun mu4e-action-message-to-speech (msg)
"Pronounce the message text using `mu4e-text2speech-command'." "Pronounce the message text using `mu4e-text2speech-command'."
(unless (mu4e-msg-field msg :body-txt) (unless (mu4e-message-field msg :body-txt)
(mu4e-error "No text body for this message")) (mu4e-warn "No text body for this message"))
(with-temp-buffer (with-temp-buffer
(insert (mu4e-msg-field msg :body-txt)) (insert (mu4e-message-field msg :body-txt))
(shell-command-on-region (point-min) (point-max) (shell-command-on-region (point-min) (point-max)
mu4e-text2speech-command))) mu4e-text2speech-command)))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -142,7 +143,7 @@ store your org-contacts."
(mu4e-error "org-capture is not available.")) (mu4e-error "org-capture is not available."))
(unless mu4e-org-contacts-file (unless mu4e-org-contacts-file
(mu4e-error "`mu4e-org-contacts-file' is not defined.")) (mu4e-error "`mu4e-org-contacts-file' is not defined."))
(let* ((sender (car-safe (mu4e-msg-field msg :from))) (let* ((sender (car-safe (mu4e-message-field msg :from)))
(name (car-safe sender)) (email (cdr-safe sender)) (name (car-safe sender)) (email (cdr-safe sender))
(blurb (blurb
(format (format

View File

@ -40,6 +40,7 @@
(require 'mu4e-vars) (require 'mu4e-vars)
(require 'mu4e-proc) (require 'mu4e-proc)
(require 'mu4e-actions) (require 'mu4e-actions)
(require 'mu4e-message)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Composing / Sending messages ;; Composing / Sending messages
@ -688,32 +689,33 @@ or replied to, otherwise it is nil."
a symbol, one of `reply', `forward', `edit', `new'. All but `new' a symbol, one of `reply', `forward', `edit', `new'. All but `new'
take the message at point as input. Symbol `edit' is only allowed take the message at point as input. Symbol `edit' is only allowed
for draft messages." for draft messages."
(let ((msg (mu4e-message-at-point 'noerror)))
;; some sanity checks
(unless (or msg (eq compose-type 'new))
(mu4e-warn "No message at point"))
(unless (member compose-type '(reply forward edit new))
(mu4e-error "Invalid compose type '%S'" compose-type))
(when (and (eq compose-type 'edit)
(not (member 'draft (mu4e-message-field msg :flags))))
(mu4e-warn "Editing is only allowed for draft messages"))
;; run the hooks
(mu4e~compose-run-hooks compose-type)
(unless (member compose-type '(reply forward edit new)) ;; 'new is special, since it takes no existing message as arg therefore,
(mu4e-error "Invalid compose type '%S'" compose-type)) ;; we don't need to call thec backend, and call the handler *directly*
(when (and (eq compose-type 'edit) (if (eq compose-type 'new)
(not (member 'draft (mu4e-field-at-point :flags)))) (mu4e~compose-handler 'new)
(mu4e-warn "Editing is only allowed for draft messages")) ;; otherwise, we need the doc-id
(let ((docid (mu4e-message-field msg :docid)))
;; run the hooks ;; if there's a visible view window, select that before starting composing
(mu4e~compose-run-hooks compose-type) ;; a new message, so that one will be replaced by the compose window. The
;; 10-or-so line headers buffer is not a good place to write it...
;; 'new is special, since it takes no existing message as arg therefore,
;; we don't need to call thec backend, and call the handler *directly*
(if (eq compose-type 'new)
(mu4e~compose-handler 'new)
;; otherwise, we need the doc-id
(let ((docid (mu4e-field-at-point :docid)))
;; if there's a visible view window, select that before starting composing
;; a new message, so that one will be replaced by the compose window. The
;; 10-or-so line headers buffer is not a good place to write it...
(let ((viewwin (get-buffer-window mu4e~view-buffer))) (let ((viewwin (get-buffer-window mu4e~view-buffer)))
(when (window-live-p viewwin) (when (window-live-p viewwin)
(select-window viewwin))) (select-window viewwin)))
;; talk to the backend ;; talk to the backend
(mu4e~proc-compose compose-type docid)))) (mu4e~proc-compose compose-type docid)))))
(defun mu4e-compose-reply () (defun mu4e-compose-reply ()
"Compose a reply for the message at point in the headers buffer." "Compose a reply for the message at point in the headers buffer."

View File

@ -706,7 +706,7 @@ docid DOCID, or nil if it cannot be found."
with DOCID which must be present in the headers buffer." with DOCID which must be present in the headers buffer."
(save-excursion (save-excursion
(when (mu4e~headers-goto-docid docid) (when (mu4e~headers-goto-docid docid)
(mu4e-message-field (mu4e-message-at-point t) field)))) (mu4e-message-field (mu4e-message-at-point) field))))
;;;; markers mark headers for ;;;; markers mark headers for
(defun mu4e~headers-mark (docid mark) (defun mu4e~headers-mark (docid mark)
@ -895,28 +895,27 @@ matching messages with that mark."
limited to the message at point and its descendants." limited to the message at point and its descendants."
;; the tread id is shared by all messages in a thread ;; the tread id is shared by all messages in a thread
(interactive "P") (interactive "P")
(let* ((thread-id (mu4e~headers-get-thread-info (let* ((msg (mu4e-message-at-point))
(mu4e-message-at-point t) 'thread-id)) (thread-id (mu4e~headers-get-thread-info msg 'thread-id))
(path (mu4e~headers-get-thread-info (path (mu4e~headers-get-thread-info msg 'path))
(mu4e-message-at-point t) 'path))
(markpair (markpair
(mu4e~mark-get-markpair (mu4e~mark-get-markpair
(if subthread "Mark subthread with: " "Mark whole thread with: ") (if subthread "Mark subthread with: " "Mark whole thread with: ")
t)) t))
(last-marked-point)) (last-marked-point))
(mu4e-headers-for-each (mu4e-headers-for-each
(lambda (msg) (lambda (mymsg)
(let ((my-thread-id (mu4e~headers-get-thread-info msg 'thread-id))) (let ((my-thread-id (mu4e~headers-get-thread-info mymsg 'thread-id)))
(if subthread (if subthread
;; subthread matching; msg's thread path should have path as its ;; subthread matching; mymsg's thread path should have path as its
;; prefix ;; prefix
(when (string-match (concat "^" path) (when (string-match (concat "^" path)
(mu4e~headers-get-thread-info msg 'path)) (mu4e~headers-get-thread-info mymsg 'path))
(mu4e-mark-at-point (car markpair) (cdr markpair)) (mu4e-mark-at-point (car markpair) (cdr markpair))
(setq last-marked-point (point))) (setq last-marked-point (point)))
;; nope; not looking for the subthread; looking for the whole thread ;; nope; not looking for the subthread; looking for the whole thread
(when (string= thread-id (when (string= thread-id
(mu4e~headers-get-thread-info msg 'thread-id)) (mu4e~headers-get-thread-info mymsg 'thread-id))
(mu4e-mark-at-point (car markpair) (cdr markpair)) (mu4e-mark-at-point (car markpair) (cdr markpair))
(setq last-marked-point (point))))))) (setq last-marked-point (point)))))))
(when last-marked-point (when last-marked-point
@ -1106,7 +1105,7 @@ current window. "
(interactive) (interactive)
(unless (eq major-mode 'mu4e-headers-mode) (unless (eq major-mode 'mu4e-headers-mode)
(mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode)) (mu4e-error "Must be in mu4e-headers-mode (%S)" major-mode))
(let* ((msg (mu4e-message-at-point t)) (let* ((msg (mu4e-message-at-point))
(docid (or (mu4e-message-field msg :docid) (docid (or (mu4e-message-field msg :docid)
(mu4e-warn "No message at point"))) (mu4e-warn "No message at point")))
;; decrypt (or not), based on `mu4e-decryption-policy'. ;; decrypt (or not), based on `mu4e-decryption-policy'.
@ -1234,7 +1233,7 @@ N. Otherwise, don't do anything."
"Ask user what to do with message-at-point, then do it. The "Ask user what to do with message-at-point, then do it. The
actions are specified in `mu4e-headers-actions'." actions are specified in `mu4e-headers-actions'."
(interactive) (interactive)
(let ((msg (mu4e-message-at-point t)) (let ((msg (mu4e-message-at-point))
(actionfunc (mu4e-read-option "Action: " mu4e-headers-actions))) (actionfunc (mu4e-read-option "Action: " mu4e-headers-actions)))
(funcall actionfunc msg))) (funcall actionfunc msg)))

View File

@ -28,6 +28,7 @@
;; Code: ;; Code:
(require 'mu4e-proc) (require 'mu4e-proc)
(require 'mu4e-utils) (require 'mu4e-utils)
(require 'mu4e-message)
(defcustom mu4e-headers-leave-behavior 'ask (defcustom mu4e-headers-leave-behavior 'ask
"What to do when user leaves the headers view (e.g. quits, "What to do when user leaves the headers view (e.g. quits,
@ -101,7 +102,8 @@ The following marks are available, and the corresponding props:
`deferred' n mark this message for *something* (decided later) `deferred' n mark this message for *something* (decided later)
`unmark' n unmark this message" `unmark' n unmark this message"
(interactive) (interactive)
(let* ((docid (mu4e-field-at-point :docid)) (let* ((msg (mu4e-message-at-point))
(docid (mu4e-message-field msg :docid))
;; get a cell with the mark char and the 'target' 'move' already has a ;; get a cell with the mark char and the 'target' 'move' already has a
;; target (the target folder) the other ones get a pseudo "target", as ;; target (the target folder) the other ones get a pseudo "target", as
;; info for the user. ;; info for the user.
@ -174,7 +176,7 @@ headers in the region."
the region, for moving to maildir TARGET. If target is not the region, for moving to maildir TARGET. If target is not
provided, function asks for it." provided, function asks for it."
(interactive) (interactive)
(mu4e-field-at-point :docid) ;; will raise an error if there is none (mu4e-message-at-point) ;; raises error if there is none
(let* ((target (or target (mu4e-ask-maildir "Move message to: "))) (let* ((target (or target (mu4e-ask-maildir "Move message to: ")))
(target (if (string= (substring target 0 1) "/") (target (if (string= (substring target 0 1) "/")
target target
@ -281,8 +283,7 @@ If NO-CONFIRMATION is non-nil, don't ask user for confirmation."
mu4e~mark-map) mu4e~mark-map)
;; in any case, clear the marks map ;; in any case, clear the marks map
(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))

View File

@ -28,10 +28,11 @@
(eval-when-compile (byte-compile-disable-warning 'cl-functions)) (eval-when-compile (byte-compile-disable-warning 'cl-functions))
(require 'mu4e-vars) (require 'mu4e-vars)
(require 'mu4e-utils)
(require 'cl) (require 'cl)
(require 'html2text) (require 'html2text)
(defcustom mu4e-html2text-command nil (defcustom mu4e-html2text-command nil
"Shell command that converts HTML from stdin into plain text on "Shell command that converts HTML from stdin into plain text on
@ -88,16 +89,15 @@ Some notes on the format:
;; after all this documentation, the spectacular implementation ;; after all this documentation, the spectacular implementation
(plist-get msg field)) (plist-get msg field))
(defsubst mu4e-message-at-point (&optional raise-err) (defsubst mu4e-message-at-point (&optional noerror)
"Get the message s-expression for the message at point in either "Get the message s-expression for the message at point in either
the headers buffer or the view buffer, or nil if there is no such the headers buffer or the view buffer, or nil if there is no such
message. If optional RAISE-ERR is non-nil, raise an error when message. If optional NOERROR is non-nil, do not raise an error when
there is no message at point." there is no message at point."
(let ((msg (or (get-text-property (point) 'msg) mu4e~view-msg))) (let ((msg (or (get-text-property (point) 'msg) mu4e~view-msg)))
(if msg (if msg
msg msg
(when raise-err (unless noerror (mu4e-warn "No message at point")))))
(mu4e-warn "No message at point")))))
(defun mu4e-message-for-each (msg field func) (defun mu4e-message-for-each (msg field func)
@ -171,4 +171,17 @@ function prefers the text part, but this can be changed by setting
(:index 2 :name \"photo.jpg\" :mime-type \"image/jpeg\" :size 147331)." (:index 2 :name \"photo.jpg\" :mime-type \"image/jpeg\" :size 147331)."
(plist-get msgpart field)) (plist-get msgpart field))
;; backward compatibility ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defalias 'mu4e-msg-field 'mu4e-message-field)
(defalias 'mu4e-body-text 'mu4e-message-body-text) ;; backward compatibility
(defun mu4e-field-at-point (field)
"Get FIELD (a symbol, see `mu4e-header-info') for the message at
point in eiter the headers buffer or the view buffer."
(plist-get (mu4e-message-at-point) field))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(provide 'mu4e-message) (provide 'mu4e-message)

View File

@ -28,19 +28,18 @@
(eval-when-compile (byte-compile-disable-warning 'cl-functions)) (eval-when-compile (byte-compile-disable-warning 'cl-functions))
(require 'cl) (require 'cl)
(require 'mu4e-message)
(require 'mu4e-vars) (require 'mu4e-vars)
(require 'mu4e-about) (require 'mu4e-about)
(require 'doc-view) (require 'doc-view)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; the following is taken from org.el; we copy it here since we don't want to ;; the following is taken from org.el; we copy it here since we don't want to
;; depend on org-mode directly (it causes byte-compilation errors) TODO: a ;; depend on org-mode directly (it causes byte-compilation errors) TODO: a
;; cleaner solution.... ;; cleaner solution....
(defconst mu4e~ts-regexp0 (defconst mu4e~ts-regexp0
"\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\)\\( +[^]+0-9>\r\n -]+\\)?\\( +\\([0-9]\\{1,2\\}\\):\\([0-9]\\{2\\}\\)\\)?\\)" (concat
"\\(\\([0-9]\\{4\\}\\)-\\([0-9]\\{2\\}\\)-\\([0-9]\\{2\\}\\)"
"\\( +[^]+0-9>\r\n -]+\\)?\\( +\\([0-9]\\{1,2\\}\\):\\([0-9]\\{2\\}\\)\\)?\\)")
"Regular expression matching time strings for analysis. "Regular expression matching time strings for analysis.
This one does not require the space after the date, so it can be This one does not require the space after the date, so it can be
used on a string that terminates immediately after the date.") used on a string that terminates immediately after the date.")
@ -90,13 +89,15 @@ user-input, don't show anyhting."
(defun mu4e-error (frm &rest args) (defun mu4e-error (frm &rest args)
"Create [mu4e]-prefixed error based on format FRM and ARGS. Does "Create [mu4e]-prefixed error based on format FRM and ARGS. Does
a local-exit and does not return." a local-exit and does not return, and raises a
debuggable (backtrace) error."
(mu4e-log 'error (apply 'mu4e-format frm args)) (mu4e-log 'error (apply 'mu4e-format frm args))
(error "%s" (apply 'mu4e-format frm args))) (error "%s" (apply 'mu4e-format frm args)))
(defun mu4e-warn (frm &rest args) (defun mu4e-warn (frm &rest args)
"Create [mu4e]-prefixed warning based on format FRM and "Create [mu4e]-prefixed warning based on format FRM and
ARGS. Does a local-exit and does not return." ARGS. Does a local-exit and does not return. In emacs versions
below 24.2, the functions is the same as `mu4e-error'."
(mu4e-log 'error (apply 'mu4e-format frm args)) (mu4e-log 'error (apply 'mu4e-format frm args))
(if (fboundp 'user-error) (if (fboundp 'user-error)
(user-error "%s" (apply 'mu4e-format frm args)) ;; only in emacs-trunk (user-error "%s" (apply 'mu4e-format frm args)) ;; only in emacs-trunk
@ -239,25 +240,6 @@ and offer to create it if it does not exist yet."
mdir)) mdir))
(defun mu4e-mark-for-move-set (&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
provided, function asks for it."
(interactive)
(unless (mu4e~headers-docid-at-point)
(mu4e-warn "No message at point."))
(let* ((target (or target (mu4e-ask-maildir "Move message to: ")))
(target (if (string= (substring target 0 1) "/")
target
(concat "/" target)))
(fulltarget (concat mu4e-maildir target)))
(when (or (file-directory-p fulltarget)
(and (yes-or-no-p
(mu4e-format "%s does not exist. Create now?" fulltarget))
(mu4e~proc-mkdir fulltarget)))
(mu4e-mark-set 'move target))))
(defun mu4e-ask-bookmark (prompt &optional kar) (defun mu4e-ask-bookmark (prompt &optional kar)
"Ask the user for a bookmark (using PROMPT) as defined in "Ask the user for a bookmark (using PROMPT) as defined in
`mu4e-bookmarks', then return the corresponding query." `mu4e-bookmarks', then return the corresponding query."
@ -361,9 +343,6 @@ http://cr.yp.to/proto/maildir.html "
(format "%2.1fK" (/ size 1000.0))) (format "%2.1fK" (/ size 1000.0)))
((< size 1000) (format "%d" size)) ((< size 1000) (format "%d" size))
(t (propertize "?" 'face 'mu4e-system-face)))) (t (propertize "?" 'face 'mu4e-system-face))))
(defalias 'mu4e-body-text 'mu4e-message-body-text) ;; backward compatibility
(defun mu4e-display-manual () (defun mu4e-display-manual ()
@ -377,13 +356,6 @@ top level if there is none."
(t "mu4e")))) (t "mu4e"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defalias 'mu4e-msg-field 'mu4e-message-field) ;; backward compatibility
(defun mu4e-field-at-point (field)
"Get FIELD (a symbol, see `mu4e-header-info') for the message at
point in eiter the headers buffer or the view buffer."
(plist-get (mu4e-message-at-point t) field))
(defun mu4e-last-query () (defun mu4e-last-query ()
"Get the most recent query or nil if there is none." "Get the most recent query or nil if there is none."
(when (buffer-live-p mu4e~headers-buffer) (when (buffer-live-p mu4e~headers-buffer)

View File

@ -782,7 +782,7 @@ current message."
`(progn `(progn
(unless '(buffer-live-p mu4e~view-headers-buffer) (unless '(buffer-live-p mu4e~view-headers-buffer)
(mu4e-error "no headers-buffer connected")) (mu4e-error "no headers-buffer connected"))
(let* ((msg (mu4e-message-at-point t)) (let* ((msg (mu4e-message-at-point))
(docid (mu4e-message-field msg :docid))) (docid (mu4e-message-field msg :docid)))
(unless docid (unless docid
(mu4e-error "message without docid: action is not possible.")) (mu4e-error "message without docid: action is not possible."))
@ -831,7 +831,7 @@ N (prefix argument), to the Nth previous header."
if nil), then do it. The actions are specified in if nil), then do it. The actions are specified in
`mu4e-view-actions'." `mu4e-view-actions'."
(interactive) (interactive)
(let* ((msg (or msg (mu4e-message-at-point t))) (let* ((msg (or msg (mu4e-message-at-point)))
(actionfunc (mu4e-read-option "Action: " mu4e-view-actions))) (actionfunc (mu4e-read-option "Action: " mu4e-view-actions)))
(funcall actionfunc msg))) (funcall actionfunc msg)))
@ -935,7 +935,7 @@ will save attachments 1,3,4,5,6 and 8.
Furthermore, there is a shortcut \"a\" which so means all Furthermore, there is a shortcut \"a\" which so means all
attachments, but as this is the default, you may not need it." attachments, but as this is the default, you may not need it."
(interactive) (interactive)
(let* ((msg (or msg (mu4e-message-at-point t))) (let* ((msg (or msg (mu4e-message-at-point)))
(attachstr (mu4e~view-get-attach-num (attachstr (mu4e~view-get-attach-num
"Attachment number range (or 'a' for 'all')" msg t)) "Attachment number range (or 'a' for 'all')" msg t))
(count (hash-table-count mu4e~view-attach-map)) (count (hash-table-count mu4e~view-attach-map))
@ -956,7 +956,7 @@ attachments."
"Open attachment number ATTNUM (or ask if nil) from MSG (or "Open attachment number ATTNUM (or ask if nil) from MSG (or
message-at-point if nil)." message-at-point if nil)."
(interactive) (interactive)
(let* ((msg (or msg (mu4e-message-at-point t))) (let* ((msg (or msg (mu4e-message-at-point)))
(attnum (or attnum (attnum (or attnum
(mu4e~view-get-attach-num "Attachment to open" msg))) (mu4e~view-get-attach-num "Attachment to open" msg)))
(att (or (mu4e~view-get-attach msg attnum))) (att (or (mu4e~view-get-attach msg attnum)))
@ -1025,7 +1025,7 @@ PIPECMD is nil, ask user for it."
message-at-point, then do it. The actions are specified in message-at-point, then do it. The actions are specified in
`mu4e-view-attachment-actions'." `mu4e-view-attachment-actions'."
(interactive) (interactive)
(let* ((msg (or msg (mu4e-message-at-point t))) (let* ((msg (or msg (mu4e-message-at-point)))
(actionfunc (mu4e-read-option (actionfunc (mu4e-read-option
"Action on attachment: " "Action on attachment: "
mu4e-view-attachment-actions)) mu4e-view-attachment-actions))