+;; @ For `message-mail-follow-up-address-checker'.
+
+(defcustom message-mailing-list-address-list nil
+ "*Regexp matching addresses that are mailing lists.
+It must be a simple regexp string or a list of regexp strings.
+This variable is used by \`message-check-mailing-list-with-address-list\'."
+ :group 'message-mail
+ :type '(repeat regexp))
+
+(defun message-check-mailing-list-with-address-list (alist)
+ (let ((s alist)
+ (regexp (if (stringp message-mailing-list-address-list)
+ message-mailing-list-address-list
+ (mapconcat
+ (lambda (x)
+ x)
+ message-mailing-list-address-list
+ "\\|")))
+ address non-mailing-list mailing-list)
+ (while (setq address (car (pop s)))
+ (if (string-match regexp address)
+ (setq mailing-list t)
+ (setq non-mailing-list
+ (append non-mailing-list (list address)))))
+ (if (or (not non-mailing-list)
+ (not mailing-list)
+ (not (y-or-n-p "Do you want to remove private address? ")))
+ alist
+ (setq s non-mailing-list)
+ (while s
+ (setq alist (delq (assoc (pop s) alist) alist)))
+ alist)
+ ))
+
+(defcustom message-mailing-list-address-p nil
+ "*The function return t if address is a mailing list.
+It must be function, and interface is (ADDRESS).
+ADDRESS is a string of mail address.
+This variable is used by \`message-check-mailing-list-with-function\'."
+ :group 'message-mail
+ :type 'function)
+
+(defun message-check-mailing-list-with-function (alist)
+ (let ((s alist)
+ address non-mailing-list mailing-list)
+ (while (setq address (car (pop s)))
+ (if (funcall message-mailing-list-address-p address)
+ (setq mailing-list t)
+ (setq non-mailing-list
+ (append non-mailing-list (list address)))))
+ (if (or (not non-mailing-list)
+ (not mailing-list)
+ (not (y-or-n-p "Do you want to remove private address? ")))
+ alist
+ (setq s non-mailing-list)
+ (while s
+ (setq alist (delq (assoc (pop s) alist) alist)))
+ alist)
+ ))
+
+;;; @ for locale specification.
+;;;
+
+(defcustom message-mime-charset-recover-function
+ 'message-mime-charset-recover-by-ask
+ "A function called to recover \
+when could not found legal MIME charset for sending message."
+ :type '(radio (function-item message-mime-charset-recover-by-ask)
+ (function :tag "Other"))
+ :group 'message-sending)
+
+(defvar message-mime-charset-recover-args nil)
+(defvar message-charsets-mime-charset-alist nil)
+
+(defun message-maybe-encode ()
+ (when message-mime-mode
+ (run-hooks 'mime-edit-translate-hook))
+ (let ((locale-list (message-locale-detect)))
+ (when message-mime-mode
+ (let* ((default-mime-charset-detect-method-for-write
+ (or message-mime-charset-recover-function
+ default-mime-charset-detect-method-for-write))
+ message-mime-charset-recover-args
+ (charsets-mime-charset-alist charsets-mime-charset-alist)
+ (message-charsets-mime-charset-alist charsets-mime-charset-alist))
+ (message-mime-charset-setup locale-list)
+ (if (catch 'mime-edit-error
+ (save-excursion
+ (mime-edit-translate-body)
+ ))
+ (error "Translation error!")
+ ))
+ (end-of-invisible)
+ (run-hooks 'mime-edit-exit-hook)
+ )))
+
+(defcustom message-locale-default nil
+ "Default locale for sending message."
+ :group 'message-sending
+ :type 'symbol)
+
+(defcustom message-locale-detect-for-mail nil
+ "*A function called to detect locale from recipient mail address."
+ :group 'message-sending
+ :type 'function)
+
+(defcustom message-locale-detect-for-news
+ 'message-locale-detect-with-newsgroup-alist
+ "*A function called to detect locale from newsgroup."
+ :group 'message-sending
+ :type 'function)
+
+(defun message-locale-detect ()
+ (when (or message-locale-detect-for-news
+ message-locale-detect-for-mail)
+ (save-excursion
+ (save-restriction
+ (message-narrow-to-head)
+ (let (lc dest)
+ (when message-locale-detect-for-news
+ (setq lc (mapcar
+ (lambda (newsgroup)
+ (funcall message-locale-detect-for-news
+ (and (string-match "[^ \t]+" newsgroup)
+ (match-string 0 newsgroup))))
+ (message-tokenize-header
+ (message-fetch-field "newsgroups")))))
+ (when message-locale-detect-for-mail
+ (let ((field-list '("to" "cc" "bcc")))
+ (while (car field-list)
+ (setq lc (append
+ lc
+ (mapcar
+ (lambda (address)
+ (funcall message-locale-detect-for-mail
+ (car
+ (cdr (std11-extract-address-components
+ address)))))
+ (message-tokenize-header
+ (message-fetch-field (pop field-list)))))))))
+ (setq lc (delq nil lc))
+ (while lc
+ (setq dest (cons (car lc) dest)
+ lc (delq (car lc) lc)))
+ (or dest
+ (and message-locale-default (list message-locale-default)))
+ )))))
+
+(defvar message-locale-newsgroup-alist
+ '(("^fj\\." . fj)
+ ))
+
+(defun message-locale-detect-with-newsgroup-alist (newsgroup)
+ (let ((rest message-locale-newsgroup-alist)
+ done)
+ (while (and (not done)
+ rest)
+ (when (string-match (car (car rest)) newsgroup)
+ (setq done (car rest)))
+ (setq rest (cdr rest)))
+ (cdr done)
+ ))
+
+(defvar message-locale-mail-address-alist nil)
+
+(defun message-locale-detect-with-mail-address-alist (address)
+ (let ((rest message-locale-mail-address-alist)
+ done)
+ (while (and (not done)
+ rest)
+ (when (string-match (car (car rest)) address)
+ (setq done (car rest)))
+ (setq rest (cdr rest)))
+ (cdr done)
+ ))
+
+(defcustom message-mime-charset-recover-ask-function
+ 'message-mime-charset-recover-ask-y-or-n
+ "A function called to ask MIME charset.
+This funtion will by called from \`message-mime-charset-recover-by-ask\'."
+ :type '(radio (function-item message-mime-charset-recover-ask-y-or-n)
+ (function-item message-mime-charset-recover-ask-charset)
+ (function :tag "Other"))
+ :group 'message-sending)
+
+(defun message-mime-charset-recover-by-ask (type charsets &rest args)
+ (let* ((charsets-mime-charset-alist message-charsets-mime-charset-alist)
+ (default-charset
+ (upcase (symbol-name
+ (or (charsets-to-mime-charset charsets)
+ default-mime-charset-for-write))))
+ charset)
+ (save-excursion
+ (save-restriction
+ (save-window-excursion
+ (when (eq type 'region)
+ (narrow-to-region (car args) (car (cdr args)))
+ (pop-to-buffer (current-buffer) nil t))
+ (if (setq charset (funcall message-mime-charset-recover-ask-function
+ default-charset charsets))
+ (intern (downcase charset))
+ (error "Canceled.")))))))
+
+(defun message-mime-charset-recover-ask-y-or-n (default-charset charsets)
+ (or (y-or-n-p (format "MIME charset %s is selected. OK? "
+ default-charset))
+ (error "Canceled."))
+ default-charset)
+
+(defun message-mime-charset-recover-ask-charset (default-charset charsets)
+ (let ((alist (mapcar
+ (lambda (cs)
+ (list (upcase (symbol-name cs))))
+ (mime-charset-list)))
+ charset)
+ (while (not charset)
+ (setq charset
+ (completing-read "What MIME charset: "
+ alist nil t default-charset))
+ (when (string= charset "")
+ (setq charset nil)))
+ charset))
+
+(defvar message-locale-mime-charsets-alist
+ '((fj . (us-ascii iso-2022-jp iso-2022-jp-2))
+ (none . nil)
+ ))
+
+(defun message-mime-charset-setup (locale-list)
+ (let (locale-cs)
+ (while (and charsets-mime-charset-alist
+ locale-list)
+ (unless (setq locale-cs
+ (assq (car locale-list)
+ message-locale-mime-charsets-alist))
+ (error "Unknown locale \`%s\'. Add locale to \`%s\'."
+ (car locale-list)
+ 'message-locale-mime-charsets-alist))
+ (setq locale-cs (cdr locale-cs)
+ charsets-mime-charset-alist (delq nil
+ (mapcar
+ (lambda (cs)
+ (and (memq (cdr cs) locale-cs)
+ cs))
+ charsets-mime-charset-alist))
+ locale-list (cdr locale-list))
+ )))
+
+;;; @ for MIME Edit mode
+;;;
+
+(defun message-mime-insert-article (&optional message)
+ (interactive)
+ (let ((message-cite-function 'mime-edit-inserted-message-filter)
+ (message-reply-buffer
+ (message-get-parameter-with-eval 'original-buffer))
+ (start (point)))
+ (message-yank-original nil)
+ (save-excursion
+ (narrow-to-region (goto-char start)
+ (if (search-forward "\n\n" nil t)
+ (1- (point))
+ (point-max)))
+ (goto-char (point-min))
+ (message-remove-header message-included-forward-headers t nil t)
+ (widen))))
+
+(set-alist 'mime-edit-message-inserter-alist
+ 'message-mode (function message-mime-insert-article))
+
+(defun message-mime-encode (start end &optional orig-buf)
+ (save-restriction
+ (narrow-to-region start end)
+ (when (with-current-buffer orig-buf
+ mime-edit-mode-flag)
+ (run-hooks 'mime-edit-translate-hook)
+ (mime-edit-translate-buffer)
+ )
+ (goto-char start)
+ (and (search-forward (concat "\n" mail-header-separator "\n") nil t)
+ (replace-match "\n\n"))
+ ))
+
+(set-alist 'format-alist
+ 'mime-message
+ '("MIME message."
+ "1\\(^\\)"
+ nil
+ message-mime-encode
+ t nil))
+
+(defun message-mime-setup ()
+ (turn-on-mime-edit)
+ (add-to-list 'buffer-file-format 'mime-message))