diff --git a/mu4e/mu4e-proc.el b/mu4e/mu4e-proc.el index 68ea5a82..5730f0e7 100644 --- a/mu4e/mu4e-proc.el +++ b/mu4e/mu4e-proc.el @@ -247,6 +247,7 @@ The server output is as follows: (plist-get sexp :temp) ;; name of the temp file (plist-get sexp :what) ;; what to do with it ;; (pipe|emacs|open-with...) + (plist-get sexp :docid) ;; docid of the message (plist-get sexp :param)));; parameter for the action ;; get some info @@ -436,8 +437,9 @@ mean: docid partidx path)) (open (format "action:open docid:%d index:%d" docid partidx)) (temp - (format "action:temp docid:%d index:%d what:%s param:\"%s\"" - docid partidx what param)) + (format "action:temp docid:%d index:%d what:%s%s" + docid partidx what + (if param (format " param:\"%s\"" param) ""))) (otherwise (mu4e-error "Unsupported action %S" action)))))) (mu4e~proc-send-command cmd))) diff --git a/mu4e/mu4e-vars.el b/mu4e/mu4e-vars.el index 84610387..b9266841 100644 --- a/mu4e/mu4e-vars.el +++ b/mu4e/mu4e-vars.el @@ -462,7 +462,7 @@ headers)." ( :name "Signature" :shortname "Sgn" :help "Check for the cryptographic signature" - :sortable nil)) + :sortable nil)) (:size . ( :name "Size" :shortname "Size" @@ -509,10 +509,14 @@ Note, :sortable does not work for custom header fields.") ;; headers (defconst mu4e~headers-buffer-name "*mu4e-headers*" "Name of the buffer for message headers.") -(defvar mu4e~headers-buffer nil "Buffer for message headers") +(defvar mu4e~headers-buffer nil "Buffer for message headers.") ; view (defconst mu4e~view-buffer-name "*mu4e-view*" - "Name for the message view buffer") + "Name for the message view buffer.") + +(defconst mu4e~view-embedded-buffer-name " *mu4e-embedded-view*" + "Name for the embedded message view buffer.") + (defvar mu4e~view-buffer nil "The view buffer.") (defvar mu4e~view-msg nil "The message being viewed in view mode.") diff --git a/mu4e/mu4e-view.el b/mu4e/mu4e-view.el index e9df5f38..0b0d25a6 100644 --- a/mu4e/mu4e-view.el +++ b/mu4e/mu4e-view.el @@ -114,6 +114,10 @@ The first letter of NAME is used as a shortcut character.") (defvar mu4e~view-link-map nil "A map of some number->url so we can jump to url by number.") +(defvar mu4e~path-parent-docid-map (make-hash-table :test 'equal) + "A map of msg paths --> parent-docids. This is to determine what + is the parent docid for embedded message extracted at some path.") + (defconst mu4e~view-url-regexp "\\(\\(https?\\://\\|mailto:\\)[-+a-zA-Z0-9.?_$%/+&#@!*~,:;=/()]+\\)" "Regexp that matches http:/https:/mailto: URLs; match-string 1 @@ -134,17 +138,6 @@ wanting to show specific messages - for example, `mu4e-org'." (mu4e~proc-view msgid mu4e-show-images mu4e-decryption-policy)) -(defun mu4e-view-message-with-path (path) - "View message at PATH. This is meant for external programs -wanting to show specific messages - for example, `mu4e-org'." - ;; note: hackish; if mu4e-decryption-policy is non-nil (ie., t or 'ask), we - ;; decrpt the message. Since here we don't know if message is encrypted or - ;; not, when the policy is 'ask'. we simply assume the user said yes... the - ;; alternative would be to ask for each message, encrypted or not. maybe we - ;; need an extra policy... - (mu4e~proc-view-path path mu4e-show-images mu4e-decryption-policy)) - - (defun mu4e-view-message-text (msg) "Return the message to display (as a string), based on the MSG plist." @@ -193,6 +186,13 @@ plist." ;; (mu4e~decrypt-parts-maybe msg) )) + (defun mu4e~view-embedded-winbuf () + "Get a buffer (shown in a window) for the embedded message." + (let* ((buf (get-buffer-create mu4e~view-embedded-buffer-name)) + (win (or (get-buffer-window buf) (split-window-vertically)))) + (select-window win) + (switch-to-buffer buf))) + (defun mu4e-view (msg headersbuf &optional refresh) "Display the message MSG in a new buffer, and keep in sync with HDRSBUF. @@ -203,14 +203,20 @@ REFRESH is for re-showing an already existing message. As a side-effect, a message that is being viewed loses its 'unread' marking if it still had that." - (let ((buf (get-buffer-create mu4e~view-buffer-name))) + (let* ((embedded ;; is it registered as an embedded msg? + (when (gethash (plist-get msg :path) mu4e~path-parent-docid-map) t)) + (buf + (if embedded + (mu4e~view-embedded-winbuf) + (get-buffer-create mu4e~view-buffer-name)))) (with-current-buffer buf (mu4e-view-mode) + (let ((inhibit-read-only t)) (setq ;; buffer local mu4e~view-msg msg - mu4e~view-headers-buffer headersbuf - mu4e~view-buffer buf) + mu4e~view-headers-buffer headersbuf) + (erase-buffer) (insert (mu4e-view-message-text msg)) (switch-to-buffer buf) @@ -219,9 +225,15 @@ marking if it still had that." (mu4e~view-fontify-footer) (mu4e~view-make-urls-clickable) (mu4e~view-show-images-maybe msg) - (unless refresh - ;; no use in trying to set flags again - (mu4e~view-mark-as-read-maybe))) ))) + + (if embedded + (local-set-key "q" 'kill-buffer-and-window) + (setq mu4e~view-buffer buf)) + + (unless (or refresh embedded) + ;; no use in trying to set flags again, or when it's an embedded + ;; message + (mu4e~view-mark-as-read-maybe)))))) (defun mu4e~view-construct-header (field val &optional dont-propertize-val) @@ -946,12 +958,17 @@ message-at-point if nil)." (mu4e~view-get-attach-num "Attachment to open" msg))) (att (or (mu4e~view-get-attach msg attnum))) (index (plist-get att :index)) + (docid (plist-get msg :docid)) (mimetype (plist-get att :mime-type))) (if (and mimetype (string= mimetype "message/rfc822")) - ;; special handling for message-attachments; we open them in mu4e. - (mu4e~view-temp-action (plist-get msg :docid) index "mu4e") + ;; special handling for message-attachments; we open them in mu4e. we also + ;; send the docid as parameter (4th arg); we'll get this back from the + ;; server, and use it to determine the parent message (ie., the current + ;; message) when showing the embedded message/rfc822, and return to the + ;; current message when quiting that one. + (mu4e~view-temp-action docid index "mu4e" docid) ;; otherwise, open with the default program (handled in mu-server - (mu4e~proc-extract 'open (plist-get msg :docid) index)))) + (mu4e~proc-extract 'open docid index)))) (defun mu4e~view-temp-action (docid index what &optional param) @@ -1015,7 +1032,7 @@ message-at-point, then do it. The actions are specified in ;; handler-function to handle the response we get from the server when we ;; want to do something with one of the attachments. -(defun mu4e~view-temp-handler (path what param) +(defun mu4e~view-temp-handler (path what docid param) "Handler function for doing things with temp files (ie., attachments) in response to a (mu4e~proc-extract 'temp ... )." (cond @@ -1025,14 +1042,19 @@ attachments) in response to a (mu4e~proc-extract 'temp ... )." ((string= what "pipe") ;; 'param' will be the pipe command, path the infile for this (mu4e-process-file-through-pipe path param)) + ;; if it's mu4e, it's some embedded message; 'param' may contain the docid of + ;; the parent message. ((string= what "mu4e") - (mu4e-view-message-with-path path)) + ;; remember the mapping path->docid, which maps the path of the embedded + ;; message to the docid of its parent + (puthash path docid mu4e~path-parent-docid-map) + (mu4e~proc-view-path path mu4e-show-images mu4e-decryption-policy)) ((string= what "emacs") (find-file path) ;; make the buffer read-only since it usually does not make - ;; sense to edit the temp buffer; use C-x C-q if you insist... + ;; sense to edit the temp buffer; use C-x C-q if you insist... (setq buffer-read-only t)) - (t (mu4e-error "Unsupported action %S" what)))) + (t (mu4e-error "Unsupported action %S" what)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; marking @@ -1118,7 +1140,7 @@ user that unmarking only works in the header list." (unless url (mu4e-warn "Invalid number for URL")) (funcall (mu4e~view-browse-url-func url)))) -(defconst mu4e~view-raw-buffer-name "*mu4e-raw-view*" +(defconst mu4e~view-raw-buffer-name " *mu4e-raw-view*" "*internal* Name for the raw message view buffer") (defun mu4e-view-raw-message ()