(defvar wl-draft-reply-buffer nil)
(defvar wl-draft-forward nil)
(defvar wl-draft-parent-folder nil)
+(defvar wl-draft-doing-mime-bcc nil)
(defvar wl-draft-config-sub-func-alist
'((body . wl-draft-config-sub-body)
(defun wl-draft-setup ()
(let ((field wl-draft-fields)
- ret-val)
+ cl)
(while field
- (setq ret-val (append ret-val
- (list (cons (concat (car field) " ")
- (concat (car field) " ")))))
+ (setq cl (append cl
+ (list (cons (concat (car field) " ")
+ (concat (car field) " ")))))
(setq field (cdr field)))
- (setq wl-draft-field-completion-list ret-val)))
+ (setq cl
+ (cons (cons (concat wl-draft-mime-bcc-field-name ": ")
+ (concat wl-draft-mime-bcc-field-name ": "))
+ cl))
+ (setq wl-draft-field-completion-list cl)
+ (setq wl-address-complete-header-regexp
+ (wl-regexp-opt
+ (append wl-address-complete-header-list
+ (list (concat wl-draft-mime-bcc-field-name ":")))))))
(defun wl-draft-make-mail-followup-to (recipients)
(if (elmo-list-member
(mapconcat 'identity references "\n\t"))))
(wl-draft (list (cons 'To "")
(cons 'Subject
- (concat "Forward: " original-subject))
+ (concat wl-forward-subject-prefix original-subject))
(cons 'References references))
nil nil nil nil parent-folder))
(goto-char (point-max))
(wl-message-field-exists-p "Resent-to")
(wl-message-field-exists-p "Cc")
(wl-message-field-exists-p "Bcc")
+ (wl-message-field-exists-p wl-draft-mime-bcc-field-name)
;;; This may be needed..
;;; (wl-message-field-exists-p "Fcc")
))
(buffer-live-p message-buf))
(progn
(with-current-buffer summary-buf
- (setq num (save-excursion
- (set-buffer message-buf)
- wl-message-buffer-cur-number))
- (setq entity (elmo-msgdb-overview-get-entity
- num (wl-summary-buffer-msgdb)))
- (setq date (elmo-msgdb-overview-entity-get-date entity))
- (setq from (elmo-msgdb-overview-entity-get-from entity)))
+ (let ((elmo-mime-charset wl-summary-buffer-mime-charset))
+ (setq num (save-excursion
+ (set-buffer message-buf)
+ wl-message-buffer-cur-number))
+ (setq entity (elmo-msgdb-overview-get-entity
+ num (wl-summary-buffer-msgdb)))
+ (setq date (elmo-msgdb-overview-entity-get-date entity))
+ (setq from (elmo-msgdb-overview-entity-get-from entity))))
(setq cite-title (format "At %s,\n%s wrote:"
(or date "some time ago")
(if wl-default-draft-cite-decorate-author
- (wl-summary-from-func-internal
- (or from "you"))
+ (funcall wl-summary-from-function
+ (or from "you"))
(or from "you"))))))
(and cite-title
(insert cite-title "\n"))
(kill-region b e)
(insert wl-draft-elide-ellipsis))
+;; Imported from message.el.
+(defun wl-draft-beginning-of-line (&optional n)
+ "Move point to beginning of header value or to beginning of line."
+ (interactive "p")
+ (let ((zrs 'zmacs-region-stays))
+ (when (and (interactive-p) (boundp zrs))
+ (set zrs t)))
+ (if (wl-draft-point-in-header-p)
+ (let* ((here (point))
+ (bol (progn (beginning-of-line n) (point)))
+ (eol (line-end-position))
+ (eoh (and (looking-at "[^ \t]")
+ (re-search-forward ": *" eol t))))
+ (if (and eoh (or (> here eoh) (= here bol)))
+ (goto-char eoh)
+ (goto-char bol)))
+ (beginning-of-line n)))
+
+(defun wl-draft-point-in-header-p ()
+ "Return t if point is in the header."
+ (save-excursion
+ (let ((p (point)))
+ (goto-char (point-min))
+ (not (re-search-forward
+ (concat "^" (regexp-quote mail-header-separator) "\n")
+ p t)))))
+
;; function for wl-sent-message-via
(defmacro wl-draft-sent-message-p (type)
","))))
""))
(id (if id (concat " id=" id) ""))
- (time (wl-sendlog-time)))
+ (time (format-time-string "%Y/%m/%d %T")))
(insert (format "%s proto=%s stat=%s%s%s%s\n"
time proto status server to id))
(if (and wl-draft-sendlog-max-size filesize
"Get address list suitable for smtp RCPT TO:<address>.
Group list content is removed if `wl-draft-remove-group-list-contents' is
non-nil."
- (let ((fields '("to" "cc" "bcc"))
+ (let ((fields (if (and wl-draft-doing-mime-bcc
+ wl-draft-disable-bcc-for-mime-bcc)
+ '("to" "cc")
+ '("to" "cc" "bcc")))
(resent-fields '("resent-to" "resent-cc" "resent-bcc"))
(case-fold-search t)
addrs recipients)
"$\\|^$") nil t)
(point-marker)))
(smtp-server
- (or wl-smtp-posting-server
- ;; Compatibility stuff for FLIM 1.12.5 or earlier.
- ;; They don't accept a function as the value of `smtp-server'.
- (if (functionp smtp-server)
- (funcall
- smtp-server
- sender
- ;; no harm..
- (let (wl-draft-remove-group-list-contents)
- (wl-draft-deduce-address-list
- (current-buffer) (point-min) delimline)))
- (or smtp-server "localhost"))))
+ (or wl-smtp-posting-server smtp-server "localhost"))
(smtp-service (or wl-smtp-posting-port smtp-service))
(smtp-local-domain (or smtp-local-domain wl-local-domain))
(id (std11-field-body "message-id"))
(defun wl-draft-insert-required-fields (&optional force-msgid)
"Insert Message-ID, Date, and From field.
-If FORCE-MSGID, ignore 'wl-insert-message-id'."
+If FORCE-MSGID, insert message-id regardless of `wl-insert-message-id'."
;; Insert Message-Id field...
(goto-char (point-min))
(when (and (or force-msgid
(defun wl-draft-dispatch-message (&optional mes-string)
"Send the message in the current buffer. Not modified the header fields."
- (let (delimline)
+ (let (delimline mime-bcc)
(if (and wl-draft-verbose-send mes-string)
(message mes-string))
;; get fcc folders.
(if (or (not (or wl-draft-force-queuing
wl-draft-force-queuing-mail))
(memq 'mail wl-sent-message-queued))
- (funcall wl-draft-send-mail-function)
+ (progn
+ (setq mime-bcc (wl-draft-mime-bcc-field))
+ (funcall wl-draft-send-mail-function)
+ (when (not (zerop (length mime-bcc)))
+ (wl-draft-do-mime-bcc mime-bcc)))
(push 'mail wl-sent-message-queued)
(wl-draft-set-sent-message 'mail 'unplugged)))
(if (and (wl-message-news-p)
(funcall wl-draft-send-news-function)
(push 'news wl-sent-message-queued)
(wl-draft-set-sent-message 'news 'unplugged))))
- ;;
(let* ((status (wl-draft-sent-message-results))
(unplugged-via (car status))
(sent-via (nth 1 status)))
;; If one sent, process fcc folder.
(if (and sent-via wl-draft-fcc-list)
(progn
- (wl-draft-do-fcc (wl-draft-get-header-delimiter) wl-draft-fcc-list)
+ (wl-draft-do-fcc (wl-draft-get-header-delimiter)
+ wl-draft-fcc-list)
(setq wl-draft-fcc-list nil)))
(if wl-draft-use-cache
(let ((id (std11-field-body "Message-ID"))
(expand-abbrev) ; for mail-abbrevs
(let ((mime-header-encode-method-alist
(append
- '((wl-draft-eword-encode-address-list
+ '((wl-draft-eword-encode-address-list
. (To Cc Bcc Resent-To Resent-Cc Bcc Resent-Bcc)))
(if (boundp 'mime-header-encode-method-alist)
(symbol-value 'mime-header-encode-method-alist)))))
(run-hooks 'mail-send-hook) ; translate buffer
)
+ ;;
(if wl-draft-verbose-send
(message (or mes-string "Sending...")))
(funcall wl-draft-send-function editing-buffer kill-when-done)
(cdr (car mail-send-actions)))
(error))
(setq mail-send-actions (cdr mail-send-actions)))
-;; (if (or (eq major-mode 'wl-draft-mode)
-;; (eq major-mode 'mail-mode))
-;; (local-set-key "\C-c\C-s" 'wl-draft-send)) ; override
(if wl-draft-verbose-send
(message (concat (or wl-draft-verbose-msg
mes-string "Sending...")
(and (buffer-live-p sending-buffer)
(kill-buffer sending-buffer))))))
+(defun wl-draft-mime-bcc-field ()
+ "Return the MIME-Bcc field body. The field is deleted."
+ (prog1 (std11-field-body wl-draft-mime-bcc-field-name)
+ (wl-draft-delete-field wl-draft-mime-bcc-field-name)))
+
+(defun wl-draft-do-mime-bcc (field-body)
+ "Send MIME-Bcc (Encapsulated blind carbon copy)."
+ (let ((orig-from (mime-decode-field-body (std11-field-body "from")
+ 'From))
+ (orig-subj (mime-decode-field-body (or (std11-field-body "subject")
+ "")
+ 'Subject))
+ (recipients (wl-parse-addresses field-body))
+ (draft-buffer (current-buffer))
+ wl-draft-use-frame)
+ (save-window-excursion
+ (when (and (not wl-draft-doing-mime-bcc) ; To avoid infinite loop.
+ (not (zerop (length field-body))))
+ (let ((wl-draft-doing-mime-bcc t))
+ (dolist (recipient recipients)
+ (wl-draft-create-buffer)
+ (wl-draft-create-contents
+ (append `((From . ,orig-from)
+ (To . ,recipient)
+ (Subject . ,(concat "A blind carbon copy ("
+ orig-subj
+ ")")))
+ (wl-draft-default-headers)))
+ (wl-draft-insert-mail-header-separator)
+ (wl-draft-prepare-edit)
+ (goto-char (point-max))
+ (insert (or wl-draft-mime-bcc-body
+ "This is a blind carbon copy.")
+ "\n")
+ (mime-edit-insert-tag "message" "rfc822")
+ (insert-buffer draft-buffer)
+ (let (wl-interactive-send)
+ (wl-draft-send 'kill-when-done))))))))
+
+;; Derived from `message-save-drafts' in T-gnus.
(defun wl-draft-save ()
- "Save current draft.
-Derived from `message-save-drafts' in T-gnus."
+ "Save current draft."
(interactive)
(if (buffer-modified-p)
(progn
(if (or (not bufname)
(string-equal bufname "")
(string-equal bufname (buffer-name)))
- (wl-draft-save-and-exit)
+ (let ((bufname (current-buffer)))
+ (when (or (not (buffer-modified-p))
+ (yes-or-no-p
+ (format "Buffer %s modified; kill anyway? " bufname)))
+ (set-buffer-modified-p nil)
+ (wl-draft-hide bufname)
+ (kill-buffer bufname)))
(kill-buffer bufname))))
(defun wl-draft-save-and-exit ()
(point-max)))))))
(defun wl-draft-get-fcc-list (header-end)
- (let (fcc-list
- (case-fold-search t))
- (or (markerp header-end) (error "HEADER-END must be a marker"))
- (save-excursion
- (goto-char (point-min))
- (while (re-search-forward "^Fcc:[ \t]*" header-end t)
- (setq fcc-list
- (cons (buffer-substring-no-properties
- (point)
- (progn
- (end-of-line)
- (skip-chars-backward " \t")
- (point)))
- fcc-list))
- (save-match-data
- (wl-folder-confirm-existence
- (wl-folder-get-elmo-folder (eword-decode-string (car fcc-list)))))
- (delete-region (match-beginning 0)
- (progn (forward-line 1) (point)))))
- fcc-list))
+ (if (and wl-draft-doing-mime-bcc
+ wl-draft-disable-fcc-for-mime-bcc)
+ (progn
+ (wl-draft-delete-field "fcc")
+ nil)
+ (let (fcc-list
+ (case-fold-search t))
+ (or (markerp header-end) (error "HEADER-END must be a marker"))
+ (save-excursion
+ (goto-char (point-min))
+ (while (re-search-forward "^Fcc:[ \t]*" header-end t)
+ (setq fcc-list
+ (cons (buffer-substring-no-properties
+ (point)
+ (progn
+ (end-of-line)
+ (skip-chars-backward " \t")
+ (point)))
+ fcc-list))
+ (save-match-data
+ (wl-folder-confirm-existence
+ (wl-folder-get-elmo-folder (eword-decode-string (car fcc-list)))))
+ (delete-region (match-beginning 0)
+ (progn (forward-line 1) (point)))))
+ fcc-list)))
(defun wl-draft-do-fcc (header-end &optional fcc-list)
(let ((send-mail-buffer (current-buffer))
(append header-alist (list (cons 'Subject ""))))))
(setq header-alist (append header-alist
(wl-draft-default-headers)
- (if body (list "" body))))
+ wl-draft-additional-header-alist
+ (if body (list "" (cons 'Body body)))))
(wl-draft-create-contents header-alist)
(if edit-again
(wl-draft-decode-body
'(function ;; funcall
string ;; insert string
(symbol . string) ;; insert symbol-value: string
- (symbol . function) ;; insert symbol-value: (funcall)
- (symbol . nil) ;; insert nothing
- (function . (arg1 arg2 ..)) ;; call function with argument
- nil ;; insert nothing
+ (symbol . function) ;; (funcall) and if it returns string,
+ ;; insert symbol-value: string
+ (symbol . nil) ;; do nothing
+ nil ;; do nothing
+ )
"
(unless (eq major-mode 'wl-draft-mode)
(error "wl-draft-create-header must be use in wl-draft-mode."))
(setq field (car (car halist)))
(setq value (cdr (car halist)))
(cond
- ((functionp field) (apply field value))
((symbolp field)
(cond
+ ((eq field 'Body) ; body
+ (insert value))
((stringp value) (insert (symbol-name field) ": " value "\n"))
((functionp value)
- (insert (symbol-name field) ": " (funcall value) "\n"))
- ((not value))
- (t
- (debug))))
- ((stringp field)
- (cond
- ((stringp value) (insert field value "\n"))
- ((functionp value) (insert field (funcall value) "\n"))
+ (let ((value-return (funcall value)))
+ (when (stringp value-return)
+ (insert (symbol-name field) ": " value-return "\n"))))
((not value))
(t
(debug))))
(if (not (= (preceding-char) ?\n))
(insert ?\n)))
-(defsubst wl-draft-insert-ccs (str cc)
+(defsubst wl-draft-trim-ccs (cc)
(let ((field
(if (functionp cc)
(funcall cc)
(wl-parse-addresses (std11-field-body "To"))
(wl-parse-addresses (std11-field-body "Cc"))))
(mapcar 'downcase wl-subscribed-mailing-list)))))
- (insert str field "\n"))))
+ field
+ nil)))
(defsubst wl-draft-default-headers ()
(list
- (cons "Mail-Reply-To: " (and wl-insert-mail-reply-to
- (wl-address-header-extract-address
- wl-from)))
- (cons "" wl-generate-mailer-string-function)
- (cons "Reply-To: " mail-default-reply-to)
- (cons 'wl-draft-insert-ccs
- (list "Bcc: " (or wl-bcc
- (and mail-self-blind (user-login-name)))))
- (cons 'wl-draft-insert-ccs
- (list "Fcc: " wl-fcc))
- (cons "Organization: " wl-organization)
+ (cons 'Mail-Reply-To (and wl-insert-mail-reply-to
+ (wl-address-header-extract-address
+ wl-from)))
+ (cons 'User-Agent wl-generate-mailer-string-function)
+ (cons 'Reply-To mail-default-reply-to)
+ (cons 'Bcc (function
+ (lambda ()
+ (wl-draft-trim-ccs
+ (or wl-bcc (and mail-self-blind (user-login-name)))))))
+ (cons 'Fcc (function
+ (lambda ()
+ (wl-draft-trim-ccs wl-fcc))))
+ (cons 'Organization wl-organization)
(and wl-auto-insert-x-face
(file-exists-p wl-x-face-file)
'wl-draft-insert-x-face-field-here) ;; allow nil
mail-default-headers
;; check \n at th end of line for `mail-default-headers'
'wl-draft-check-new-line
-; wl-draft-default-headers
-; 'wl-draft-check-new-line
))
(defun wl-draft-insert-mail-header-separator (&optional delimline)
(elmo-nntp-default-port
(or wl-nntp-posting-port elmo-nntp-default-port))
(elmo-nntp-default-stream-type
- (or wl-nntp-posting-stream-type elmo-nntp-default-stream-type)))
+ (or wl-nntp-posting-stream-type elmo-nntp-default-stream-type))
+ (elmo-nntp-default-function wl-nntp-posting-function)
+ condition)
+ (if (setq condition (cdr (elmo-string-matched-assoc
+ (std11-field-body "Newsgroups")
+ wl-nntp-posting-config-alist)))
+ (if (stringp condition)
+ (setq elmo-nntp-default-server condition)
+ (while (car condition)
+ (set (intern (format "elmo-nntp-default-%s"
+ (symbol-name (caar condition))))
+ (cdar condition))
+ (setq condition (cdr condition)))))
+ (unless elmo-nntp-default-function
+ (error "wl-draft-nntp-send: posting-function is nil."))
(if (not (elmo-plugged-p elmo-nntp-default-server elmo-nntp-default-port))
(wl-draft-set-sent-message 'news 'unplugged
(cons elmo-nntp-default-server
elmo-nntp-default-port))
- (elmo-nntp-post elmo-nntp-default-server (current-buffer))
+ (funcall elmo-nntp-default-function
+ elmo-nntp-default-server (current-buffer))
(wl-draft-set-sent-message 'news 'sent)
(wl-draft-write-sendlog 'ok 'nntp elmo-nntp-default-server
(std11-field-body "Newsgroups")
(wl-draft-config-exec config-alist reply-buf)))))
(defun wl-draft-config-exec (&optional config-alist reply-buf)
- "Change headers in draft sending time."
+ "Change headers according to the value of `wl-draft-config-alist'.
+Automatically applied in draft sending time."
(interactive)
(let ((case-fold-search t)
(alist (or config-alist wl-draft-config-alist))
(interactive "P")
(if arg
(wl-jump-to-draft-folder)
- (let ((bufs (buffer-list))
- (draft-regexp (concat
- "^" (regexp-quote
- (elmo-localdir-folder-directory-internal
- (wl-folder-get-elmo-folder wl-draft-folder)))))
- buf draft-bufs)
- (while bufs
- (if (and
- (setq buf (with-current-buffer (car bufs)
- wl-draft-buffer-file-name))
- (string-match draft-regexp buf))
- (setq draft-bufs (cons (buffer-name (car bufs)) draft-bufs)))
- (setq bufs (cdr bufs)))
+ (let ((draft-bufs (wl-collect-draft))
+ buf)
(cond
((null draft-bufs)
(message "No draft buffer exist."))
(t
(setq draft-bufs
- (sort draft-bufs (function (lambda (a b) (not (string< a b))))))
- (if (setq buf (cdr (member (buffer-name) draft-bufs)))
+ (sort (mapcar 'buffer-name draft-bufs)
+ (function (lambda (a b)
+ (not (string< a b))))))
+ (if (setq buf (cdr (member (buffer-name)
+ draft-bufs)))
(setq buf (car buf))
(setq buf (car draft-bufs)))
(switch-to-buffer buf))))))