Mercurial > emacs
changeset 60691:2333319dc01c
(sendmail-send-it): Reenaable the code
to compute resend-to-address and use it.
(mail-yank-ignored-headers)
(mail-font-lock-keywords, mail-mode-fill-paragraph):
Add Mail-Followup-To and Mail-Reply-To headers.
(mail-citation-hook): Add autoload cookie.
(mail-mode): Doc fix.
(mail-mode-map): Bind mail-mail-followup-to and mail-mail-reply-to.
(mail-send): Compute Mail-Followup-To and Mail-Reply-To headers.
(mail-mode-fill-paragraph): Handle those headers.
(mail-mailing-lists): New variable.
(mail-mail-reply-to, mail-mail-followup-to): New functions.
author | Richard M. Stallman <rms@gnu.org> |
---|---|
date | Fri, 18 Mar 2005 00:08:24 +0000 |
parents | d23604c1b411 |
children | e2880855e3d0 |
files | lisp/mail/sendmail.el |
diffstat | 1 files changed, 127 insertions(+), 46 deletions(-) [+] |
line wrap: on
line diff
--- a/lisp/mail/sendmail.el Thu Mar 17 23:59:31 2005 +0000 +++ b/lisp/mail/sendmail.el Fri Mar 18 00:08:24 2005 +0000 @@ -107,7 +107,7 @@ :group 'sendmail) ;;;###autoload -(defcustom mail-yank-ignored-headers "^via:\\|^mail-from:\\|^origin:\\|^status:\\|^remailed\\|^received:\\|^message-id:\\|^summary-line:\\|^to:\\|^subject:\\|^in-reply-to:\\|^return-path:" "\ +(defcustom mail-yank-ignored-headers "^via:\\|^mail-from:\\|^origin:\\|^status:\\|^remailed\\|^received:\\|^message-id:\\|^summary-line:\\|^to:\\|^subject:\\|^in-reply-to:\\|^return-path:\\|^mail-reply-to:\\|^mail-followup-to:" "\ *Delete these headers from old message when it's inserted in a reply." :type 'regexp :group 'sendmail) @@ -213,6 +213,7 @@ This is a normal hook, misnamed for historical reasons. It is semi-obsolete and mail agents should no longer use it.") +;;;###autoload (defcustom mail-citation-hook nil "*Hook for modifying a citation just inserted in the mail buffer. Each hook function can find the citation between (point) and (mark t), @@ -363,7 +364,7 @@ (cite-prefix "[:alpha:]") (cite-suffix (concat cite-prefix "0-9_.@-`'\""))) (list '("^\\(To\\|Newsgroups\\):" . font-lock-function-name-face) - '("^\\(B?CC\\|Reply-to\\):" . font-lock-keyword-face) + '("^\\(B?CC\\|Reply-to\\|Mail-\\(reply\\|followup\\)-to\\):" . font-lock-keyword-face) '("^\\(Subject:\\)[ \t]*\\(.+\\)?" (1 font-lock-comment-face) (2 font-lock-type-face nil t)) ;; Use EVAL to delay in case `mail-header-separator' gets changed. @@ -492,6 +493,8 @@ \\[mail-to] move to To: \\[mail-subject] move to Subject: \\[mail-cc] move to CC: \\[mail-bcc] move to BCC: \\[mail-fcc] move to FCC: \\[mail-reply-to] move to Reply-To: + \\[mail-mail-reply-to] move to Mail-Reply-To: + \\[mail-mail-followup-to] move to Mail-Followup-To: \\[mail-text] mail-text (move to beginning of message text). \\[mail-signature] mail-signature (insert `mail-signature-file' file). \\[mail-yank-original] mail-yank-original (insert current message, in Rmail). @@ -599,6 +602,7 @@ ;; make sure we can fill after each address. (if (member fieldname '("to" "cc" "bcc" "from" "reply-to" + "mail-reply-to" "mail-followup-to" "resent-to" "resent-cc" "resent-bcc" "resent-from" "resent-reply-to")) (while (search-forward "," end t) @@ -627,6 +631,8 @@ (define-key mail-mode-map "\C-c\C-f\C-c" 'mail-cc) (define-key mail-mode-map "\C-c\C-f\C-s" 'mail-subject) (define-key mail-mode-map "\C-c\C-f\C-r" 'mail-reply-to) + (define-key mail-mode-map "\C-c\C-f\C-a" 'mail-mail-reply-to) ; author + (define-key mail-mode-map "\C-c\C-f\C-l" 'mail-mail-followup-to) ; list (define-key mail-mode-map "\C-c\C-t" 'mail-text) (define-key mail-mode-map "\C-c\C-y" 'mail-yank-original) (define-key mail-mode-map "\C-c\C-r" 'mail-yank-region) @@ -674,6 +680,12 @@ (define-key mail-mode-map [menu-bar headers sent-via] '("Sent Via" . mail-sent-via)) +(define-key mail-mode-map [menu-bar headers mail-reply-to] + '("Mail Reply To" . mail-mail-reply-to)) + +(define-key mail-mode-map [menu-bar headers mail-followup-to] + '("Mail Followup To" . mail-mail-followup-to)) + (define-key mail-mode-map [menu-bar headers reply-to] '("Reply-To" . mail-reply-to)) @@ -745,6 +757,16 @@ :options '(flyspell-mode-off) :group 'sendmail) +;;;###autoload +(defcustom mail-mailing-lists nil "\ +*List of mailing list addresses the user is subscribed to. + +The variable is used to trigger insertion of the \"Mail-Followup-To\" +header when sending a message to a mailing list." + :type '(repeat string) + :group 'sendmail) + + (defun mail-send () "Send the message in the current buffer. If `mail-interactive' is non-nil, wait for success indication @@ -757,7 +779,45 @@ (or (buffer-modified-p) (y-or-n-p "Message already sent; resend? "))) (let ((inhibit-read-only t) - (opoint (point))) + (opoint (point)) + (ml (when mail-mailing-lists + ;; The surrounding regexp assumes the use of + ;; `mail-strip-quoted-names' on addresses before matching + ;; Cannot deal with full RFC 822 freedom, but that is + ;; unlikely to be problematic. + (concat "\\(?:[[:space:];,]\\|\\`\\)" + (regexp-opt mail-mailing-lists t) + "\\(?:[[:space:];,]\\|\\'\\)")))) + ;; If there are mailing lists defined + (when ml + (save-excursion + (let* ((to (mail-fetch-field "to" nil t)) + (cc (mail-fetch-field "cc" nil t)) + (new-header-values ; To: and Cc: + (mail-strip-quoted-names + (concat to (when cc (concat ", " cc)))))) + ;; If message goes to known mailing list ... + (when (string-match ml new-header-values) + ;; Add Mail-Followup-To if none yet + (unless (mail-fetch-field "mail-followup-to") + (goto-char (mail-header-end)) + (insert "Mail-Followup-To: " + (let ((l)) + (mapc + ;; remove duplicates + '(lambda (e) + (unless (member e l) + (push e l))) + (split-string new-header-values ", +" t)) + (mapconcat 'identity l ", ")) + "\n")) + ;; Add Mail-Reply-To if none yet + (unless (mail-fetch-field "mail-reply-to") + (goto-char (mail-header-end)) + (insert "Mail-Reply-To: " + (or (mail-fetch-field "reply-to") + user-mail-address) + "\n")))))) (unless (memq mail-send-nonascii '(t mime)) (goto-char (point-min)) (skip-chars-forward "\0-\177") @@ -833,7 +893,7 @@ (multibyte enable-multibyte-characters) (case-fold-search nil) (selected-coding (select-message-coding-system)) -;;; resend-to-addresses + resend-to-addresses delimline fcc-was-found (mailbuf (current-buffer)) @@ -869,39 +929,42 @@ (< (point) delimline)) (replace-match "\n")) (goto-char (point-min)) + ;; Look for Resent- headers. They require sending + ;; the message specially. (let ((case-fold-search t)) -;;; (goto-char (point-min)) -;;; (while (re-search-forward "^Resent-\\(to\\|cc\\|bcc\\):" delimline t) -;;; (setq resend-to-addresses -;;; (save-restriction -;;; (narrow-to-region (point) -;;; (save-excursion -;;; (forward-line 1) -;;; (while (looking-at "^[ \t]") -;;; (forward-line 1)) -;;; (point))) -;;; (append (mail-parse-comma-list) -;;; resend-to-addresses))) -;;; ;; Delete Resent-BCC ourselves -;;; (if (save-excursion (beginning-of-line) -;;; (looking-at "resent-bcc")) -;;; (delete-region (save-excursion (beginning-of-line) (point)) -;;; (save-excursion (end-of-line) (1+ (point)))))) -;;; Apparently this causes a duplicate Sender. -;;; ;; If the From is different than current user, insert Sender. -;;; (goto-char (point-min)) -;;; (and (re-search-forward "^From:" delimline t) -;;; (progn -;;; (require 'mail-utils) -;;; (not (string-equal -;;; (mail-strip-quoted-names -;;; (save-restriction -;;; (narrow-to-region (point-min) delimline) -;;; (mail-fetch-field "From"))) -;;; (user-login-name)))) -;;; (progn -;;; (forward-line 1) -;;; (insert "Sender: " (user-login-name) "\n"))) + (goto-char (point-min)) + (while (re-search-forward "^Resent-\\(to\\|cc\\|bcc\\):" delimline t) + ;; Put a list of such addresses in resend-to-addresses. + (setq resend-to-addresses + (save-restriction + (narrow-to-region (point) + (save-excursion + (forward-line 1) + (while (looking-at "^[ \t]") + (forward-line 1)) + (point))) + (append (mail-parse-comma-list) + resend-to-addresses))) + ;; Delete Resent-BCC ourselves + (if (save-excursion (beginning-of-line) + (looking-at "resent-bcc")) + (delete-region (save-excursion (beginning-of-line) (point)) + (save-excursion (end-of-line) (1+ (point)))))) +;;; Apparently this causes a duplicate Sender. +;;; ;; If the From is different than current user, insert Sender. +;;; (goto-char (point-min)) +;;; (and (re-search-forward "^From:" delimline t) +;;; (progn +;;; (require 'mail-utils) +;;; (not (string-equal +;;; (mail-strip-quoted-names +;;; (save-restriction +;;; (narrow-to-region (point-min) delimline) +;;; (mail-fetch-field "From"))) +;;; (user-login-name)))) +;;; (progn +;;; (forward-line 1) +;;; (insert "Sender: " (user-login-name) "\n"))) ;; Don't send out a blank subject line (goto-char (point-min)) (if (re-search-forward "^Subject:\\([ \t]*\n\\)+\\b" delimline t) @@ -1000,9 +1063,9 @@ (erase-buffer)))) (goto-char (point-min)) (if (let ((case-fold-search t)) - (re-search-forward "^To:\\|^cc:\\|^bcc:\\|^resent-to:\ -\\|^resent-cc:\\|^resent-bcc:" - delimline t)) + (or resend-to-addresses + (re-search-forward "^To:\\|^cc:\\|^bcc:" + delimline t))) (let* ((default-directory "/") (coding-system-for-write selected-coding) (args @@ -1023,14 +1086,14 @@ ;; These mean "report errors by mail" ;; and "deliver in background". '("-oem" "-odb")) -;;; ;; Get the addresses from the message -;;; ;; unless this is a resend. -;;; ;; We must not do that for a resend -;;; ;; because we would find the original addresses. -;;; ;; For a resend, include the specific addresses. -;;; (or resend-to-addresses + ;; Get the addresses from the message + ;; unless this is a resend. + ;; We must not do that for a resend + ;; because we would find the original addresses. + ;; For a resend, include the specific addresses. + (or resend-to-addresses '("-t") -;;; ) + ) (if mail-use-dsn (list "-N" (mapconcat 'symbol-name mail-use-dsn ","))) @@ -1249,6 +1312,24 @@ (expand-abbrev) (mail-position-on-field "Reply-To")) +(defun mail-mail-reply-to () + "Move point to end of Mail-Reply-To field. +Create a Mail-Reply-To field if none." + (interactive) + (expand-abbrev) + (or (mail-position-on-field "mail-reply-to" t) + (progn (mail-position-on-field "to") + (insert "\nMail-Reply-To: ")))) + +(defun mail-mail-followup-to () + "Move point to end of Mail-Followup-To field. +Create a Mail-Followup-To field if none." + (interactive) + (expand-abbrev) + (or (mail-position-on-field "mail-followup-to" t) + (progn (mail-position-on-field "to") + (insert "\nMail-Followup-To: ")))) + (defun mail-position-on-field (field &optional soft) (let (end (case-fold-search t))