(eval-when-compile
(require 'cl)
(defvar gnus-list-identifiers)) ; gnus-sum is required where necessary
+
(require 'mailheader)
(require 'nnheader)
;; This is apparently necessary even though things are autoloaded:
:group 'message-insertion
:type 'regexp)
+(defcustom message-cite-prefix-regexp
+ ;; ?-, ?_ or ?. MUST NOT be in syntax entry w.
+ "\\([ \t]*\\(\\w\\|[-_.]\\)+>+\\|[ \t]*[]>»|:}+]\\)+"
+ "*Regexp matching the longest possible citation prefix on a line."
+ :group 'message-insertion
+ :type 'regexp)
+
(defcustom message-cancel-message "I am canceling my own article.\n"
"Message to be inserted in the cancel message."
:group 'message-interface
:group 'message-faces)
(defvar message-font-lock-keywords
- (let* ((cite-prefix "A-Za-z")
- (cite-suffix (concat cite-prefix "0-9_.@-"))
- (content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)"))
+ (let ((content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)\n?"))
`((,(concat "^\\([Tt]o:\\)" content)
(1 'message-header-name-face)
(2 'message-header-to-face nil t))
`((,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$")
1 'message-separator-face))
nil)
- (,(concat "^[ \t]*"
- "\\([" cite-prefix "]+[" cite-suffix "]*\\)?"
- "[:>|}].*")
+ (,(concat "^\\(" message-cite-prefix-regexp "\\).*")
(0 'message-cited-text-face))
("<#/?\\(multipart\\|part\\|external\\|mml\\).*>"
(0 'message-mml-face))))
(User-Agent))
"Alist used for formatting headers.")
+(defvar message-options nil
+ "Some saved answers when sending message.")
+
(eval-and-compile
(autoload 'message-setup-toolbar "messagexmas")
(autoload 'mh-new-draft-name "mh-comp")
(concat
"[ \t]*" ; possible initial space
"\\(\\(" (regexp-quote message-yank-prefix) "\\|" ; user's prefix
- "\\w+>\\|" ; supercite-style prefix
+ "\\(\\w\\|[-_.]\\)+>\\|" ; supercite-style prefix
"[|:>]" ; standard prefix
"\\)[ \t]*\\)+"))) ; possible space after each prefix
(setq paragraph-start
(mail-fetch-field "to")
(not (string-match "\\` *\\'" (mail-fetch-field "to"))))
(insert ", "))
- (insert (or (message-fetch-reply-field "reply-to")
+ (insert (or (message-fetch-reply-field "mail-reply-to")
+ (message-fetch-reply-field "reply-to")
(message-fetch-reply-field "from") "")))
(defun message-widen-reply ()
(defun message-newline-and-reformat ()
"Insert four newlines, and then reformat if inside quoted text."
(interactive)
- (let ((prefix "[]>»|:}+ \t]*")
- (supercite-thing "[-._a-zA-Z0-9]*[>]+[ \t]*")
- quoted point)
+ (let (quoted point)
(unless (bolp)
(save-excursion
(beginning-of-line)
- (when (looking-at (concat prefix
- supercite-thing))
+ (when (looking-at message-cite-prefix-regexp)
(setq quoted (match-string 0))))
(insert "\n"))
(setq point (point))
(message message-sending-message)
(let ((alist message-send-method-alist)
(success t)
- elem sent)
+ elem sent
+ (message-options message-options))
+ (message-options-set-recipient)
(while (and success
(setq elem (pop alist)))
(when (funcall (cadr elem))
(Subject . ,(or subject ""))))))
(defun message-get-reply-headers (wide &optional to-address)
- (let (follow-to mct never-mct from to cc reply-to ccalist)
+ (let (follow-to mct never-mct from to cc reply-to mrt mft ccalist)
;; Find all relevant headers we need.
(setq from (message-fetch-field "from")
to (message-fetch-field "to")
cc (message-fetch-field "cc")
mct (message-fetch-field "mail-copies-to")
- reply-to (message-fetch-field "reply-to"))
+ reply-to (message-fetch-field "reply-to")
+ mrt (message-fetch-field "mail-reply-to")
+ mft (message-fetch-field "mail-followup-to"))
;; Handle special values of Mail-Copies-To.
(when mct
(setq mct nil))
((or (equal (downcase mct) "always")
(equal (downcase mct) "poster"))
- (setq mct (or reply-to from)))))
+ (setq mct (or mrt reply-to from)))))
(if (or (not wide)
to-address)
(progn
- (setq follow-to (list (cons 'To (or to-address reply-to from))))
- (when (and wide mct)
- (push (cons 'Cc mct) follow-to)))
+ (setq follow-to (list (cons 'To (or to-address mrt reply-to from))))
+ (when (and wide (or mft mct))
+ (push (cons 'Cc (or mft mct)) follow-to)))
(let (ccalist)
(save-excursion
(message-set-work-buffer)
- (unless never-mct
- (insert (or reply-to from "")))
- (insert (if to (concat (if (bolp) "" ", ") to "") ""))
- (insert (if mct (concat (if (bolp) "" ", ") mct) ""))
- (insert (if cc (concat (if (bolp) "" ", ") cc) ""))
+ (if (and mft
+ message-use-followup-to
+ (or (not (eq message-use-followup-to 'ask))
+ (message-y-or-n-p
+ (concat "Obey Mail-Followup-To? ") t "\
+You should normally obey the Mail-Followup-To: header. In this
+article, it has the value of
+
+" mft "
+
+which directs your response to " (if (string-match "," mft)
+ "the specified addresses"
+ "that address only") ".
+
+If a message is posted to several mailing lists, Mail-Followup-To is
+often used to direct the following discussion to one list only,
+because discussions that are spread over several lists tend to be
+fragmented and very difficult to follow.
+
+Also, some source/announcement lists are not indented for discussion;
+responses here are directed to other addresses.")))
+ (insert mft)
+ (unless never-mct
+ (insert (or mrt reply-to from "")))
+ (insert (if to (concat (if (bolp) "" ", ") to "") ""))
+ (insert (if mct (concat (if (bolp) "" ", ") mct) ""))
+ (insert (if cc (concat (if (bolp) "" ", ") cc) "")))
(goto-char (point-min))
(while (re-search-forward "[ \t]+" nil t)
(replace-match " " t t))
(goto-char (point-min))
;; Perhaps "Mail-Copies-To: never" removed the only address?
(when (eobp)
- (insert (or reply-to from "")))
+ (insert (or mrt reply-to from "")))
(setq ccalist
(mapcar
(lambda (addr)
(push ccs follow-to)))))
follow-to))
-
;;;###autoload
(defun message-reply (&optional to-address wide)
"Start editing a reply to the article in the current buffer."
(interactive)
(require 'gnus-sum) ; for gnus-list-identifiers
(let ((cur (current-buffer))
- from subject date reply-to mct
+ from subject date reply-to mrt mct
references message-id follow-to
(inhibit-point-motion-hooks t)
(message-this-is-news t)
newsgroups (message-fetch-field "newsgroups")
posted-to (message-fetch-field "posted-to")
reply-to (message-fetch-field "reply-to")
+ mrt (message-fetch-field "mail-reply-to")
distribution (message-fetch-field "distribution")
mct (message-fetch-field "mail-copies-to"))
(when (and (setq gnus-warning (message-fetch-field "gnus-warning"))
does not read the newsgroup, so he wouldn't see any replies sent to it."))
(progn
(setq message-this-is-news nil)
- (cons 'To (or reply-to from "")))
+ (cons 'To (or mrt reply-to from "")))
(cons 'Newsgroups newsgroups)))
(t
(if (or (equal followup-to newsgroups)
(equal (downcase mct) "nobody"))))
(list (cons 'Cc (if (or (equal (downcase mct) "always")
(equal (downcase mct) "poster"))
- (or reply-to from "")
+ (or mrt reply-to from "")
mct)))))
cur)
;;; Miscellaneous functions
-;; stolen (and renamed) from nnheader.el
-(if (fboundp 'subst-char-in-string)
- (defsubst message-replace-chars-in-string (string from to)
- (subst-char-in-string from to string))
- (defun message-replace-chars-in-string (string from to)
- "Replace characters in STRING from FROM to TO."
- (let ((string (substring string 0)) ;Copy string.
- (len (length string))
- (idx 0))
- ;; Replace all occurrences of FROM with TO.
- (while (< idx len)
- (when (= (aref string idx) from)
- (aset string idx to))
- (setq idx (1+ idx)))
- string)))
+(defsubst message-replace-chars-in-string (string from to)
+ (mm-subst-char-in-string from to string))
;;;
;;; MIME functions
(goto-char (point-max))
(insert "From: " email "\n"))))
+(defun message-options-get (symbol)
+ (cdr (assq symbol message-options)))
+
+(defun message-options-set (symbol value)
+ (let ((the-cons (assq symbol message-options)))
+ (if the-cons
+ (if value
+ (setcdr the-cons value)
+ (setq message-options (delq the-cons message-options)))
+ (and value
+ (push (cons symbol value) message-options))))
+ value)
+
+(defun message-options-set-recipient ()
+ (save-restriction
+ (message-narrow-to-headers-or-head)
+ (message-options-set 'message-sender
+ (mail-strip-quoted-names
+ (message-fetch-field "from")))
+ (message-options-set 'message-recipients
+ (mail-strip-quoted-names
+ (message-fetch-field "to")))))
+
(provide 'message)
(run-hooks 'message-load-hook)