* mu4e: abstract access to the mu4e-message plist

This commit is contained in:
djcb 2012-09-26 12:25:38 +03:00
parent 3f305f665a
commit 7d831184b7
6 changed files with 210 additions and 137 deletions

View File

@ -30,6 +30,7 @@ dist_lisp_LISP= \
mu4e-headers.el \ mu4e-headers.el \
mu4e-main.el \ mu4e-main.el \
mu4e-mark.el \ mu4e-mark.el \
mu4e-message.el \
mu4e-meta.el \ mu4e-meta.el \
mu4e-proc.el \ mu4e-proc.el \
mu4e-speedbar.el \ mu4e-speedbar.el \

View File

@ -99,7 +99,6 @@ forwarded or edited) in `mu4e-compose-pre-hook.")
"message/rfc822" "message/rfc822"
(or (plist-get mu4e-captured-message :subject) "No subject") (or (plist-get mu4e-captured-message :subject) "No subject")
"attachment"))) "attachment")))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun mu4e~compose-user-agent-construct () (defun mu4e~compose-user-agent-construct ()
@ -137,8 +136,8 @@ comma-separated string. Normally, this the concatenation of the
existing References (which may be empty) and the message-id. If the existing References (which may be empty) and the message-id. If the
message-id is empty, returns the old References. If both are empty, message-id is empty, returns the old References. If both are empty,
return nil." return nil."
(let ((refs (plist-get msg :references)) (let ((refs (mu4e-message-field msg :references))
(old-msgid (plist-get msg :message-id))) (old-msgid (mu4e-message-field msg :message-id)))
(when old-msgid (when old-msgid
(setq refs (append refs (list old-msgid))) (setq refs (append refs (list old-msgid)))
(mapconcat (mapconcat

View File

@ -39,6 +39,7 @@
(require 'mu4e-mark) (require 'mu4e-mark)
(require 'mu4e-compose) (require 'mu4e-compose)
(require 'mu4e-actions) (require 'mu4e-actions)
(require 'mu4e-message)
;; the headers view ;; the headers view
(defgroup mu4e-headers nil (defgroup mu4e-headers nil
@ -197,7 +198,7 @@ in the database. This function will update the current list of
headers." headers."
(when (buffer-live-p mu4e~headers-buffer) (when (buffer-live-p mu4e~headers-buffer)
(with-current-buffer mu4e~headers-buffer (with-current-buffer mu4e~headers-buffer
(let* ((docid (plist-get msg :docid)) (let* ((docid (mu4e-message-field msg :docid))
(point (mu4e~headers-docid-pos docid))) (point (mu4e~headers-docid-pos docid)))
(when point ;; is the message present in this list? (when point ;; is the message present in this list?
@ -316,27 +317,27 @@ display may be different)."
`mu4e-user-mail-address-regexp', show the To address; otherwise `mu4e-user-mail-address-regexp', show the To address; otherwise
show the from address; prefixed with the appropriate show the from address; prefixed with the appropriate
`mu4e-headers-from-or-to-prefix'." `mu4e-headers-from-or-to-prefix'."
(let ((addr (cdr-safe (car-safe (plist-get msg :from))))) (let ((addr (cdr-safe (car-safe (mu4e-message-field msg :from)))))
(if (and addr (string-match mu4e-user-mail-address-regexp addr)) (if (and addr (string-match mu4e-user-mail-address-regexp addr))
(concat (cdr mu4e-headers-from-or-to-prefix) (concat (cdr mu4e-headers-from-or-to-prefix)
(mu4e~headers-contact-str (plist-get msg :to))) (mu4e~headers-contact-str (mu4e-message-field msg :to)))
(concat (car mu4e-headers-from-or-to-prefix) (concat (car mu4e-headers-from-or-to-prefix)
(mu4e~headers-contact-str (plist-get msg :from)))))) (mu4e~headers-contact-str (mu4e-message-field msg :from))))))
;; note: this function is very performance-sensitive ;; note: this function is very performance-sensitive
(defun mu4e~headers-header-handler (msg &optional point) (defun mu4e~headers-header-handler (msg &optional point)
"Create a one line description of MSG in this buffer, at POINT, "Create a one line description of MSG in this buffer, at POINT,
if provided, or at the end of the buffer otherwise." if provided, or at the end of the buffer otherwise."
(let ((docid (plist-get msg :docid)) (line "")) (let ((docid (mu4e-message-field msg :docid)) (line ""))
(dolist (f-w mu4e-headers-fields) (dolist (f-w mu4e-headers-fields)
(let ((field (car f-w)) (width (cdr f-w)) (let ((field (car f-w)) (width (cdr f-w))
(val (plist-get msg (car f-w))) (str)) (val (mu4e-message-field msg (car f-w))) (str))
(setq str (setq str
(case field (case field
(:subject (:subject
(concat ;; prefix subject with a thread indicator (concat ;; prefix subject with a thread indicator
(mu4e~headers-thread-prefix (plist-get msg :thread)) (mu4e~headers-thread-prefix (mu4e-message-field msg :thread))
;; "["(plist-get (plist-get msg :thread) :path) "] " ;; "["(plist-get (mu4e-message-field msg :thread) :path) "] "
val)) val))
((:maildir :path) val) ((:maildir :path) val)
((:to :from :cc :bcc) (mu4e~headers-contact-str val)) ((:to :from :cc :bcc) (mu4e~headers-contact-str val))
@ -356,7 +357,7 @@ if provided, or at the end of the buffer otherwise."
(truncate-string-to-width str width 0 ?\s t)) " "))))) (truncate-string-to-width str width 0 ?\s t)) " ")))))
;; now, propertize it. ;; now, propertize it.
(setq line (propertize line 'face (setq line (propertize line 'face
(case (car-safe (plist-get msg :flags)) (case (car-safe (mu4e-message-field msg :flags))
('draft 'mu4e-draft-face) ('draft 'mu4e-draft-face)
('trash 'mu4e-trashed-face) ('trash 'mu4e-trashed-face)
((unread new) 'mu4e-unread-face) ((unread new) 'mu4e-unread-face)
@ -875,7 +876,7 @@ matching messages with that mark."
(defun mu4e~headers-get-thread-info (msg what) (defun mu4e~headers-get-thread-info (msg what)
"Get WHAT (a symbol, either path or thread-id) for MSG." "Get WHAT (a symbol, either path or thread-id) for MSG."
(let* ((thread (or (plist-get msg :thread) (let* ((thread (or (mu4e-message-field msg :thread)
(mu4e-error "No thread info found"))) (mu4e-error "No thread info found")))
(path (or (plist-get thread :path) (path (or (plist-get thread :path)
(mu4e-error "No threadpath found")))) (mu4e-error "No threadpath found"))))

164
mu4e/mu4e-message.el Normal file
View File

@ -0,0 +1,164 @@
;;; mu4e-message.el -- part of mu4e, the mu mail user agent
;;
;; Copyright (C) 2012 Dirk-Jan C. Binnema
;; Author: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; Maintainer: Dirk-Jan C. Binnema <djcb@djcbsoftware.nl>
;; This file is not part of GNU Emacs.
;;
;; GNU Emacs is free software: you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Functions to get data from mu4e-message plist structure
;;; Code:
(eval-when-compile (byte-compile-disable-warning 'cl-functions))
(require 'cl)
(require 'html2text)
(defcustom mu4e-html2text-command nil
"Shell command that converts HTML from stdin into plain text on
stdout. If this is not defined, the emacs `html2text' tool will be
used when faced with html-only message. If you use htmltext, it's
recommended you use \"html2text -utf8 -width 72\"."
:type 'string
:group 'mu4e-view
:safe 'stringp)
(defcustom mu4e-view-prefer-html nil
"Whether to base the body display on the HTML-version of the
e-mail message (if there is any."
:type 'boolean
:group 'mu4e-view)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defsubst mu4e-message-field (msg field)
"Retrieve FIELD from message plist MSG. FIELD is one
of :from, :to, :cc, :bcc, :subject, :data, :message-id, :path, :maildir,
:priority, :attachments, :references, :in-reply-to, :body-txt, :body-html
A message plist looks something like:
\(:docid 32461
:from ((\"Nikola Tesla\" . \"niko@example.com\"))
:to ((\"Thomas Edison\" . \"tom@example.com\"))
:cc ((\"Rupert The Monkey\" . \"rupert@example.com\"))
:subject \"RE: what about the 50K?\"
:date (20369 17624 0)
:size 4337
:message-id \"6BDC23465F79238C8233AB82D81EE81AF0114E4E74@123213.mail.example.com\"
:path \"/home/tom/Maildir/INBOX/cur/133443243973_1.10027.atlas:2,S\"
:maildir \"/INBOX\"
:priority normal
:flags (seen)
:attachments
((:index 2 :name \"photo.jpg\" :mime-type \"image/jpeg\" :size 147331)
(:index 3 :name \"book.pdf\" :mime-type \"application/pdf\" :size 192220))
:references (\"6BDC23465F79238C8384574032D81EE81AF0114E4E74@123213.mail.example.com\"
\"6BDC23465F79238203498230942D81EE81AF0114E4E74@123213.mail.example.com\")
:in-reply-to \"6BDC23465F79238203498230942D81EE81AF0114E4E74@123213.mail.example.com\"
:body-txt \"Hi Tom, ...\"
\)).
Some notes on the format:
- The address fields are lists of pairs (NAME . EMAIL), where NAME can be nil.
- The date is in format emacs uses in `current-time'
- Attachments are a list of elements with fields :index (the number of
the MIME-part), :name (the file name, if any), :mime-type (the
MIME-type, if any) and :size (the size in bytes, if any).
- Messages in the Headers view come from the database and do not have
:attachments. :body-txt or :body-html fields. Message in the
Message view use the actual message file, and do include these fields."
;; after all this documentation, the spectacular implementation
(plist-get msg field))
(defun mu4e-message-for-each (msg field func)
"Call FUNC for each element in the field FIELD (which must be a
lists-type field). FUNC takes the element as its arg."
(let ((lst (mu4e-message-field msg field)))
(unless (listp lst)
(error "Not a list type"))
(dolist (elm (mu4e-message-field msg field))
(funcall func elm))))
(defun mu4e-message-for-each-contact-field (msg field func)
"Call FUNC for each element of contact
FIELD (:to, :cc, :bcc, :from). FUNC takes two args, strings
name (possibly nil) and an email address."
(unless (member field '(:to :from :bcc :cc))
(error "Not a contacts field"))
(mu4e-message-for-each msg field
(lambda (contact)
(funcall func (car contact) (cdr contact)))))
(defun mu4e-message-body-text (msg)
"Get the body in text form for this message, which is either :body-txt,
or if not available, :body-html converted to text. By default, it
uses the emacs built-in `html2text'. Alternatively, if
`mu4e-html2text-command' is non-nil, it will use that. Normally,
function prefers the text part, but this can be changed by setting
`mu4e-view-prefer-html'."
(let* ((txt (mu4e-message-field msg :body-txt))
(html (mu4e-message-field msg :body-html))
(body
(cond
;; does it look like some text? ie., 10x the length of the text
;; should be longer than the html, an heuristic to guard against
;; 'This messages requires html' text bodies.
((and (> (* 10 (length txt)) (length html))
;; use html if it's prefered, unless there is no html
(or (not mu4e-view-prefer-html) (not html)))
txt)
;; otherwise, it there some html?
(html
(with-temp-buffer
(insert html)
;; if defined, use the external tool
(if mu4e-html2text-command
(shell-command-on-region (point-min) (point-max)
mu4e-html2text-command nil t)
;; otherwise...
(html2text))
(buffer-string)))
(t ;; otherwise, an empty body
""))))
;; and finally, remove some crap from the remaining string; it seems
;; esp. outlook lies about its encoding (ie., it says 'iso-8859-1' but
;; really it's 'windows-1252'), thus giving us these funky chars. here, we
;; either remove them, or replace with 'what-was-meant' (heuristically)
(with-temp-buffer
(insert body)
(goto-char (point-min))
(while (re-search-forward "[  ’]" nil t)
(replace-match
(cond
((string= (match-string 0) "’") "'")
(t ""))))
(buffer-string))))
(defsubst mu4e-message-part-field (msgpart field)
"Get some field in a message part; a part would look something like:
(:index 2 :name \"photo.jpg\" :mime-type \"image/jpeg\" :size 147331)."
(plist-get msgpart field))
(provide 'mu4e-message)

View File

@ -28,25 +28,11 @@
(eval-when-compile (byte-compile-disable-warning 'cl-functions)) (eval-when-compile (byte-compile-disable-warning 'cl-functions))
(require 'cl) (require 'cl)
(require 'html2text) (require 'mu4e-message)
(require 'mu4e-vars) (require 'mu4e-vars)
(require 'mu4e-about) (require 'mu4e-about)
(require 'doc-view) (require 'doc-view)
(defcustom mu4e-html2text-command nil
"Shell command that converts HTML from stdin into plain text on
stdout. If this is not defined, the emacs `html2text' tool will be
used when faced with html-only message. If you use htmltext, it's
recommended you use \"html2text -utf8 -width 72\"."
:type 'string
:group 'mu4e-view
:safe 'stringp)
(defcustom mu4e-view-prefer-html nil
"Whether to base the body display on the HTML-version of the
e-mail message (if there is any."
:type 'boolean
:group 'mu4e-view)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@ -377,52 +363,8 @@ http://cr.yp.to/proto/maildir.html "
(t (propertize "?" 'face 'mu4e-system-face)))) (t (propertize "?" 'face 'mu4e-system-face))))
(defalias 'mu4e-body-text 'mu4e-message-body-text) ;; backward compatibility
(defun mu4e-body-text (msg)
"Get the body in text form for this message, which is either :body-txt,
or if not available, :body-html converted to text. By default, it
uses the emacs built-in `html2text'. Alternatively, if
`mu4e-html2text-command' is non-nil, it will use that. Normally,
function prefers the text part, but this can be changed by setting
`mu4e-view-prefer-html'."
(let* ((txt (plist-get msg :body-txt))
(html (plist-get msg :body-html))
(body
(cond
;; does it look like some text? ie., 10x the length of the text
;; should be longer than the html, an heuristic to guard against
;; 'This messages requires html' text bodies.
((and (> (* 10 (length txt)) (length html))
;; use html if it's prefered, unless there is no html
(or (not mu4e-view-prefer-html) (not html)))
txt)
;; otherwise, it there some html?
(html
(with-temp-buffer
(insert html)
;; if defined, use the external tool
(if mu4e-html2text-command
(shell-command-on-region (point-min) (point-max)
mu4e-html2text-command nil t)
;; otherwise...
(html2text))
(buffer-string)))
(t ;; otherwise, an empty body
""))))
;; and finally, remove some crap from the remaining string; it seems
;; esp. outlook lies about its encoding (ie., it says 'iso-8859-1' but
;; really it's 'windows-1252'), thus giving us these funky chars. here, we
;; either remove them, or replace with 'what-was-meant' (heuristically)
(with-temp-buffer
(insert body)
(goto-char (point-min))
(while (re-search-forward "[  ’]" nil t)
(replace-match
(cond
((string= (match-string 0) "’") "'")
(t ""))))
(buffer-string))))
(defun mu4e-display-manual () (defun mu4e-display-manual ()
"Display the mu4e manual page for the current mode, or go to the "Display the mu4e manual page for the current mode, or go to the
@ -435,44 +377,8 @@ top level if there is none."
(t "mu4e")))) (t "mu4e"))))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defsubst mu4e-msg-field (msg field) (defalias 'mu4e-msg-field 'mu4e-message-field) ;; backward compatibility
"Retrieve FIELD from message plist MSG. FIELD is one
of :from, :to, :cc, :bcc, :subject, :data, :message-id, :path, :maildir,
:priority, :attachments, :references, :in-reply-to, :body-txt, :body-html
A message plist looks something like:
\(:docid 32461
:from ((\"Nikola Tesla\" . \"niko@example.com\"))
:to ((\"Thomas Edison\" . \"tom@example.com\"))
:cc ((\"Rupert The Monkey\" . \"rupert@example.com\"))
:subject \"RE: what about the 50K?\"
:date (20369 17624 0)
:size 4337
:message-id \"6BDC23465F79238C8233AB82D81EE81AF0114E4E74@123213.mail.example.com\"
:path \"/home/tom/Maildir/INBOX/cur/133443243973_1.10027.atlas:2,S\"
:maildir \"/INBOX\"
:priority normal
:flags (seen)
:attachments
((:index 2 :name \"photo.jpg\" :mime-type \"image/jpeg\" :size 147331)
(:index 3 :name \"book.pdf\" :mime-type \"application/pdf\" :size 192220))
:references (\"6BDC23465F79238C8384574032D81EE81AF0114E4E74@123213.mail.example.com\"
\"6BDC23465F79238203498230942D81EE81AF0114E4E74@123213.mail.example.com\")
:in-reply-to \"6BDC23465F79238203498230942D81EE81AF0114E4E74@123213.mail.example.com\"
:body-txt \"Hi Tom, ...\"
\)).
Some notes on the format:
- The address fields are lists of pairs (NAME . EMAIL), where NAME can be nil.
- The date is in format emacs uses in `current-time'
- Attachments are a list of elements with fields :index (the number of
the MIME-part), :name (the file name, if any), :mime-type (the
MIME-type, if any) and :size (the size in bytes, if any).
- Messages in the Headers view come from the database and do not have
:attachments. :body-txt or :body-html fields. Message in the
Message view use the actual message file, and do include these fields."
;; after all this documentation, the spectacular implementation
(plist-get msg field))
(defun mu4e-message-at-point (&optional raise-err) (defun mu4e-message-at-point (&optional raise-err)
"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

View File

@ -32,6 +32,7 @@
(require 'mu4e-proc) (require 'mu4e-proc)
(require 'mu4e-compose) (require 'mu4e-compose)
(require 'mu4e-actions) (require 'mu4e-actions)
(require 'mu4e-message)
(require 'longlines) (require 'longlines)
(require 'comint) (require 'comint)
@ -144,7 +145,7 @@ plist."
(concat (concat
(mapconcat (mapconcat
(lambda (field) (lambda (field)
(let ((fieldval (plist-get msg field))) (let ((fieldval (mu4e-message-field msg field)))
(case field (case field
(:subject (mu4e~view-construct-header field fieldval)) (:subject (mu4e~view-construct-header field fieldval))
(:path (mu4e~view-construct-header field fieldval)) (:path (mu4e~view-construct-header field fieldval))
@ -159,7 +160,7 @@ plist."
;; if we (`user-mail-address' are the From, show To, otherwise, ;; if we (`user-mail-address' are the From, show To, otherwise,
;; show From ;; show From
(:from-or-to (:from-or-to
(let* ((from (plist-get msg :from)) (let* ((from (mu4e-message-field msg :from))
(from (and from (cdar from)))) (from (and from (cdar from))))
(if (and from (string-match mu4e-user-mail-address-regexp from)) (if (and from (string-match mu4e-user-mail-address-regexp from))
(mu4e~view-construct-contacts-header msg :to) (mu4e~view-construct-contacts-header msg :to)
@ -180,7 +181,7 @@ plist."
(t (mu4e-error "Unsupported field: %S" field))))) (t (mu4e-error "Unsupported field: %S" field)))))
mu4e-view-fields "") mu4e-view-fields "")
"\n" "\n"
(mu4e-body-text msg) (mu4e-message-body-text msg)
;; ;; decrypt maybe; depends on whether there are any such parts ;; ;; decrypt maybe; depends on whether there are any such parts
;; ;; and the value of `mu4e-view-decrypt-parts' ;; ;; and the value of `mu4e-view-decrypt-parts'
;; (mu4e~decrypt-parts-maybe msg) ;; (mu4e~decrypt-parts-maybe msg)
@ -204,7 +205,8 @@ REFRESH is for re-showing an already existing message.
As a side-effect, a message that is being viewed loses its 'unread' As a side-effect, a message that is being viewed loses its 'unread'
marking if it still had that." marking if it still had that."
(let* ((embedded ;; is it registered as an embedded msg? (let* ((embedded ;; is it registered as an embedded msg?
(when (gethash (plist-get msg :path) mu4e~path-parent-docid-map) t)) (when (gethash (mu4e-message-field msg :path)
mu4e~path-parent-docid-map) t))
(buf (buf
(if embedded (if embedded
(mu4e~view-embedded-winbuf) (mu4e~view-embedded-winbuf)
@ -315,7 +317,7 @@ at POINT, or if nil, at (point)."
(format "<%s>\n%s\n%s" email (format "<%s>\n%s\n%s" email
"[mouse-1] or [M-RET] to toggle long/short display" "[mouse-1] or [M-RET] to toggle long/short display"
"[mouse-2] or C to compose a mail for this recipient")))) "[mouse-2] or C to compose a mail for this recipient"))))
(plist-get msg field) ", ") t)) (mu4e-message-field msg field) ", ") t))
(defun mu4e~view-construct-flags-header (flags) (defun mu4e~view-construct-flags-header (flags)
@ -331,10 +333,10 @@ at POINT, or if nil, at (point)."
(defun mu4e~view-construct-signature-header (msg) (defun mu4e~view-construct-signature-header (msg)
"Construct a Signature: header, if there are any signed parts." "Construct a Signature: header, if there are any signed parts."
(let* ((parts (plist-get msg :parts)) (let* ((parts (mu4e-message-field msg :parts))
(verdicts (verdicts
(remove-if 'null (remove-if 'null
(mapcar (lambda (part) (plist-get part :signature)) parts))) (mapcar (lambda (part) (mu4e-message-part-field part :signature)) parts)))
(val (when verdicts (val (when verdicts
(mapconcat (mapconcat
(lambda (v) (lambda (v)
@ -379,21 +381,21 @@ at POINT, or if nil, at (point)."
;; user-visible numbers and the part indices ;; user-visible numbers and the part indices
(remove-if-not (remove-if-not
(lambda (part) (lambda (part)
(let ((mtype (plist-get part :mime-type)) (let ((mtype (mu4e-message-part-field part :mime-type))
(isattach (member 'attachment (plist-get part :type)))) (isattach (member 'attachment (mu4e-message-part-field part :type))))
(or ;; remove if it's not an attach *or* if it's an (or ;; remove if it's not an attach *or* if it's an
;; image/audio/application type (but not a signature) ;; image/audio/application type (but not a signature)
isattach isattach
(string-match "^\\(image\\|audio\\)" mtype) (string-match "^\\(image\\|audio\\)" mtype)
(and (string-match "^application" mtype) (and (string-match "^application" mtype)
(not (string-match "signature" mtype)))))) (not (string-match "signature" mtype))))))
(plist-get msg :parts))) (mu4e-message-field msg :parts)))
(attstr (attstr
(mapconcat (mapconcat
(lambda (part) (lambda (part)
(let ((index (plist-get part :index)) (let ((index (mu4e-message-part-field part :index))
(name (plist-get part :name)) (name (mu4e-message-part-field part :name))
(size (plist-get part :size)) (size (mu4e-message-part-field part :size))
(map (make-sparse-keymap))) (map (make-sparse-keymap)))
(incf id) (incf id)
(puthash id index mu4e~view-attach-map) (puthash id index mu4e~view-attach-map)
@ -431,8 +433,8 @@ at POINT, or if nil, at (point)."
;; (let ((str "")) ;; (let ((str ""))
;; (mu4e-view-for-each-part msg ;; (mu4e-view-for-each-part msg
;; (lambda (msg part) ;; (lambda (msg part)
;; (when (member 'encrypted (plist-get part :type)) ;; (when (member 'encrypted (mu4e-message-part-field part :type))
;; (let ((file (plist-get part :temp))) ;; (let ((file (mu4e-message-part-field part :temp)))
;; (when (and file (file-exists-p file)) ;; (when (and file (file-exists-p file))
;; ;; if our mu-server was build with crypto support, we only use EPA ;; ;; if our mu-server was build with crypto support, we only use EPA
;; ;; to push the password into gpg's memory ;; ;; to push the password into gpg's memory
@ -730,8 +732,8 @@ browser is called is depending on `browse-url-browser-function' and
(when (and (display-images-p) mu4e-show-images) (when (and (display-images-p) mu4e-show-images)
(mu4e-view-for-each-part msg (mu4e-view-for-each-part msg
(lambda (msg part) (lambda (msg part)
(when (string-match "^image/" (plist-get part :mime-type)) (when (string-match "^image/" (mu4e-message-part-field part :mime-type))
(let ((imgfile (plist-get part :temp))) (let ((imgfile (mu4e-message-part-field part :temp)))
(when (and imgfile (file-exists-p imgfile)) (when (and imgfile (file-exists-p imgfile))
(save-excursion (save-excursion
(goto-char (point-max)) (goto-char (point-max))
@ -893,8 +895,8 @@ number ATTNUM."
(attach (attach
(find-if (find-if
(lambda (part) (lambda (part)
(eq (plist-get part :index) partid)) (eq (mu4e-message-part-field part :index) partid))
(plist-get msg :parts)))) (mu4e-message-field msg :parts))))
(or attach (mu4e-error "Not a valid attachment")))) (or attach (mu4e-error "Not a valid attachment"))))
@ -920,7 +922,7 @@ message-at-point if nil) to disk."
(and (file-exists-p path) (and (file-exists-p path)
(not (y-or-n-p (mu4e-format "Overwrite '%s'?" path)))))) (not (y-or-n-p (mu4e-format "Overwrite '%s'?" path))))))
(mu4e~proc-extract (mu4e~proc-extract
'save (plist-get msg :docid) index path))) 'save (mu4e-message-field msg :docid) index path)))
(defun mu4e-view-save-attachment-multi (&optional msg) (defun mu4e-view-save-attachment-multi (&optional msg)
"Offer to save multiple email attachments from the current message. "Offer to save multiple email attachments from the current message.
@ -958,7 +960,7 @@ message-at-point if nil)."
(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)))
(index (plist-get att :index)) (index (plist-get att :index))
(docid (plist-get msg :docid)) (docid (mu4e-message-field msg :docid))
(mimetype (plist-get att :mime-type))) (mimetype (plist-get att :mime-type)))
(if (and mimetype (string= mimetype "message/rfc822")) (if (and mimetype (string= mimetype "message/rfc822"))
;; special handling for message-attachments; we open them in mu4e. we also ;; special handling for message-attachments; we open them in mu4e. we also
@ -990,7 +992,7 @@ user for it."
(mu4e-format "Shell command to open it with: ") (mu4e-format "Shell command to open it with: ")
nil 'mu4e~view-open-with-hist))) nil 'mu4e~view-open-with-hist)))
(index (plist-get att :index))) (index (plist-get att :index)))
(mu4e~view-temp-action (plist-get msg :docid) index "open-with" cmd))) (mu4e~view-temp-action (mu4e-message-field msg :docid) index "open-with" cmd)))
(defvar mu4e~view-pipe-hist nil (defvar mu4e~view-pipe-hist nil
"History list for the pipe argument.") "History list for the pipe argument.")
@ -1006,7 +1008,7 @@ PIPECMD is nil, ask user for it."
nil nil
'mu4e~view-pipe-hist))) 'mu4e~view-pipe-hist)))
(index (plist-get att :index))) (index (plist-get att :index)))
(mu4e~view-temp-action (plist-get msg :docid) index "pipe" pipecmd))) (mu4e~view-temp-action (mu4e-message-field msg :docid) index "pipe" pipecmd)))
(defun mu4e-view-open-attachment-emacs (msg attachnum) (defun mu4e-view-open-attachment-emacs (msg attachnum)
@ -1014,7 +1016,7 @@ PIPECMD is nil, ask user for it."
(interactive) (interactive)
(let* ((att (mu4e~view-get-attach msg attachnum)) (let* ((att (mu4e~view-get-attach msg attachnum))
(index (plist-get att :index))) (index (plist-get att :index)))
(mu4e~view-temp-action (plist-get msg :docid) index "emacs"))) (mu4e~view-temp-action (mu4e-message-field msg :docid) index "emacs")))
(defun mu4e-view-attachment-action (&optional msg) (defun mu4e-view-attachment-action (&optional msg)
@ -1171,7 +1173,7 @@ the results."
"Pop-up a little signature verification window for (optional) MSG "Pop-up a little signature verification window for (optional) MSG
or message-at-point." or message-at-point."
(interactive) (interactive)
(let* ((path (if msg (plist-get msg :path) (mu4e-field-at-point :path))) (let* ((path (if msg (mu4e-message-field msg :path) (mu4e-field-at-point :path)))
(cmd (format "%s verify --verbose %s" (cmd (format "%s verify --verbose %s"
mu4e-mu-binary mu4e-mu-binary
(shell-quote-argument path))) (shell-quote-argument path)))