From 339d1ff036873aa305327a0d7d52b391e06e3677 Mon Sep 17 00:00:00 2001 From: djcb Date: Wed, 31 Oct 2012 20:33:46 +0200 Subject: [PATCH] * mu4e: refactor part of mu4e-compose into the new mu4e-draft.el --- mu4e/mu4e-compose.el | 343 ++------------------------------------- mu4e/mu4e-draft.el | 374 +++++++++++++++++++++++++++++++++++++++++++ mu4e/mu4e-vars.el | 21 +++ 3 files changed, 405 insertions(+), 333 deletions(-) create mode 100644 mu4e/mu4e-draft.el diff --git a/mu4e/mu4e-compose.el b/mu4e/mu4e-compose.el index b1914526..e35d08fa 100644 --- a/mu4e/mu4e-compose.el +++ b/mu4e/mu4e-compose.el @@ -81,6 +81,7 @@ (require 'mu4e-proc) (require 'mu4e-actions) (require 'mu4e-message) +(require 'mu4e-draft) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Composing / Sending messages @@ -88,12 +89,6 @@ "Customizations for composing/sending messages." :group 'mu4e) -(defcustom mu4e-reply-to-address nil - "The Reply-To address (if this, for some reason, is not equal to -the From: address.)" - :type 'string - :group 'mu4e-compose) - (defcustom mu4e-sent-messages-behavior 'sent "Determines what mu4e does with sent messages - this is a symbol which can be either: @@ -109,22 +104,11 @@ sent folder." :safe 'symbolp :group 'mu4e-compose) -(defcustom mu4e-compose-keep-self-cc nil - "Non-nil means your e-mail address is kept on the CC list when -replying to messages." - :type 'boolean - :group 'mu4e-compose) - (defvar mu4e-compose-pre-hook nil "Hook run just *before* message composition starts. If the compose-type is either /reply/ or /forward/, the variable `mu4e-compose-parent-message' points to the message replied to / being forwarded / edited.") - -(defvar mu4e-compose-parent-message nil - "The parent message plist -- the message being replied to, -forwarded or edited; used in `mu4e-compose-pre-hook. For new -messages, it is nil.") ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -144,313 +128,6 @@ messages, it is nil.") "attachment"))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun mu4e~compose-user-agent-construct () - "Return the User-Agent string for mu4e. This is either the value -of `mu4e-user-agent', or, if not set, a string based on the versions -of mu4e and emacs." - (format "mu4e %s; emacs %s" mu4e-mu-version emacs-version)) - - -(defun mu4e~compose-cite-original (msg) - "Return a cited version of the original message MSG (ie., the -plist). This function use gnus' `message-cite-function', and as -such all its settings apply." - (with-temp-buffer - (when (fboundp 'mu4e-view-message-text) ;; keep bytecompiler happy - (insert (mu4e-view-message-text msg)) - ;; this seems to be needed, otherwise existing signatures - ;; won't be stripped - (message-yank-original) - (goto-char (point-min)) - (push-mark (point-max)) - (funcall message-cite-function) - (pop-mark) - (buffer-string)))) - -(defun mu4e~compose-header (hdr val) - "Return a header line of the form HDR: VAL\n. If VAL is nil, -return nil." - (when val (format "%s: %s\n" hdr val))) - - -(defun mu4e~compose-references-construct (msg) - "Construct the value of the References: header based on MSG as a -comma-separated string. Normally, this the concatenation of 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, -return nil." - (let ((refs (mu4e-message-field msg :references)) - (old-msgid (mu4e-message-field msg :message-id))) - (when old-msgid - (setq refs (append refs (list old-msgid))) - (mapconcat - (lambda (msgid) (format "<%s>" msgid)) - refs ",")))) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;; determine the recipient fields for new messages - -(defun mu4e~compose-recipients-list-to-string (lst) - "Convert a lst LST of address cells into a string with a list of -e-mail addresses. If LST is nil, returns nil." - (when lst - (mapconcat - (lambda (addrcell) - (let ((name (car addrcell)) - (email (cdr addrcell))) - (if name - (format "\"%s\" <%s>" name email) - (format "%s" email)))) - lst ", "))) - -(defun mu4e~compose-address-cell-equal (cell1 cell2) - "Return t if cell1 and cell2 have the same e-mail - address (case-insensitively), nil otherwise. cell1 and cell2 are - cons cells (NAME . EMAIL)." - (string= - (downcase (or (cdr cell1) "")) - (downcase (or (cdr cell2) "")))) - - -(defun mu4e~compose-create-to-lst (origmsg) - "Create a list of address for the To: in a new message, based on -the original message ORIGMSG. If the Reply-To address is set, use -that, otherwise use the From address. Note, whatever was in the To: -field before, goes to the Cc:-list (if we're doing a reply-to-all)." - (let ((reply-to - (or (plist-get origmsg :reply-to) (plist-get origmsg :from)))) - (delete-duplicates reply-to :test #'mu4e~compose-address-cell-equal))) - - -(defun mu4e~compose-create-cc-lst (origmsg reply-all) - "Create a list of address for the Cc: in a new message, based on -the original message ORIGMSG, and whether it's a reply-all." - (when reply-all - (let* ((cc-lst ;; get the cc-field from the original, remove dups - (delete-duplicates - (append - (plist-get origmsg :to) - (plist-get origmsg :cc)) - :test #'mu4e~compose-address-cell-equal)) - ;; now we have the basic list, but we must remove - ;; addresses also in the to list - (cc-lst - (delete-if - (lambda (cc-cell) - (find-if - (lambda (to-cell) - (mu4e~compose-address-cell-equal cc-cell to-cell)) - (mu4e~compose-create-to-lst origmsg))) - cc-lst)) - ;; finally, we need to remove ourselves from the cc-list - ;; unless mu4e-compose-keep-self-cc is non-nil - (cc-lst - (if (or mu4e-compose-keep-self-cc (null user-mail-address)) - cc-lst - (delete-if - (lambda (cc-cell) - (mu4e~compose-address-cell-equal cc-cell - (cons nil user-mail-address))) - cc-lst)))) - cc-lst))) - -(defun mu4e~compose-recipients-construct (field origmsg &optional reply-all) - "Create value (a string) for the recipient field FIELD (a -symbol, :to or :cc), based on the original message ORIGMSG, -and (optionally) REPLY-ALL which indicates this is a reply-to-all -message. Return nil if there are no recipients for the particular field." - (mu4e~compose-recipients-list-to-string - (case field - (:to - (mu4e~compose-create-to-lst origmsg)) - (:cc - (mu4e~compose-create-cc-lst origmsg reply-all)) - (otherwise - (mu4e-error "Unsupported field"))))) - - -(defun mu4e~compose-from-construct () - "Construct a value for the From:-field of the reply to MSG, -based on `user-full-name' and `user-mail-address'; if the latter is -nil, function returns nil." - (when user-mail-address - (if user-full-name - (format "%s <%s>" user-full-name user-mail-address) - (format "%s" user-mail-address)))) - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defun mu4e~compose-insert-mail-header-separator () - "Insert `mail-header-separator' in the first empty line of the -message. message-mode needs this line to know where the headers end -and the body starts. Note, in `mu4e-compose-mode, we use -`before-save-hook' and `after-save-hook' to ensure that this -separator is never written to the message file. Also see -`mu4e-remove-mail-header-separator'." - (save-excursion - (let ((sepa (propertize mail-header-separator - 'intangible t - 'read-only "Can't touch this" - 'rear-nonsticky t - 'font-lock-face 'mu4e-system-face))) - (goto-char (point-min)) - ;; search for the first empty line - (if (search-forward-regexp "^$" nil t) - (replace-match (concat sepa)) - (progn ;; no empty line? then prepend one - (goto-char (point-max)) - (insert "\n" sepa)))))) - -(defun mu4e~compose-remove-mail-header-separator () - "Remove `mail-header-separator; we do this before saving a -file (and restore it afterwards), to ensure that the separator -never hits the disk. Also see `mu4e~compose-insert-mail-header-separator." - (save-excursion - (goto-char (point-min)) - ;; remove the --text follows this line-- separator - (when (search-forward-regexp (concat "^" mail-header-separator)) - (let ((inhibit-read-only t)) - (replace-match ""))))) - -(defun mu4e~compose-user-wants-reply-all (origmsg) - "Ask user whether she wants to reply to *all* recipients if there -are more than 1 (based on ORIGMSG)." - (let* ((recipnum - (+ (length (mu4e~compose-create-to-lst origmsg)) - (length (mu4e~compose-create-cc-lst origmsg t)))) - (response - (if (= recipnum 1) - 'all ;; with one recipient, we can reply to 'all'.... - (mu4e-read-option - "Reply to " - `( (,(format "all %d recipients" recipnum) . all) - ("sender only" . sender-only)))))) - (eq response 'all))) - -(defun mu4e~compose-message-filename-construct (&optional flagstr) - "Construct a randomized name for a message file with flags FLAGSTR; it looks -something like -