diff options
| author | Richard M. Stallman | 2005-03-18 00:08:24 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 2005-03-18 00:08:24 +0000 |
| commit | 3ca0be33c2c19ae7265ec3e490e036f64fd64ab0 (patch) | |
| tree | 3ce6977253bd60bce96e6fef7ef786c31567743a | |
| parent | 65363a4e3d837758f2bfbcd4bd37c961c57c6852 (diff) | |
| download | emacs-3ca0be33c2c19ae7265ec3e490e036f64fd64ab0.tar.gz emacs-3ca0be33c2c19ae7265ec3e490e036f64fd64ab0.zip | |
(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.
| -rw-r--r-- | lisp/mail/sendmail.el | 173 |
1 files changed, 127 insertions, 46 deletions
diff --git a/lisp/mail/sendmail.el b/lisp/mail/sendmail.el index 8cf30f295df..af1fca1b1da 100644 --- a/lisp/mail/sendmail.el +++ b/lisp/mail/sendmail.el | |||
| @@ -107,7 +107,7 @@ nil means let mailer mail back a message to report errors." | |||
| 107 | :group 'sendmail) | 107 | :group 'sendmail) |
| 108 | 108 | ||
| 109 | ;;;###autoload | 109 | ;;;###autoload |
| 110 | (defcustom mail-yank-ignored-headers "^via:\\|^mail-from:\\|^origin:\\|^status:\\|^remailed\\|^received:\\|^message-id:\\|^summary-line:\\|^to:\\|^subject:\\|^in-reply-to:\\|^return-path:" "\ | 110 | (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:" "\ |
| 111 | *Delete these headers from old message when it's inserted in a reply." | 111 | *Delete these headers from old message when it's inserted in a reply." |
| 112 | :type 'regexp | 112 | :type 'regexp |
| 113 | :group 'sendmail) | 113 | :group 'sendmail) |
| @@ -213,6 +213,7 @@ text as modified. | |||
| 213 | This is a normal hook, misnamed for historical reasons. | 213 | This is a normal hook, misnamed for historical reasons. |
| 214 | It is semi-obsolete and mail agents should no longer use it.") | 214 | It is semi-obsolete and mail agents should no longer use it.") |
| 215 | 215 | ||
| 216 | ;;;###autoload | ||
| 216 | (defcustom mail-citation-hook nil | 217 | (defcustom mail-citation-hook nil |
| 217 | "*Hook for modifying a citation just inserted in the mail buffer. | 218 | "*Hook for modifying a citation just inserted in the mail buffer. |
| 218 | Each hook function can find the citation between (point) and (mark t), | 219 | Each hook function can find the citation between (point) and (mark t), |
| @@ -363,7 +364,7 @@ actually occur.") | |||
| 363 | (cite-prefix "[:alpha:]") | 364 | (cite-prefix "[:alpha:]") |
| 364 | (cite-suffix (concat cite-prefix "0-9_.@-`'\""))) | 365 | (cite-suffix (concat cite-prefix "0-9_.@-`'\""))) |
| 365 | (list '("^\\(To\\|Newsgroups\\):" . font-lock-function-name-face) | 366 | (list '("^\\(To\\|Newsgroups\\):" . font-lock-function-name-face) |
| 366 | '("^\\(B?CC\\|Reply-to\\):" . font-lock-keyword-face) | 367 | '("^\\(B?CC\\|Reply-to\\|Mail-\\(reply\\|followup\\)-to\\):" . font-lock-keyword-face) |
| 367 | '("^\\(Subject:\\)[ \t]*\\(.+\\)?" | 368 | '("^\\(Subject:\\)[ \t]*\\(.+\\)?" |
| 368 | (1 font-lock-comment-face) (2 font-lock-type-face nil t)) | 369 | (1 font-lock-comment-face) (2 font-lock-type-face nil t)) |
| 369 | ;; Use EVAL to delay in case `mail-header-separator' gets changed. | 370 | ;; Use EVAL to delay in case `mail-header-separator' gets changed. |
| @@ -492,6 +493,8 @@ Here are commands that move to a header field (and create it if there isn't): | |||
| 492 | \\[mail-to] move to To: \\[mail-subject] move to Subject: | 493 | \\[mail-to] move to To: \\[mail-subject] move to Subject: |
| 493 | \\[mail-cc] move to CC: \\[mail-bcc] move to BCC: | 494 | \\[mail-cc] move to CC: \\[mail-bcc] move to BCC: |
| 494 | \\[mail-fcc] move to FCC: \\[mail-reply-to] move to Reply-To: | 495 | \\[mail-fcc] move to FCC: \\[mail-reply-to] move to Reply-To: |
| 496 | \\[mail-mail-reply-to] move to Mail-Reply-To: | ||
| 497 | \\[mail-mail-followup-to] move to Mail-Followup-To: | ||
| 495 | \\[mail-text] mail-text (move to beginning of message text). | 498 | \\[mail-text] mail-text (move to beginning of message text). |
| 496 | \\[mail-signature] mail-signature (insert `mail-signature-file' file). | 499 | \\[mail-signature] mail-signature (insert `mail-signature-file' file). |
| 497 | \\[mail-yank-original] mail-yank-original (insert current message, in Rmail). | 500 | \\[mail-yank-original] mail-yank-original (insert current message, in Rmail). |
| @@ -599,6 +602,7 @@ If within the headers, this makes the new lines into continuation lines." | |||
| 599 | ;; make sure we can fill after each address. | 602 | ;; make sure we can fill after each address. |
| 600 | (if (member fieldname | 603 | (if (member fieldname |
| 601 | '("to" "cc" "bcc" "from" "reply-to" | 604 | '("to" "cc" "bcc" "from" "reply-to" |
| 605 | "mail-reply-to" "mail-followup-to" | ||
| 602 | "resent-to" "resent-cc" "resent-bcc" | 606 | "resent-to" "resent-cc" "resent-bcc" |
| 603 | "resent-from" "resent-reply-to")) | 607 | "resent-from" "resent-reply-to")) |
| 604 | (while (search-forward "," end t) | 608 | (while (search-forward "," end t) |
| @@ -627,6 +631,8 @@ If within the headers, this makes the new lines into continuation lines." | |||
| 627 | (define-key mail-mode-map "\C-c\C-f\C-c" 'mail-cc) | 631 | (define-key mail-mode-map "\C-c\C-f\C-c" 'mail-cc) |
| 628 | (define-key mail-mode-map "\C-c\C-f\C-s" 'mail-subject) | 632 | (define-key mail-mode-map "\C-c\C-f\C-s" 'mail-subject) |
| 629 | (define-key mail-mode-map "\C-c\C-f\C-r" 'mail-reply-to) | 633 | (define-key mail-mode-map "\C-c\C-f\C-r" 'mail-reply-to) |
| 634 | (define-key mail-mode-map "\C-c\C-f\C-a" 'mail-mail-reply-to) ; author | ||
| 635 | (define-key mail-mode-map "\C-c\C-f\C-l" 'mail-mail-followup-to) ; list | ||
| 630 | (define-key mail-mode-map "\C-c\C-t" 'mail-text) | 636 | (define-key mail-mode-map "\C-c\C-t" 'mail-text) |
| 631 | (define-key mail-mode-map "\C-c\C-y" 'mail-yank-original) | 637 | (define-key mail-mode-map "\C-c\C-y" 'mail-yank-original) |
| 632 | (define-key mail-mode-map "\C-c\C-r" 'mail-yank-region) | 638 | (define-key mail-mode-map "\C-c\C-r" 'mail-yank-region) |
| @@ -674,6 +680,12 @@ If within the headers, this makes the new lines into continuation lines." | |||
| 674 | (define-key mail-mode-map [menu-bar headers sent-via] | 680 | (define-key mail-mode-map [menu-bar headers sent-via] |
| 675 | '("Sent Via" . mail-sent-via)) | 681 | '("Sent Via" . mail-sent-via)) |
| 676 | 682 | ||
| 683 | (define-key mail-mode-map [menu-bar headers mail-reply-to] | ||
| 684 | '("Mail Reply To" . mail-mail-reply-to)) | ||
| 685 | |||
| 686 | (define-key mail-mode-map [menu-bar headers mail-followup-to] | ||
| 687 | '("Mail Followup To" . mail-mail-followup-to)) | ||
| 688 | |||
| 677 | (define-key mail-mode-map [menu-bar headers reply-to] | 689 | (define-key mail-mode-map [menu-bar headers reply-to] |
| 678 | '("Reply-To" . mail-reply-to)) | 690 | '("Reply-To" . mail-reply-to)) |
| 679 | 691 | ||
| @@ -745,6 +757,16 @@ Prefix arg means don't delete this window." | |||
| 745 | :options '(flyspell-mode-off) | 757 | :options '(flyspell-mode-off) |
| 746 | :group 'sendmail) | 758 | :group 'sendmail) |
| 747 | 759 | ||
| 760 | ;;;###autoload | ||
| 761 | (defcustom mail-mailing-lists nil "\ | ||
| 762 | *List of mailing list addresses the user is subscribed to. | ||
| 763 | |||
| 764 | The variable is used to trigger insertion of the \"Mail-Followup-To\" | ||
| 765 | header when sending a message to a mailing list." | ||
| 766 | :type '(repeat string) | ||
| 767 | :group 'sendmail) | ||
| 768 | |||
| 769 | |||
| 748 | (defun mail-send () | 770 | (defun mail-send () |
| 749 | "Send the message in the current buffer. | 771 | "Send the message in the current buffer. |
| 750 | If `mail-interactive' is non-nil, wait for success indication | 772 | If `mail-interactive' is non-nil, wait for success indication |
| @@ -757,7 +779,45 @@ the user from the mailer." | |||
| 757 | (or (buffer-modified-p) | 779 | (or (buffer-modified-p) |
| 758 | (y-or-n-p "Message already sent; resend? "))) | 780 | (y-or-n-p "Message already sent; resend? "))) |
| 759 | (let ((inhibit-read-only t) | 781 | (let ((inhibit-read-only t) |
| 760 | (opoint (point))) | 782 | (opoint (point)) |
| 783 | (ml (when mail-mailing-lists | ||
| 784 | ;; The surrounding regexp assumes the use of | ||
| 785 | ;; `mail-strip-quoted-names' on addresses before matching | ||
| 786 | ;; Cannot deal with full RFC 822 freedom, but that is | ||
| 787 | ;; unlikely to be problematic. | ||
| 788 | (concat "\\(?:[[:space:];,]\\|\\`\\)" | ||
| 789 | (regexp-opt mail-mailing-lists t) | ||
| 790 | "\\(?:[[:space:];,]\\|\\'\\)")))) | ||
| 791 | ;; If there are mailing lists defined | ||
| 792 | (when ml | ||
| 793 | (save-excursion | ||
| 794 | (let* ((to (mail-fetch-field "to" nil t)) | ||
| 795 | (cc (mail-fetch-field "cc" nil t)) | ||
| 796 | (new-header-values ; To: and Cc: | ||
| 797 | (mail-strip-quoted-names | ||
| 798 | (concat to (when cc (concat ", " cc)))))) | ||
| 799 | ;; If message goes to known mailing list ... | ||
| 800 | (when (string-match ml new-header-values) | ||
| 801 | ;; Add Mail-Followup-To if none yet | ||
| 802 | (unless (mail-fetch-field "mail-followup-to") | ||
| 803 | (goto-char (mail-header-end)) | ||
| 804 | (insert "Mail-Followup-To: " | ||
| 805 | (let ((l)) | ||
| 806 | (mapc | ||
| 807 | ;; remove duplicates | ||
| 808 | '(lambda (e) | ||
| 809 | (unless (member e l) | ||
| 810 | (push e l))) | ||
| 811 | (split-string new-header-values ", +" t)) | ||
| 812 | (mapconcat 'identity l ", ")) | ||
| 813 | "\n")) | ||
| 814 | ;; Add Mail-Reply-To if none yet | ||
| 815 | (unless (mail-fetch-field "mail-reply-to") | ||
| 816 | (goto-char (mail-header-end)) | ||
| 817 | (insert "Mail-Reply-To: " | ||
| 818 | (or (mail-fetch-field "reply-to") | ||
| 819 | user-mail-address) | ||
| 820 | "\n")))))) | ||
| 761 | (unless (memq mail-send-nonascii '(t mime)) | 821 | (unless (memq mail-send-nonascii '(t mime)) |
| 762 | (goto-char (point-min)) | 822 | (goto-char (point-min)) |
| 763 | (skip-chars-forward "\0-\177") | 823 | (skip-chars-forward "\0-\177") |
| @@ -833,7 +893,7 @@ external program defined by `sendmail-program'." | |||
| 833 | (multibyte enable-multibyte-characters) | 893 | (multibyte enable-multibyte-characters) |
| 834 | (case-fold-search nil) | 894 | (case-fold-search nil) |
| 835 | (selected-coding (select-message-coding-system)) | 895 | (selected-coding (select-message-coding-system)) |
| 836 | ;;; resend-to-addresses | 896 | resend-to-addresses |
| 837 | delimline | 897 | delimline |
| 838 | fcc-was-found | 898 | fcc-was-found |
| 839 | (mailbuf (current-buffer)) | 899 | (mailbuf (current-buffer)) |
| @@ -869,39 +929,42 @@ external program defined by `sendmail-program'." | |||
| 869 | (< (point) delimline)) | 929 | (< (point) delimline)) |
| 870 | (replace-match "\n")) | 930 | (replace-match "\n")) |
| 871 | (goto-char (point-min)) | 931 | (goto-char (point-min)) |
| 932 | ;; Look for Resent- headers. They require sending | ||
| 933 | ;; the message specially. | ||
| 872 | (let ((case-fold-search t)) | 934 | (let ((case-fold-search t)) |
| 873 | ;;; (goto-char (point-min)) | 935 | (goto-char (point-min)) |
| 874 | ;;; (while (re-search-forward "^Resent-\\(to\\|cc\\|bcc\\):" delimline t) | 936 | (while (re-search-forward "^Resent-\\(to\\|cc\\|bcc\\):" delimline t) |
| 875 | ;;; (setq resend-to-addresses | 937 | ;; Put a list of such addresses in resend-to-addresses. |
| 876 | ;;; (save-restriction | 938 | (setq resend-to-addresses |
| 877 | ;;; (narrow-to-region (point) | 939 | (save-restriction |
| 878 | ;;; (save-excursion | 940 | (narrow-to-region (point) |
| 879 | ;;; (forward-line 1) | 941 | (save-excursion |
| 880 | ;;; (while (looking-at "^[ \t]") | 942 | (forward-line 1) |
| 881 | ;;; (forward-line 1)) | 943 | (while (looking-at "^[ \t]") |
| 882 | ;;; (point))) | 944 | (forward-line 1)) |
| 883 | ;;; (append (mail-parse-comma-list) | 945 | (point))) |
| 884 | ;;; resend-to-addresses))) | 946 | (append (mail-parse-comma-list) |
| 885 | ;;; ;; Delete Resent-BCC ourselves | 947 | resend-to-addresses))) |
| 886 | ;;; (if (save-excursion (beginning-of-line) | 948 | ;; Delete Resent-BCC ourselves |
| 887 | ;;; (looking-at "resent-bcc")) | 949 | (if (save-excursion (beginning-of-line) |
| 888 | ;;; (delete-region (save-excursion (beginning-of-line) (point)) | 950 | (looking-at "resent-bcc")) |
| 889 | ;;; (save-excursion (end-of-line) (1+ (point)))))) | 951 | (delete-region (save-excursion (beginning-of-line) (point)) |
| 890 | ;;; Apparently this causes a duplicate Sender. | 952 | (save-excursion (end-of-line) (1+ (point)))))) |
| 891 | ;;; ;; If the From is different than current user, insert Sender. | 953 | ;;; Apparently this causes a duplicate Sender. |
| 892 | ;;; (goto-char (point-min)) | 954 | ;;; ;; If the From is different than current user, insert Sender. |
| 893 | ;;; (and (re-search-forward "^From:" delimline t) | 955 | ;;; (goto-char (point-min)) |
| 894 | ;;; (progn | 956 | ;;; (and (re-search-forward "^From:" delimline t) |
| 895 | ;;; (require 'mail-utils) | 957 | ;;; (progn |
| 896 | ;;; (not (string-equal | 958 | ;;; (require 'mail-utils) |
| 897 | ;;; (mail-strip-quoted-names | 959 | ;;; (not (string-equal |
| 898 | ;;; (save-restriction | 960 | ;;; (mail-strip-quoted-names |
| 899 | ;;; (narrow-to-region (point-min) delimline) | 961 | ;;; (save-restriction |
| 900 | ;;; (mail-fetch-field "From"))) | 962 | ;;; (narrow-to-region (point-min) delimline) |
| 901 | ;;; (user-login-name)))) | 963 | ;;; (mail-fetch-field "From"))) |
| 902 | ;;; (progn | 964 | ;;; (user-login-name)))) |
| 903 | ;;; (forward-line 1) | 965 | ;;; (progn |
| 904 | ;;; (insert "Sender: " (user-login-name) "\n"))) | 966 | ;;; (forward-line 1) |
| 967 | ;;; (insert "Sender: " (user-login-name) "\n"))) | ||
| 905 | ;; Don't send out a blank subject line | 968 | ;; Don't send out a blank subject line |
| 906 | (goto-char (point-min)) | 969 | (goto-char (point-min)) |
| 907 | (if (re-search-forward "^Subject:\\([ \t]*\n\\)+\\b" delimline t) | 970 | (if (re-search-forward "^Subject:\\([ \t]*\n\\)+\\b" delimline t) |
| @@ -1000,9 +1063,9 @@ external program defined by `sendmail-program'." | |||
| 1000 | (erase-buffer)))) | 1063 | (erase-buffer)))) |
| 1001 | (goto-char (point-min)) | 1064 | (goto-char (point-min)) |
| 1002 | (if (let ((case-fold-search t)) | 1065 | (if (let ((case-fold-search t)) |
| 1003 | (re-search-forward "^To:\\|^cc:\\|^bcc:\\|^resent-to:\ | 1066 | (or resend-to-addresses |
| 1004 | \\|^resent-cc:\\|^resent-bcc:" | 1067 | (re-search-forward "^To:\\|^cc:\\|^bcc:" |
| 1005 | delimline t)) | 1068 | delimline t))) |
| 1006 | (let* ((default-directory "/") | 1069 | (let* ((default-directory "/") |
| 1007 | (coding-system-for-write selected-coding) | 1070 | (coding-system-for-write selected-coding) |
| 1008 | (args | 1071 | (args |
| @@ -1023,14 +1086,14 @@ external program defined by `sendmail-program'." | |||
| 1023 | ;; These mean "report errors by mail" | 1086 | ;; These mean "report errors by mail" |
| 1024 | ;; and "deliver in background". | 1087 | ;; and "deliver in background". |
| 1025 | '("-oem" "-odb")) | 1088 | '("-oem" "-odb")) |
| 1026 | ;;; ;; Get the addresses from the message | 1089 | ;; Get the addresses from the message |
| 1027 | ;;; ;; unless this is a resend. | 1090 | ;; unless this is a resend. |
| 1028 | ;;; ;; We must not do that for a resend | 1091 | ;; We must not do that for a resend |
| 1029 | ;;; ;; because we would find the original addresses. | 1092 | ;; because we would find the original addresses. |
| 1030 | ;;; ;; For a resend, include the specific addresses. | 1093 | ;; For a resend, include the specific addresses. |
| 1031 | ;;; (or resend-to-addresses | 1094 | (or resend-to-addresses |
| 1032 | '("-t") | 1095 | '("-t") |
| 1033 | ;;; ) | 1096 | ) |
| 1034 | (if mail-use-dsn | 1097 | (if mail-use-dsn |
| 1035 | (list "-N" (mapconcat 'symbol-name | 1098 | (list "-N" (mapconcat 'symbol-name |
| 1036 | mail-use-dsn ","))) | 1099 | mail-use-dsn ","))) |
| @@ -1249,6 +1312,24 @@ external program defined by `sendmail-program'." | |||
| 1249 | (expand-abbrev) | 1312 | (expand-abbrev) |
| 1250 | (mail-position-on-field "Reply-To")) | 1313 | (mail-position-on-field "Reply-To")) |
| 1251 | 1314 | ||
| 1315 | (defun mail-mail-reply-to () | ||
| 1316 | "Move point to end of Mail-Reply-To field. | ||
| 1317 | Create a Mail-Reply-To field if none." | ||
| 1318 | (interactive) | ||
| 1319 | (expand-abbrev) | ||
| 1320 | (or (mail-position-on-field "mail-reply-to" t) | ||
| 1321 | (progn (mail-position-on-field "to") | ||
| 1322 | (insert "\nMail-Reply-To: ")))) | ||
| 1323 | |||
| 1324 | (defun mail-mail-followup-to () | ||
| 1325 | "Move point to end of Mail-Followup-To field. | ||
| 1326 | Create a Mail-Followup-To field if none." | ||
| 1327 | (interactive) | ||
| 1328 | (expand-abbrev) | ||
| 1329 | (or (mail-position-on-field "mail-followup-to" t) | ||
| 1330 | (progn (mail-position-on-field "to") | ||
| 1331 | (insert "\nMail-Followup-To: ")))) | ||
| 1332 | |||
| 1252 | (defun mail-position-on-field (field &optional soft) | 1333 | (defun mail-position-on-field (field &optional soft) |
| 1253 | (let (end | 1334 | (let (end |
| 1254 | (case-fold-search t)) | 1335 | (case-fold-search t)) |