Mercurial > hg > xemacs-beta
comparison lisp/gnus/message.el @ 16:0293115a14e9 r19-15b91
Import from CVS: tag r19-15b91
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:49:20 +0200 |
parents | ac2d302a0011 |
children | d95e72db5c07 |
comparison
equal
deleted
inserted
replaced
15:ad457d5f7d04 | 16:0293115a14e9 |
---|---|
1 ;;; message.el --- composing mail and news messages | 1 ;;; message.el --- composing mail and news messages |
2 ;; Copyright (C) 1996 Free Software Foundation, Inc. | 2 ;; Copyright (C) 1996,97 Free Software Foundation, Inc. |
3 | 3 |
4 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no> | 4 ;; Author: Lars Magne Ingebrigtsen <larsi@ifi.uio.no> |
5 ;; Keywords: mail, news | 5 ;; Keywords: mail, news |
6 | 6 |
7 ;; This file is part of GNU Emacs. | 7 ;; This file is part of GNU Emacs. |
34 (require 'mailheader) | 34 (require 'mailheader) |
35 (require 'rmail) | 35 (require 'rmail) |
36 (require 'nnheader) | 36 (require 'nnheader) |
37 (require 'timezone) | 37 (require 'timezone) |
38 (require 'easymenu) | 38 (require 'easymenu) |
39 (require 'custom) | |
39 (if (string-match "XEmacs\\|Lucid" emacs-version) | 40 (if (string-match "XEmacs\\|Lucid" emacs-version) |
40 (require 'mail-abbrevs) | 41 (require 'mail-abbrevs) |
41 (require 'mailabbrev)) | 42 (require 'mailabbrev)) |
42 | 43 |
43 (defvar message-directory "~/Mail/" | 44 (defgroup message '((user-mail-address custom-variable) |
44 "*Directory from which all other mail file variables are derived.") | 45 (user-full-name custom-variable)) |
45 | 46 "Mail and news message composing." |
46 (defvar message-max-buffers 10 | 47 :link '(custom-manual "(message)Top") |
47 "*How many buffers to keep before starting to kill them off.") | 48 :group 'emacs) |
48 | 49 |
49 (defvar message-send-rename-function nil | 50 (put 'user-mail-address 'custom-type 'string) |
50 "Function called to rename the buffer after sending it.") | 51 (put 'user-full-name 'custom-type 'string) |
52 | |
53 (defgroup message-various nil | |
54 "Various Message Variables" | |
55 :link '(custom-manual "(message)Various Message Variables") | |
56 :group 'message) | |
57 | |
58 (defgroup message-buffers nil | |
59 "Message Buffers" | |
60 :link '(custom-manual "(message)Message Buffers") | |
61 :group 'message) | |
62 | |
63 (defgroup message-sending nil | |
64 "Message Sending" | |
65 :link '(custom-manual "(message)Sending Variables") | |
66 :group 'message) | |
67 | |
68 (defgroup message-interface nil | |
69 "Message Interface" | |
70 :link '(custom-manual "(message)Interface") | |
71 :group 'message) | |
72 | |
73 (defgroup message-forwarding nil | |
74 "Message Forwarding" | |
75 :link '(custom-manual "(message)Forwarding") | |
76 :group 'message-interface) | |
77 | |
78 (defgroup message-insertion nil | |
79 "Message Insertion" | |
80 :link '(custom-manual "(message)Insertion") | |
81 :group 'message) | |
82 | |
83 (defgroup message-headers nil | |
84 "Message Headers" | |
85 :link '(custom-manual "(message)Message Headers") | |
86 :group 'message) | |
87 | |
88 (defgroup message-news nil | |
89 "Composing News Messages" | |
90 :group 'message) | |
91 | |
92 (defgroup message-mail nil | |
93 "Composing Mail Messages" | |
94 :group 'message) | |
95 | |
96 (defcustom message-directory "~/Mail/" | |
97 "*Directory from which all other mail file variables are derived." | |
98 :group 'message-various | |
99 :type 'directory) | |
100 | |
101 (defcustom message-max-buffers 10 | |
102 "*How many buffers to keep before starting to kill them off." | |
103 :group 'message-buffers | |
104 :type 'integer) | |
105 | |
106 (defcustom message-send-rename-function nil | |
107 "Function called to rename the buffer after sending it." | |
108 :group 'message-buffers | |
109 :type 'function) | |
51 | 110 |
52 ;;;###autoload | 111 ;;;###autoload |
53 (defvar message-fcc-handler-function 'rmail-output | 112 (defcustom message-fcc-handler-function 'message-output |
54 "*A function called to save outgoing articles. | 113 "*A function called to save outgoing articles. |
55 This function will be called with the name of the file to store the | 114 This function will be called with the name of the file to store the |
56 article in. The default function is `rmail-output' which saves in Unix | 115 article in. The default function is `rmail-output' which saves in Unix |
57 mailbox format.") | 116 mailbox format." |
117 :type '(radio (function-item rmail-output) | |
118 (function :tag "Other")) | |
119 :group 'message-sending) | |
120 | |
121 (defcustom message-courtesy-message | |
122 "The following message is a courtesy copy of an article\nthat has been posted to %s as well.\n\n" | |
123 "*This is inserted at the start of a mailed copy of a posted message. | |
124 If the string contains the format spec \"%s\", the Newsgroups | |
125 the article has been posted to will be inserted there. | |
126 If this variable is nil, no such courtesy message will be added." | |
127 :group 'message-sending | |
128 :type 'string) | |
129 | |
130 (defcustom message-ignored-bounced-headers "^\\(Received\\|Return-Path\\):" | |
131 "*Regexp that matches headers to be removed in resent bounced mail." | |
132 :group 'message-interface | |
133 :type 'regexp) | |
58 | 134 |
59 ;;;###autoload | 135 ;;;###autoload |
60 (defvar message-courtesy-message | 136 (defcustom message-from-style 'default |
61 "The following message is a courtesy copy of an article\nthat has been posted as well.\n\n" | |
62 "*This is inserted at the start of a mailed copy of a posted message. | |
63 If this variable is nil, no such courtesy message will be added.") | |
64 | |
65 ;;;###autoload | |
66 (defvar message-ignored-bounced-headers "^\\(Received\\|Return-Path\\):" | |
67 "*Regexp that matches headers to be removed in resent bounced mail.") | |
68 | |
69 ;;;###autoload | |
70 (defvar message-from-style 'default | |
71 "*Specifies how \"From\" headers look. | 137 "*Specifies how \"From\" headers look. |
72 | 138 |
73 If `nil', they contain just the return address like: | 139 If `nil', they contain just the return address like: |
74 king@grassland.com | 140 king@grassland.com |
75 If `parens', they look like: | 141 If `parens', they look like: |
76 king@grassland.com (Elvis Parsley) | 142 king@grassland.com (Elvis Parsley) |
77 If `angles', they look like: | 143 If `angles', they look like: |
78 Elvis Parsley <king@grassland.com> | 144 Elvis Parsley <king@grassland.com> |
79 | 145 |
80 Otherwise, most addresses look like `angles', but they look like | 146 Otherwise, most addresses look like `angles', but they look like |
81 `parens' if `angles' would need quoting and `parens' would not.") | 147 `parens' if `angles' would need quoting and `parens' would not." |
82 | 148 :type '(choice (const :tag "simple" nil) |
83 ;;;###autoload | 149 (const parens) |
84 (defvar message-syntax-checks nil | 150 (const angles) |
151 (const default)) | |
152 :group 'message-headers) | |
153 | |
154 (defcustom message-syntax-checks nil | |
155 ;; Guess this one shouldn't be easy to customize... | |
85 "Controls what syntax checks should not be performed on outgoing posts. | 156 "Controls what syntax checks should not be performed on outgoing posts. |
86 To disable checking of long signatures, for instance, add | 157 To disable checking of long signatures, for instance, add |
87 `(signature . disabled)' to this list. | 158 `(signature . disabled)' to this list. |
88 | 159 |
89 Don't touch this variable unless you really know what you're doing. | 160 Don't touch this variable unless you really know what you're doing. |
90 | 161 |
91 Checks include subject-cmsg multiple-headers sendsys message-id from | 162 Checks include subject-cmsg multiple-headers sendsys message-id from |
92 long-lines control-chars size new-text redirected-followup signature | 163 long-lines control-chars size new-text redirected-followup signature |
93 approved sender empty empty-headers message-id from subject.") | 164 approved sender empty empty-headers message-id from subject |
94 | 165 shorten-followup-to existing-newsgroups." |
95 ;;;###autoload | 166 :group 'message-news) |
96 (defvar message-required-news-headers | 167 |
168 (defcustom message-required-news-headers | |
97 '(From Newsgroups Subject Date Message-ID | 169 '(From Newsgroups Subject Date Message-ID |
98 (optional . Organization) Lines | 170 (optional . Organization) Lines |
99 (optional . X-Newsreader)) | 171 (optional . X-Newsreader)) |
100 "*Headers to be generated or prompted for when posting an article. | 172 "Headers to be generated or prompted for when posting an article. |
101 RFC977 and RFC1036 require From, Date, Newsgroups, Subject, | 173 RFC977 and RFC1036 require From, Date, Newsgroups, Subject, |
102 Message-ID. Organization, Lines, In-Reply-To, Expires, and | 174 Message-ID. Organization, Lines, In-Reply-To, Expires, and |
103 X-Newsreader are optional. If don't you want message to insert some | 175 X-Newsreader are optional. If don't you want message to insert some |
104 header, remove it from this list.") | 176 header, remove it from this list." |
105 | 177 :group 'message-news |
106 ;;;###autoload | 178 :group 'message-headers |
107 (defvar message-required-mail-headers | 179 :type '(repeat sexp)) |
180 | |
181 (defcustom message-required-mail-headers | |
108 '(From Subject Date (optional . In-Reply-To) Message-ID Lines | 182 '(From Subject Date (optional . In-Reply-To) Message-ID Lines |
109 (optional . X-Mailer)) | 183 (optional . X-Mailer)) |
110 "*Headers to be generated or prompted for when mailing a message. | 184 "Headers to be generated or prompted for when mailing a message. |
111 RFC822 required that From, Date, To, Subject and Message-ID be | 185 RFC822 required that From, Date, To, Subject and Message-ID be |
112 included. Organization, Lines and X-Mailer are optional.") | 186 included. Organization, Lines and X-Mailer are optional." |
113 | 187 :group 'message-mail |
114 ;;;###autoload | 188 :group 'message-headers |
115 (defvar message-deletable-headers '(Message-ID Date) | 189 :type '(repeat sexp)) |
116 "*Headers to be deleted if they already exist and were generated by message previously.") | 190 |
117 | 191 (defcustom message-deletable-headers '(Message-ID Date Lines) |
118 ;;;###autoload | 192 "Headers to be deleted if they already exist and were generated by message previously." |
119 (defvar message-ignored-news-headers | 193 :group 'message-headers |
120 "^NNTP-Posting-Host:\\|^Xref:\\|^Bcc:\\|^Gcc:\\|^Fcc:" | 194 :type 'sexp) |
121 "*Regexp of headers to be removed unconditionally before posting.") | 195 |
122 | 196 (defcustom message-ignored-news-headers |
123 ;;;###autoload | 197 "^NNTP-Posting-Host:\\|^Xref:\\|^Bcc:\\|^Gcc:\\|^Fcc:\\|^Resent-Fcc:" |
124 (defvar message-ignored-mail-headers "^Gcc:\\|^Fcc:" | 198 "*Regexp of headers to be removed unconditionally before posting." |
125 "*Regexp of headers to be removed unconditionally before mailing.") | 199 :group 'message-news |
126 | 200 :group 'message-headers |
127 ;;;###autoload | 201 :type 'regexp) |
128 (defvar message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|Return-Path:\\|^Supersedes:" | 202 |
203 (defcustom message-ignored-mail-headers "^Gcc:\\|^Fcc:\\|^Resent-Fcc:" | |
204 "*Regexp of headers to be removed unconditionally before mailing." | |
205 :group 'message-mail | |
206 :group 'message-headers | |
207 :type 'regexp) | |
208 | |
209 (defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|Return-Path:\\|^Supersedes:" | |
129 "*Header lines matching this regexp will be deleted before posting. | 210 "*Header lines matching this regexp will be deleted before posting. |
130 It's best to delete old Path and Date headers before posting to avoid | 211 It's best to delete old Path and Date headers before posting to avoid |
131 any confusion.") | 212 any confusion." |
213 :group 'message-interface | |
214 :type 'regexp) | |
132 | 215 |
133 ;;;###autoload | 216 ;;;###autoload |
134 (defvar message-signature-separator "^-- *$" | 217 (defcustom message-signature-separator "^-- *$" |
135 "Regexp matching the signature separator.") | 218 "Regexp matching the signature separator." |
136 | 219 :type 'regexp |
137 ;;;###autoload | 220 :group 'message-various) |
138 (defvar message-interactive nil | 221 |
222 (defcustom message-elide-elipsis "\n[...]\n\n" | |
223 "*The string which is inserted for elided text.") | |
224 | |
225 (defcustom message-interactive nil | |
139 "Non-nil means when sending a message wait for and display errors. | 226 "Non-nil means when sending a message wait for and display errors. |
140 nil means let mailer mail back a message to report errors.") | 227 nil means let mailer mail back a message to report errors." |
141 | 228 :group 'message-sending |
142 ;;;###autoload | 229 :group 'message-mail |
143 (defvar message-generate-new-buffers t | 230 :type 'boolean) |
231 | |
232 (defcustom message-generate-new-buffers t | |
144 "*Non-nil means that a new message buffer will be created whenever `mail-setup' is called. | 233 "*Non-nil means that a new message buffer will be created whenever `mail-setup' is called. |
145 If this is a function, call that function with three parameters: The type, | 234 If this is a function, call that function with three parameters: The type, |
146 the to address and the group name. (Any of these may be nil.) The function | 235 the to address and the group name. (Any of these may be nil.) The function |
147 should return the new buffer name.") | 236 should return the new buffer name." |
148 | 237 :group 'message-buffers |
149 ;;;###autoload | 238 :type '(choice (const :tag "off" nil) |
150 (defvar message-kill-buffer-on-exit nil | 239 (const :tag "on" t) |
151 "*Non-nil means that the message buffer will be killed after sending a message.") | 240 (function fun))) |
241 | |
242 (defcustom message-kill-buffer-on-exit nil | |
243 "*Non-nil means that the message buffer will be killed after sending a message." | |
244 :group 'message-buffers | |
245 :type 'boolean) | |
152 | 246 |
153 (defvar gnus-local-organization) | 247 (defvar gnus-local-organization) |
154 (defvar message-user-organization | 248 (defcustom message-user-organization |
155 (or (and (boundp 'gnus-local-organization) | 249 (or (and (boundp 'gnus-local-organization) |
156 gnus-local-organization) | 250 gnus-local-organization) |
157 (getenv "ORGANIZATION") | 251 (getenv "ORGANIZATION") |
158 t) | 252 t) |
159 "*String to be used as an Organization header. | 253 "*String to be used as an Organization header. |
160 If t, use `message-user-organization-file'.") | 254 If t, use `message-user-organization-file'." |
255 :group 'message-headers | |
256 :type '(choice string | |
257 (const :tag "consult file" t))) | |
161 | 258 |
162 ;;;###autoload | 259 ;;;###autoload |
163 (defvar message-user-organization-file "/usr/lib/news/organization" | 260 (defcustom message-user-organization-file "/usr/lib/news/organization" |
164 "*Local news organization file.") | 261 "*Local news organization file." |
165 | 262 :type 'file |
166 (defvar message-autosave-directory "~/" | 263 :group 'message-headers) |
264 | |
265 (defcustom message-autosave-directory "~/" | |
167 ; (concat (file-name-as-directory message-directory) "drafts/") | 266 ; (concat (file-name-as-directory message-directory) "drafts/") |
168 "*Directory where message autosaves buffers. | 267 "*Directory where message autosaves buffers. |
169 If nil, message won't autosave.") | 268 If nil, message won't autosave." |
170 | 269 :group 'message-buffers |
171 (defvar message-forward-start-separator | 270 :type 'directory) |
271 | |
272 (defcustom message-forward-start-separator | |
172 "------- Start of forwarded message -------\n" | 273 "------- Start of forwarded message -------\n" |
173 "*Delimiter inserted before forwarded messages.") | 274 "*Delimiter inserted before forwarded messages." |
174 | 275 :group 'message-forwarding |
175 (defvar message-forward-end-separator | 276 :type 'string) |
277 | |
278 (defcustom message-forward-end-separator | |
176 "------- End of forwarded message -------\n" | 279 "------- End of forwarded message -------\n" |
177 "*Delimiter inserted after forwarded messages.") | 280 "*Delimiter inserted after forwarded messages." |
178 | 281 :group 'message-forwarding |
179 ;;;###autoload | 282 :type 'string) |
180 (defvar message-signature-before-forwarded-message t | 283 |
181 "*If non-nil, put the signature before any included forwarded message.") | 284 (defcustom message-signature-before-forwarded-message t |
182 | 285 "*If non-nil, put the signature before any included forwarded message." |
183 ;;;###autoload | 286 :group 'message-forwarding |
184 (defvar message-included-forward-headers | 287 :type 'boolean) |
288 | |
289 (defcustom message-included-forward-headers | |
185 "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-\\|^Message-ID:\\|^References:" | 290 "^From:\\|^Newsgroups:\\|^Subject:\\|^Date:\\|^Followup-To:\\|^Reply-To:\\|^Organization:\\|^Summary:\\|^Keywords:\\|^To:\\|^Cc:\\|^Posted-To:\\|^Mail-Copies-To:\\|^Apparently-To:\\|^Gnus-Warning:\\|^Resent-\\|^Message-ID:\\|^References:" |
186 "*Regexp matching headers to be included in forwarded messages.") | 291 "*Regexp matching headers to be included in forwarded messages." |
187 | 292 :group 'message-forwarding |
188 ;;;###autoload | 293 :type 'regexp) |
189 (defvar message-ignored-resent-headers "^Return-receipt" | 294 |
190 "*All headers that match this regexp will be deleted when resending a message.") | 295 (defcustom message-ignored-resent-headers "^Return-receipt" |
191 | 296 "*All headers that match this regexp will be deleted when resending a message." |
192 ;;;###autoload | 297 :group 'message-interface |
193 (defvar message-ignored-cited-headers "." | 298 :type 'regexp) |
194 "Delete these headers from the messages you yank.") | 299 |
300 (defcustom message-ignored-cited-headers "." | |
301 "*Delete these headers from the messages you yank." | |
302 :group 'message-insertion | |
303 :type 'regexp) | |
304 | |
305 (defcustom message-cancel-message "I am canceling my own article." | |
306 "Message to be inserted in the cancel message." | |
307 :group 'message-interface | |
308 :type 'string) | |
195 | 309 |
196 ;; Useful to set in site-init.el | 310 ;; Useful to set in site-init.el |
197 ;;;###autoload | 311 ;;;###autoload |
198 (defvar message-send-mail-function 'message-send-mail-with-sendmail | 312 (defcustom message-send-mail-function 'message-send-mail-with-sendmail |
199 "Function to call to send the current buffer as mail. | 313 "Function to call to send the current buffer as mail. |
200 The headers should be delimited by a line whose contents match the | 314 The headers should be delimited by a line whose contents match the |
201 variable `mail-header-separator'. | 315 variable `mail-header-separator'. |
202 | 316 |
203 Legal values include `message-send-mail-with-mh' and | 317 Legal values include `message-send-mail-with-sendmail' (the default), |
204 `message-send-mail-with-sendmail', which is the default.") | 318 `message-send-mail-with-mh' and `message-send-mail-with-qmail'." |
205 | 319 :type '(radio (function-item message-send-mail-with-sendmail) |
206 ;;;###autoload | 320 (function-item message-send-mail-with-mh) |
207 (defvar message-send-news-function 'message-send-news | 321 (function-item message-send-mail-with-qmail) |
322 (function :tag "Other")) | |
323 :group 'message-sending | |
324 :group 'message-mail) | |
325 | |
326 (defcustom message-send-news-function 'message-send-news | |
208 "Function to call to send the current buffer as news. | 327 "Function to call to send the current buffer as news. |
209 The headers should be delimited by a line whose contents match the | 328 The headers should be delimited by a line whose contents match the |
210 variable `mail-header-separator'.") | 329 variable `mail-header-separator'." |
211 | 330 :group 'message-sending |
212 ;;;###autoload | 331 :group 'message-news |
213 (defvar message-reply-to-function nil | 332 :type 'function) |
333 | |
334 (defcustom message-reply-to-function nil | |
214 "Function that should return a list of headers. | 335 "Function that should return a list of headers. |
215 This function should pick out addresses from the To, Cc, and From headers | 336 This function should pick out addresses from the To, Cc, and From headers |
216 and respond with new To and Cc headers.") | 337 and respond with new To and Cc headers." |
217 | 338 :group 'message-interface |
218 ;;;###autoload | 339 :type 'function) |
219 (defvar message-wide-reply-to-function nil | 340 |
341 (defcustom message-wide-reply-to-function nil | |
220 "Function that should return a list of headers. | 342 "Function that should return a list of headers. |
221 This function should pick out addresses from the To, Cc, and From headers | 343 This function should pick out addresses from the To, Cc, and From headers |
222 and respond with new To and Cc headers.") | 344 and respond with new To and Cc headers." |
223 | 345 :group 'message-interface |
224 ;;;###autoload | 346 :type 'function) |
225 (defvar message-followup-to-function nil | 347 |
348 (defcustom message-followup-to-function nil | |
226 "Function that should return a list of headers. | 349 "Function that should return a list of headers. |
227 This function should pick out addresses from the To, Cc, and From headers | 350 This function should pick out addresses from the To, Cc, and From headers |
228 and respond with new To and Cc headers.") | 351 and respond with new To and Cc headers." |
229 | 352 :group 'message-interface |
230 ;;;###autoload | 353 :type 'function) |
231 (defvar message-use-followup-to 'ask | 354 |
355 (defcustom message-use-followup-to 'ask | |
232 "*Specifies what to do with Followup-To header. | 356 "*Specifies what to do with Followup-To header. |
233 If nil, ignore the header. If it is t, use its value, but query before | 357 If nil, always ignore the header. If it is t, use its value, but |
234 using the \"poster\" value. If it is the symbol `ask', query the user | 358 query before using the \"poster\" value. If it is the symbol `ask', |
235 whether to ignore the \"poster\" value. If it is the symbol `use', | 359 always query the user whether to use the value. If it is the symbol |
236 always use the value.") | 360 `use', always use the value." |
361 :group 'message-interface | |
362 :type '(choice (const :tag "ignore" nil) | |
363 (const use) | |
364 (const ask))) | |
365 | |
366 ;; stuff relating to broken sendmail in MMDF | |
367 (defcustom message-sendmail-f-is-evil nil | |
368 "*Non-nil means that \"-f username\" should not be added to the sendmail | |
369 command line, because it is even more evil than leaving it out." | |
370 :group 'message-sending | |
371 :type 'boolean) | |
372 | |
373 ;; qmail-related stuff | |
374 (defcustom message-qmail-inject-program "/var/qmail/bin/qmail-inject" | |
375 "Location of the qmail-inject program." | |
376 :group 'message-sending | |
377 :type 'file) | |
378 | |
379 (defcustom message-qmail-inject-args nil | |
380 "Arguments passed to qmail-inject programs. | |
381 This should be a list of strings, one string for each argument. | |
382 | |
383 For e.g., if you wish to set the envelope sender address so that bounces | |
384 go to the right place or to deal with listserv's usage of that address, you | |
385 might set this variable to '(\"-f\" \"you@some.where\")." | |
386 :group 'message-sending | |
387 :type '(repeat string)) | |
237 | 388 |
238 (defvar gnus-post-method) | 389 (defvar gnus-post-method) |
239 (defvar gnus-select-method) | 390 (defvar gnus-select-method) |
240 ;;;###autoload | 391 (defcustom message-post-method |
241 (defvar message-post-method | |
242 (cond ((and (boundp 'gnus-post-method) | 392 (cond ((and (boundp 'gnus-post-method) |
243 gnus-post-method) | 393 gnus-post-method) |
244 gnus-post-method) | 394 gnus-post-method) |
245 ((boundp 'gnus-select-method) | 395 ((boundp 'gnus-select-method) |
246 gnus-select-method) | 396 gnus-select-method) |
247 (t '(nnspool ""))) | 397 (t '(nnspool ""))) |
248 "Method used to post news.") | 398 "Method used to post news." |
249 | 399 :group 'message-news |
250 ;;;###autoload | 400 :group 'mesage-sending |
251 (defvar message-generate-headers-first nil | 401 ;; This should be the `gnus-select-method' widget, but that might |
252 "*If non-nil, generate all possible headers before composing.") | 402 ;; create a dependence to `gnus.el'. |
253 | 403 :type 'sexp) |
254 (defvar message-setup-hook nil | 404 |
405 (defcustom message-generate-headers-first nil | |
406 "*If non-nil, generate all possible headers before composing." | |
407 :group 'message-headers | |
408 :type 'boolean) | |
409 | |
410 (defcustom message-setup-hook nil | |
255 "Normal hook, run each time a new outgoing message is initialized. | 411 "Normal hook, run each time a new outgoing message is initialized. |
256 The function `message-setup' runs this hook.") | 412 The function `message-setup' runs this hook." |
257 | 413 :group 'message-various |
258 (defvar message-signature-setup-hook nil | 414 :type 'hook) |
415 | |
416 (defcustom message-signature-setup-hook nil | |
259 "Normal hook, run each time a new outgoing message is initialized. | 417 "Normal hook, run each time a new outgoing message is initialized. |
260 It is run after the headers have been inserted and before | 418 It is run after the headers have been inserted and before |
261 the signature is inserted.") | 419 the signature is inserted." |
262 | 420 :group 'message-various |
263 (defvar message-mode-hook nil | 421 :type 'hook) |
264 "Hook run in message mode buffers.") | 422 |
265 | 423 (defcustom message-mode-hook nil |
266 (defvar message-header-hook nil | 424 "Hook run in message mode buffers." |
267 "Hook run in a message mode buffer narrowed to the headers.") | 425 :group 'message-various |
268 | 426 :type 'hook) |
269 (defvar message-header-setup-hook nil | 427 |
270 "Hook called narrowed to the headers when setting up a message buffer.") | 428 (defcustom message-header-hook nil |
429 "Hook run in a message mode buffer narrowed to the headers." | |
430 :group 'message-various | |
431 :type 'hook) | |
432 | |
433 (defcustom message-header-setup-hook nil | |
434 "Hook called narrowed to the headers when setting up a message | |
435 buffer." | |
436 :group 'message-various | |
437 :type 'hook) | |
271 | 438 |
272 ;;;###autoload | 439 ;;;###autoload |
273 (defvar message-citation-line-function 'message-insert-citation-line | 440 (defcustom message-citation-line-function 'message-insert-citation-line |
274 "*Function called to insert the \"Whomever writes:\" line.") | 441 "*Function called to insert the \"Whomever writes:\" line." |
442 :type 'function | |
443 :group 'message-insertion) | |
275 | 444 |
276 ;;;###autoload | 445 ;;;###autoload |
277 (defvar message-yank-prefix "> " | 446 (defcustom message-yank-prefix "> " |
278 "*Prefix inserted on the lines of yanked messages. | 447 "*Prefix inserted on the lines of yanked messages. |
279 nil means use indentation.") | 448 nil means use indentation." |
280 | 449 :type 'string |
281 (defvar message-indentation-spaces 3 | 450 :group 'message-insertion) |
451 | |
452 (defcustom message-indentation-spaces 3 | |
282 "*Number of spaces to insert at the beginning of each cited line. | 453 "*Number of spaces to insert at the beginning of each cited line. |
283 Used by `message-yank-original' via `message-yank-cite'.") | 454 Used by `message-yank-original' via `message-yank-cite'." |
455 :group 'message-insertion | |
456 :type 'integer) | |
284 | 457 |
285 ;;;###autoload | 458 ;;;###autoload |
286 (defvar message-cite-function 'message-cite-original | 459 (defcustom message-cite-function |
287 "*Function for citing an original message.") | 460 (if (and (boundp 'mail-citation-hook) |
461 mail-citation-hook) | |
462 mail-citation-hook | |
463 'message-cite-original) | |
464 "*Function for citing an original message." | |
465 :type '(radio (function-item message-cite-original) | |
466 (function-item sc-cite-original) | |
467 (function :tag "Other")) | |
468 :group 'message-insertion) | |
288 | 469 |
289 ;;;###autoload | 470 ;;;###autoload |
290 (defvar message-indent-citation-function 'message-indent-citation | 471 (defcustom message-indent-citation-function 'message-indent-citation |
291 "*Function for modifying a citation just inserted in the mail buffer. | 472 "*Function for modifying a citation just inserted in the mail buffer. |
292 This can also be a list of functions. Each function can find the | 473 This can also be a list of functions. Each function can find the |
293 citation between (point) and (mark t). And each function should leave | 474 citation between (point) and (mark t). And each function should leave |
294 point and mark around the citation text as modified.") | 475 point and mark around the citation text as modified." |
476 :type 'function | |
477 :group 'message-insertion) | |
295 | 478 |
296 (defvar message-abbrevs-loaded nil) | 479 (defvar message-abbrevs-loaded nil) |
297 | 480 |
298 ;;;###autoload | 481 ;;;###autoload |
299 (defvar message-signature t | 482 (defcustom message-signature t |
300 "*String to be inserted at the end of the message buffer. | 483 "*String to be inserted at the end of the message buffer. |
301 If t, the `message-signature-file' file will be inserted instead. | 484 If t, the `message-signature-file' file will be inserted instead. |
302 If a function, the result from the function will be used instead. | 485 If a function, the result from the function will be used instead. |
303 If a form, the result from the form will be used instead.") | 486 If a form, the result from the form will be used instead." |
487 :type 'sexp | |
488 :group 'message-insertion) | |
304 | 489 |
305 ;;;###autoload | 490 ;;;###autoload |
306 (defvar message-signature-file "~/.signature" | 491 (defcustom message-signature-file "~/.signature" |
307 "*File containing the text inserted at end of message. buffer.") | 492 "*File containing the text inserted at end of message buffer." |
308 | 493 :type 'file |
309 (defvar message-distribution-function nil | 494 :group 'message-insertion) |
310 "*Function called to return a Distribution header.") | 495 |
311 | 496 (defcustom message-distribution-function nil |
312 (defvar message-expires 14 | 497 "*Function called to return a Distribution header." |
313 "*Number of days before your article expires.") | 498 :group 'message-news |
314 | 499 :group 'message-headers |
315 (defvar message-user-path nil | 500 :type 'function) |
501 | |
502 (defcustom message-expires 14 | |
503 "Number of days before your article expires." | |
504 :group 'message-news | |
505 :group 'message-headers | |
506 :link '(custom-manual "(message)News Headers") | |
507 :type 'integer) | |
508 | |
509 (defcustom message-user-path nil | |
316 "If nil, use the NNTP server name in the Path header. | 510 "If nil, use the NNTP server name in the Path header. |
317 If stringp, use this; if non-nil, use no host name (user name only).") | 511 If stringp, use this; if non-nil, use no host name (user name only)." |
512 :group 'message-news | |
513 :group 'message-headers | |
514 :link '(custom-manual "(message)News Headers") | |
515 :type '(choice (const :tag "nntp" nil) | |
516 (string :tag "name") | |
517 (sexp :tag "none" :format "%t" t))) | |
318 | 518 |
319 (defvar message-reply-buffer nil) | 519 (defvar message-reply-buffer nil) |
320 (defvar message-reply-headers nil) | 520 (defvar message-reply-headers nil) |
321 (defvar message-newsreader nil) | 521 (defvar message-newsreader nil) |
322 (defvar message-mailer nil) | 522 (defvar message-mailer nil) |
329 (defvar message-kill-actions nil | 529 (defvar message-kill-actions nil |
330 "A list of actions to be performed before killing a message buffer.") | 530 "A list of actions to be performed before killing a message buffer.") |
331 (defvar message-postpone-actions nil | 531 (defvar message-postpone-actions nil |
332 "A list of actions to be performed after postponing a message.") | 532 "A list of actions to be performed after postponing a message.") |
333 | 533 |
334 ;;;###autoload | 534 (defcustom message-default-headers "" |
335 (defvar message-default-headers nil | |
336 "*A string containing header lines to be inserted in outgoing messages. | 535 "*A string containing header lines to be inserted in outgoing messages. |
337 It is inserted before you edit the message, so you can edit or delete | 536 It is inserted before you edit the message, so you can edit or delete |
338 these lines.") | 537 these lines." |
339 | 538 :group 'message-headers |
340 ;;;###autoload | 539 :type 'string) |
341 (defvar message-default-mail-headers nil | 540 |
342 "*A string of header lines to be inserted in outgoing mails.") | 541 (defcustom message-default-mail-headers "" |
343 | 542 "*A string of header lines to be inserted in outgoing mails." |
344 ;;;###autoload | 543 :group 'message-headers |
345 (defvar message-default-news-headers nil | 544 :group 'message-mail |
346 "*A string of header lines to be inserted in outgoing news articles.") | 545 :type 'string) |
546 | |
547 (defcustom message-default-news-headers "" | |
548 "*A string of header lines to be inserted in outgoing news | |
549 articles." | |
550 :group 'message-headers | |
551 :group 'message-news | |
552 :type 'string) | |
347 | 553 |
348 ;; Note: could use /usr/ucb/mail instead of sendmail; | 554 ;; Note: could use /usr/ucb/mail instead of sendmail; |
349 ;; options -t, and -v if not interactive. | 555 ;; options -t, and -v if not interactive. |
350 (defvar message-mailer-swallows-blank-line | 556 (defcustom message-mailer-swallows-blank-line |
351 (if (and (string-match "sparc-sun-sunos\\(\\'\\|[^5]\\)" | 557 (if (and (string-match "sparc-sun-sunos\\(\\'\\|[^5]\\)" |
352 system-configuration) | 558 system-configuration) |
353 (file-readable-p "/etc/sendmail.cf") | 559 (file-readable-p "/etc/sendmail.cf") |
354 (let ((buffer (get-buffer-create " *temp*"))) | 560 (let ((buffer (get-buffer-create " *temp*"))) |
355 (unwind-protect | 561 (unwind-protect |
359 (goto-char (point-min)) | 565 (goto-char (point-min)) |
360 (let ((case-fold-search nil)) | 566 (let ((case-fold-search nil)) |
361 (re-search-forward "^OR\\>" nil t))) | 567 (re-search-forward "^OR\\>" nil t))) |
362 (kill-buffer buffer)))) | 568 (kill-buffer buffer)))) |
363 ;; According to RFC822, "The field-name must be composed of printable | 569 ;; According to RFC822, "The field-name must be composed of printable |
364 ;; ASCII characters (i.e. characters that have decimal values between | 570 ;; ASCII characters (i. e., characters that have decimal values between |
365 ;; 33 and 126, except colon)", i.e. any chars except ctl chars, | 571 ;; 33 and 126, except colon)", i. e., any chars except ctl chars, |
366 ;; space, or colon. | 572 ;; space, or colon. |
367 '(looking-at "[ \t]\\|[][!\"#$%&'()*+,-./0-9;<=>?@A-Z\\\\^_`a-z{|}~]+:")) | 573 '(looking-at "[ \t]\\|[][!\"#$%&'()*+,-./0-9;<=>?@A-Z\\\\^_`a-z{|}~]+:")) |
368 "Set this non-nil if the system's mailer runs the header and body together. | 574 "Set this non-nil if the system's mailer runs the header and body together. |
369 \(This problem exists on Sunos 4 when sendmail is run in remote mode.) | 575 \(This problem exists on Sunos 4 when sendmail is run in remote mode.) |
370 The value should be an expression to test whether the problem will | 576 The value should be an expression to test whether the problem will |
371 actually occur.") | 577 actually occur." |
578 :group 'message-sending | |
579 :type 'sexp) | |
580 | |
581 (ignore-errors | |
582 (define-mail-user-agent 'message-user-agent | |
583 'message-mail 'message-send-and-exit | |
584 'message-kill-buffer 'message-send-hook)) | |
585 | |
586 (defvar message-delete-mh-headers t | |
587 "If non-nil, delete the deletable headers before feeding to mh.") | |
588 | |
589 ;;; Internal variables. | |
590 ;;; Well, not really internal. | |
372 | 591 |
373 (defvar message-mode-syntax-table | 592 (defvar message-mode-syntax-table |
374 (let ((table (copy-syntax-table text-mode-syntax-table))) | 593 (let ((table (copy-syntax-table text-mode-syntax-table))) |
375 (modify-syntax-entry ?% ". " table) | 594 (modify-syntax-entry ?% ". " table) |
376 table) | 595 table) |
390 1 'font-lock-comment-face) | 609 1 'font-lock-comment-face) |
391 (cons (concat "^[ \t]*" | 610 (cons (concat "^[ \t]*" |
392 "\\([" cite-prefix "]+[" cite-suffix "]*\\)?" | 611 "\\([" cite-prefix "]+[" cite-suffix "]*\\)?" |
393 "[>|}].*") | 612 "[>|}].*") |
394 'font-lock-reference-face) | 613 'font-lock-reference-face) |
395 '("^\\(X-[A-Za-z0-9-]+\\|In-reply-to\\):.*" | 614 '("^\\(X-[A-Za-z0-9-]+\\|In-Reply-To\\):.*" |
396 . font-lock-string-face))) | 615 . font-lock-string-face))) |
397 "Additional expressions to highlight in Message mode.") | 616 "Additional expressions to highlight in Message mode.") |
398 | 617 |
399 (defvar message-face-alist | 618 (defvar message-face-alist |
400 '((bold . bold-region) | 619 '((bold . bold-region) |
403 (unbold-region b e) | 622 (unbold-region b e) |
404 (ununderline-region b e)))) | 623 (ununderline-region b e)))) |
405 "Alist of mail and news faces for facemenu. | 624 "Alist of mail and news faces for facemenu. |
406 The cdr of ech entry is a function for applying the face to a region.") | 625 The cdr of ech entry is a function for applying the face to a region.") |
407 | 626 |
408 (defvar message-send-hook nil | 627 (defcustom message-send-hook nil |
409 "Hook run before sending messages.") | 628 "Hook run before sending messages." |
410 | 629 :group 'message-various |
411 (defvar message-sent-hook nil | 630 :options '(ispell-message) |
412 "Hook run after sending messages.") | 631 :type 'hook) |
632 | |
633 (defcustom message-send-mail-hook nil | |
634 "Hook run before sending mail messages." | |
635 :group 'message-various | |
636 :type 'hook) | |
637 | |
638 (defcustom message-send-news-hook nil | |
639 "Hook run before sending news messages." | |
640 :group 'message-various | |
641 :type 'hook) | |
642 | |
643 (defcustom message-sent-hook nil | |
644 "Hook run after sending messages." | |
645 :group 'message-various | |
646 :type 'hook) | |
413 | 647 |
414 ;;; Internal variables. | 648 ;;; Internal variables. |
415 | 649 |
416 (defvar message-buffer-list nil) | 650 (defvar message-buffer-list nil) |
651 (defvar message-this-is-news nil) | |
652 (defvar message-this-is-mail nil) | |
653 | |
654 ;; Byte-compiler warning | |
655 (defvar gnus-active-hashtb) | |
656 (defvar gnus-read-active-file) | |
417 | 657 |
418 ;;; Regexp matching the delimiter of messages in UNIX mail format | 658 ;;; Regexp matching the delimiter of messages in UNIX mail format |
419 ;;; (UNIX From lines), minus the initial ^. | 659 ;;; (UNIX From lines), minus the initial ^. |
420 (defvar message-unix-mail-delimiter | 660 (defvar message-unix-mail-delimiter |
421 (let ((time-zone-regexp | 661 (let ((time-zone-regexp |
476 (Organization) | 716 (Organization) |
477 (Distribution) | 717 (Distribution) |
478 (Lines) | 718 (Lines) |
479 (Expires) | 719 (Expires) |
480 (Message-ID) | 720 (Message-ID) |
481 (References . message-fill-header) | 721 (References) |
482 (X-Mailer) | 722 (X-Mailer) |
483 (X-Newsreader)) | 723 (X-Newsreader)) |
484 "Alist used for formatting headers.") | 724 "Alist used for formatting headers.") |
485 | 725 |
486 (eval-and-compile | 726 (eval-and-compile |
487 (autoload 'message-setup-toolbar "messagexmas") | 727 (autoload 'message-setup-toolbar "messagexmas") |
488 (autoload 'mh-send-letter "mh-comp")) | 728 (autoload 'mh-send-letter "mh-comp") |
729 (autoload 'gnus-output-to-mail "gnus-util") | |
730 (autoload 'gnus-output-to-rmail "gnus-util")) | |
489 | 731 |
490 | 732 |
491 | 733 |
492 ;;; | 734 ;;; |
493 ;;; Utility functions. | 735 ;;; Utility functions. |
507 (end-of-line) | 749 (end-of-line) |
508 (prog1 | 750 (prog1 |
509 (point) | 751 (point) |
510 (goto-char p)))) | 752 (goto-char p)))) |
511 | 753 |
754 (defmacro message-y-or-n-p (question show &rest text) | |
755 "Ask QUESTION, displaying the rest of the arguments in a temp. buffer if SHOW" | |
756 `(message-talkative-question 'y-or-n-p ,question ,show ,@text)) | |
757 | |
512 ;; Delete the current line (and the next N lines.); | 758 ;; Delete the current line (and the next N lines.); |
513 (defmacro message-delete-line (&optional n) | 759 (defmacro message-delete-line (&optional n) |
514 `(delete-region (progn (beginning-of-line) (point)) | 760 `(delete-region (progn (beginning-of-line) (point)) |
515 (progn (forward-line ,(or n 1)) (point)))) | 761 (progn (forward-line ,(or n 1)) (point)))) |
516 | 762 |
517 (defun message-tokenize-header (header &optional separator) | 763 (defun message-tokenize-header (header &optional separator) |
518 "Split HEADER into a list of header elements. | 764 "Split HEADER into a list of header elements. |
519 \",\" is used as the separator." | 765 \",\" is used as the separator." |
520 (let ((regexp (format "[%s]+" (or separator ","))) | 766 (if (not header) |
521 (beg 1) | 767 nil |
522 (first t) | 768 (let ((regexp (format "[%s]+" (or separator ","))) |
523 quoted elems) | 769 (beg 1) |
524 (save-excursion | 770 (first t) |
525 (message-set-work-buffer) | 771 quoted elems paren) |
526 (insert header) | 772 (save-excursion |
527 (goto-char (point-min)) | 773 (message-set-work-buffer) |
528 (while (not (eobp)) | 774 (insert header) |
529 (if first | 775 (goto-char (point-min)) |
530 (setq first nil) | 776 (while (not (eobp)) |
531 (forward-char 1)) | 777 (if first |
532 (cond ((and (> (point) beg) | 778 (setq first nil) |
533 (or (eobp) | 779 (forward-char 1)) |
534 (and (looking-at regexp) | 780 (cond ((and (> (point) beg) |
535 (not quoted)))) | 781 (or (eobp) |
536 (push (buffer-substring beg (point)) elems) | 782 (and (looking-at regexp) |
537 (setq beg (match-end 0))) | 783 (not quoted) |
538 ((= (following-char) ?\") | 784 (not paren)))) |
539 (setq quoted (not quoted))))) | 785 (push (buffer-substring beg (point)) elems) |
540 (nreverse elems)))) | 786 (setq beg (match-end 0))) |
787 ((= (following-char) ?\") | |
788 (setq quoted (not quoted))) | |
789 ((and (= (following-char) ?\() | |
790 (not quoted)) | |
791 (setq paren t)) | |
792 ((and (= (following-char) ?\)) | |
793 (not quoted)) | |
794 (setq paren nil)))) | |
795 (nreverse elems))))) | |
541 | 796 |
542 (defun message-fetch-field (header) | 797 (defun message-fetch-field (header) |
543 "The same as `mail-fetch-field', only remove all newlines." | 798 "The same as `mail-fetch-field', only remove all newlines." |
544 (let ((value (mail-fetch-field header))) | 799 (let ((value (mail-fetch-field header nil t))) |
545 (when value | 800 (when value |
546 (nnheader-replace-chars-in-string value ?\n ? )))) | 801 (nnheader-replace-chars-in-string value ?\n ? )))) |
547 | 802 |
548 (defun message-fetch-reply-field (header) | 803 (defun message-fetch-reply-field (header) |
549 "Fetch FIELD from the message we're replying to." | 804 "Fetch FIELD from the message we're replying to." |
628 (point-max))) | 883 (point-max))) |
629 (goto-char (point-min))) | 884 (goto-char (point-min))) |
630 | 885 |
631 (defun message-news-p () | 886 (defun message-news-p () |
632 "Say whether the current buffer contains a news message." | 887 "Say whether the current buffer contains a news message." |
633 (save-excursion | 888 (or message-this-is-news |
634 (save-restriction | 889 (save-excursion |
635 (message-narrow-to-headers) | 890 (save-restriction |
636 (message-fetch-field "newsgroups")))) | 891 (message-narrow-to-headers) |
892 (message-fetch-field "newsgroups"))))) | |
637 | 893 |
638 (defun message-mail-p () | 894 (defun message-mail-p () |
639 "Say whether the current buffer contains a mail message." | 895 "Say whether the current buffer contains a mail message." |
640 (save-excursion | 896 (or message-this-is-mail |
641 (save-restriction | 897 (save-excursion |
642 (message-narrow-to-headers) | 898 (save-restriction |
643 (or (message-fetch-field "to") | 899 (message-narrow-to-headers) |
644 (message-fetch-field "cc") | 900 (or (message-fetch-field "to") |
645 (message-fetch-field "bcc"))))) | 901 (message-fetch-field "cc") |
902 (message-fetch-field "bcc")))))) | |
646 | 903 |
647 (defun message-next-header () | 904 (defun message-next-header () |
648 "Go to the beginning of the next header." | 905 "Go to the beginning of the next header." |
649 (beginning-of-line) | 906 (beginning-of-line) |
650 (or (eobp) (forward-char 1)) | 907 (or (eobp) (forward-char 1)) |
661 (message-next-header) | 918 (message-next-header) |
662 (unless (bobp) | 919 (unless (bobp) |
663 (forward-char -1))) | 920 (forward-char -1))) |
664 (lambda () | 921 (lambda () |
665 (or (get-text-property (point) 'message-rank) | 922 (or (get-text-property (point) 'message-rank) |
666 0)))) | 923 10000)))) |
667 | 924 |
668 (defun message-sort-headers () | 925 (defun message-sort-headers () |
669 "Sort the headers of the current message according to `message-header-format-alist'." | 926 "Sort the headers of the current message according to `message-header-format-alist'." |
670 (interactive) | 927 (interactive) |
671 (save-excursion | 928 (save-excursion |
727 (define-key message-mode-map "\C-c\C-c" 'message-send-and-exit) | 984 (define-key message-mode-map "\C-c\C-c" 'message-send-and-exit) |
728 (define-key message-mode-map "\C-c\C-s" 'message-send) | 985 (define-key message-mode-map "\C-c\C-s" 'message-send) |
729 (define-key message-mode-map "\C-c\C-k" 'message-kill-buffer) | 986 (define-key message-mode-map "\C-c\C-k" 'message-kill-buffer) |
730 (define-key message-mode-map "\C-c\C-d" 'message-dont-send) | 987 (define-key message-mode-map "\C-c\C-d" 'message-dont-send) |
731 | 988 |
989 (define-key message-mode-map "\C-c\C-e" 'message-elide-region) | |
990 | |
732 (define-key message-mode-map "\t" 'message-tab)) | 991 (define-key message-mode-map "\t" 'message-tab)) |
733 | 992 |
734 (easy-menu-define message-mode-menu message-mode-map | 993 (easy-menu-define |
735 "Message Menu." | 994 message-mode-menu message-mode-map "Message Menu." |
736 '("Message" | 995 '("Message" |
737 "Go to Field:" | 996 ["Sort Headers" message-sort-headers t] |
738 "----" | 997 ["Yank Original" message-yank-original t] |
739 ["To" message-goto-to t] | 998 ["Fill Yanked Message" message-fill-yanked-message t] |
740 ["Subject" message-goto-subject t] | 999 ["Insert Signature" message-insert-signature t] |
741 ["Cc" message-goto-cc t] | 1000 ["Caesar (rot13) Message" message-caesar-buffer-body t] |
742 ["Reply-to" message-goto-reply-to t] | 1001 ["Caesar (rot13) Region" message-caesar-region (mark t)] |
743 ["Summary" message-goto-summary t] | 1002 ["Elide Region" message-elide-region (mark t)] |
744 ["Keywords" message-goto-keywords t] | 1003 ["Rename buffer" message-rename-buffer t] |
745 ["Newsgroups" message-goto-newsgroups t] | 1004 ["Spellcheck" ispell-message t] |
746 ["Followup-To" message-goto-followup-to t] | 1005 "----" |
747 ["Distribution" message-goto-distribution t] | 1006 ["Send Message" message-send-and-exit t] |
748 ["Body" message-goto-body t] | 1007 ["Abort Message" message-dont-send t])) |
749 ["Signature" message-goto-signature t] | 1008 |
750 "----" | 1009 (easy-menu-define |
751 "Miscellaneous Commands:" | 1010 message-mode-field-menu message-mode-map "" |
752 "----" | 1011 '("Field" |
753 ["Sort Headers" message-sort-headers t] | 1012 ["Fetch To" message-insert-to t] |
754 ["Yank Original" message-yank-original t] | 1013 ["Fetch Newsgroups" message-insert-newsgroups t] |
755 ["Fill Yanked Message" message-fill-yanked-message t] | 1014 "----" |
756 ["Insert Signature" message-insert-signature t] | 1015 ["To" message-goto-to t] |
757 ["Caesar (rot13) Message" message-caesar-buffer-body t] | 1016 ["Subject" message-goto-subject t] |
758 ["Rename buffer" message-rename-buffer t] | 1017 ["Cc" message-goto-cc t] |
759 ["Spellcheck" ispell-message t] | 1018 ["Reply-To" message-goto-reply-to t] |
760 "----" | 1019 ["Summary" message-goto-summary t] |
761 ["Send Message" message-send-and-exit t] | 1020 ["Keywords" message-goto-keywords t] |
762 ["Abort Message" message-dont-send t])) | 1021 ["Newsgroups" message-goto-newsgroups t] |
1022 ["Followup-To" message-goto-followup-to t] | |
1023 ["Distribution" message-goto-distribution t] | |
1024 ["Body" message-goto-body t] | |
1025 ["Signature" message-goto-signature t])) | |
763 | 1026 |
764 (defvar facemenu-add-face-function) | 1027 (defvar facemenu-add-face-function) |
765 (defvar facemenu-remove-face-function) | 1028 (defvar facemenu-remove-face-function) |
766 | 1029 |
767 ;;;###autoload | 1030 ;;;###autoload |
770 Like Text Mode but with these additional commands: | 1033 Like Text Mode but with these additional commands: |
771 C-c C-s message-send (send the message) C-c C-c message-send-and-exit | 1034 C-c C-s message-send (send the message) C-c C-c message-send-and-exit |
772 C-c C-f move to a header field (and create it if there isn't): | 1035 C-c C-f move to a header field (and create it if there isn't): |
773 C-c C-f C-t move to To C-c C-f C-s move to Subject | 1036 C-c C-f C-t move to To C-c C-f C-s move to Subject |
774 C-c C-f C-c move to Cc C-c C-f C-b move to Bcc | 1037 C-c C-f C-c move to Cc C-c C-f C-b move to Bcc |
775 C-c C-f C-f move to Fcc C-c C-f C-r move to Reply-To | 1038 C-c C-f C-w move to Fcc C-c C-f C-r move to Reply-To |
776 C-c C-f C-u move to Summary C-c C-f C-n move to Newsgroups | 1039 C-c C-f C-u move to Summary C-c C-f C-n move to Newsgroups |
777 C-c C-f C-k move to Keywords C-c C-f C-d move to Distribution | 1040 C-c C-f C-k move to Keywords C-c C-f C-d move to Distribution |
778 C-c C-f C-o move to Followup-To | 1041 C-c C-f C-f move to Followup-To |
779 C-c C-t message-insert-to (add a To header to a news followup) | 1042 C-c C-t message-insert-to (add a To header to a news followup) |
780 C-c C-n message-insert-newsgroups (add a Newsgroup header to a news reply) | 1043 C-c C-n message-insert-newsgroups (add a Newsgroup header to a news reply) |
781 C-c C-b message-goto-body (move to beginning of message text). | 1044 C-c C-b message-goto-body (move to beginning of message text). |
782 C-c C-i message-goto-signature (move to the beginning of the signature). | 1045 C-c C-i message-goto-signature (move to the beginning of the signature). |
783 C-c C-w message-insert-signature (insert `message-signature-file' file). | 1046 C-c C-w message-insert-signature (insert `message-signature-file' file). |
784 C-c C-y message-yank-original (insert current message, if any). | 1047 C-c C-y message-yank-original (insert current message, if any). |
785 C-c C-q message-fill-yanked-message (fill what was yanked). | 1048 C-c C-q message-fill-yanked-message (fill what was yanked). |
786 C-c C-r message-ceasar-buffer-body (rot13 the message body)." | 1049 C-c C-e message-elide-region (elide the text between point and mark). |
1050 C-c C-r message-caesar-buffer-body (rot13 the message body)." | |
787 (interactive) | 1051 (interactive) |
788 (kill-all-local-variables) | 1052 (kill-all-local-variables) |
789 (make-local-variable 'message-reply-buffer) | 1053 (make-local-variable 'message-reply-buffer) |
790 (setq message-reply-buffer nil) | 1054 (setq message-reply-buffer nil) |
791 (make-local-variable 'message-send-actions) | 1055 (make-local-variable 'message-send-actions) |
912 | 1176 |
913 (defun message-goto-signature () | 1177 (defun message-goto-signature () |
914 "Move point to the beginning of the message signature." | 1178 "Move point to the beginning of the message signature." |
915 (interactive) | 1179 (interactive) |
916 (goto-char (point-min)) | 1180 (goto-char (point-min)) |
917 (or (re-search-forward message-signature-separator nil t) | 1181 (if (re-search-forward message-signature-separator nil t) |
918 (goto-char (point-max)))) | 1182 (forward-line 1) |
1183 (goto-char (point-max)))) | |
919 | 1184 |
920 | 1185 |
921 | 1186 |
922 (defun message-insert-to () | 1187 (defun message-insert-to () |
923 "Insert a To header that points to the author of the article being replied to." | 1188 "Insert a To header that points to the author of the article being replied to." |
924 (interactive) | 1189 (interactive) |
1190 (let ((co (message-fetch-field "courtesy-copies-to"))) | |
1191 (when (and co | |
1192 (equal (downcase co) "never")) | |
1193 (error "The user has requested not to have copies sent via mail"))) | |
925 (when (and (message-position-on-field "To") | 1194 (when (and (message-position-on-field "To") |
926 (mail-fetch-field "to") | 1195 (mail-fetch-field "to") |
927 (not (string-match "\\` *\\'" (mail-fetch-field "to")))) | 1196 (not (string-match "\\` *\\'" (mail-fetch-field "to")))) |
928 (insert ", ")) | 1197 (insert ", ")) |
929 (insert (or (message-fetch-reply-field "reply-to") | 1198 (insert (or (message-fetch-reply-field "reply-to") |
944 | 1213 |
945 (defun message-insert-signature (&optional force) | 1214 (defun message-insert-signature (&optional force) |
946 "Insert a signature. See documentation for the `message-signature' variable." | 1215 "Insert a signature. See documentation for the `message-signature' variable." |
947 (interactive (list 0)) | 1216 (interactive (list 0)) |
948 (let* ((signature | 1217 (let* ((signature |
949 (cond ((and (null message-signature) | 1218 (cond |
950 (eq force 0)) | 1219 ((and (null message-signature) |
951 (save-excursion | 1220 (eq force 0)) |
952 (goto-char (point-max)) | 1221 (save-excursion |
953 (not (re-search-backward | 1222 (goto-char (point-max)) |
954 message-signature-separator nil t)))) | 1223 (not (re-search-backward |
955 ((and (null message-signature) | 1224 message-signature-separator nil t)))) |
956 force) | 1225 ((and (null message-signature) |
957 t) | 1226 force) |
958 ((message-functionp message-signature) | 1227 t) |
959 (funcall message-signature)) | 1228 ((message-functionp message-signature) |
960 ((listp message-signature) | 1229 (funcall message-signature)) |
961 (eval message-signature)) | 1230 ((listp message-signature) |
962 (t message-signature))) | 1231 (eval message-signature)) |
1232 (t message-signature))) | |
963 (signature | 1233 (signature |
964 (cond ((stringp signature) | 1234 (cond ((stringp signature) |
965 signature) | 1235 signature) |
966 ((and (eq t signature) | 1236 ((and (eq t signature) |
967 message-signature-file | 1237 message-signature-file |
968 (file-exists-p message-signature-file)) | 1238 (file-exists-p message-signature-file)) |
969 signature)))) | 1239 signature)))) |
970 (when signature | 1240 (when signature |
1241 (goto-char (point-max)) | |
971 ;; Insert the signature. | 1242 ;; Insert the signature. |
972 (goto-char (point-max)) | |
973 (unless (bolp) | 1243 (unless (bolp) |
974 (insert "\n")) | 1244 (insert "\n")) |
975 (insert "\n-- \n") | 1245 (insert "\n-- \n") |
976 (if (eq signature t) | 1246 (if (eq signature t) |
977 (insert-file-contents message-signature-file) | 1247 (insert-file-contents message-signature-file) |
978 (insert signature)) | 1248 (insert signature)) |
979 (goto-char (point-max)) | 1249 (goto-char (point-max)) |
980 (or (bolp) (insert "\n"))))) | 1250 (or (bolp) (insert "\n"))))) |
1251 | |
1252 (defun message-elide-region (b e) | |
1253 "Elide the text between point and mark. An ellipsis (from | |
1254 message-elide-elipsis) will be inserted where the text was killed." | |
1255 (interactive "r") | |
1256 (kill-region b e) | |
1257 (unless (bolp) | |
1258 (insert "\n")) | |
1259 (insert message-elide-elipsis)) | |
981 | 1260 |
982 (defvar message-caesar-translation-table nil) | 1261 (defvar message-caesar-translation-table nil) |
983 | 1262 |
984 (defun message-caesar-region (b e &optional n) | 1263 (defun message-caesar-region (b e &optional n) |
985 "Caesar rotation of region by N, default 13, for decrypting netnews." | 1264 "Caesar rotation of region by N, default 13, for decrypting netnews." |
1030 (save-restriction | 1309 (save-restriction |
1031 (when (message-goto-body) | 1310 (when (message-goto-body) |
1032 (narrow-to-region (point) (point-max))) | 1311 (narrow-to-region (point) (point-max))) |
1033 (message-caesar-region (point-min) (point-max) rotnum)))) | 1312 (message-caesar-region (point-min) (point-max) rotnum)))) |
1034 | 1313 |
1314 (defun message-pipe-buffer-body (program) | |
1315 "Pipe the message body in the current buffer through PROGRAM." | |
1316 (save-excursion | |
1317 (save-restriction | |
1318 (when (message-goto-body) | |
1319 (narrow-to-region (point) (point-max))) | |
1320 (let ((body (buffer-substring (point-min) (point-max)))) | |
1321 (unless (equal 0 (call-process-region | |
1322 (point-min) (point-max) program t t)) | |
1323 (insert body) | |
1324 (gnus-message 1 "%s failed." program)))))) | |
1325 | |
1035 (defun message-rename-buffer (&optional enter-string) | 1326 (defun message-rename-buffer (&optional enter-string) |
1036 "Rename the *message* buffer to \"*message* RECIPIENT\". | 1327 "Rename the *message* buffer to \"*message* RECIPIENT\". |
1037 If the function is run with a prefix, it will ask for a new buffer | 1328 If the function is run with a prefix, it will ask for a new buffer |
1038 name, rather than giving an automatic name." | 1329 name, rather than giving an automatic name." |
1039 (interactive "Pbuffer name: ") | 1330 (interactive "Pbuffer name: ") |
1040 (save-excursion | 1331 (save-excursion |
1041 (save-restriction | 1332 (save-restriction |
1042 (goto-char (point-min)) | 1333 (goto-char (point-min)) |
1043 (narrow-to-region (point) | 1334 (narrow-to-region (point) |
1044 (search-forward mail-header-separator nil 'end)) | 1335 (search-forward mail-header-separator nil 'end)) |
1045 (let* ((mail-to (if (message-news-p) (message-fetch-field "Newsgroups") | 1336 (let* ((mail-to (or |
1046 (message-fetch-field "To"))) | 1337 (if (message-news-p) (message-fetch-field "Newsgroups") |
1338 (message-fetch-field "To")) | |
1339 "")) | |
1047 (mail-trimmed-to | 1340 (mail-trimmed-to |
1048 (if (string-match "," mail-to) | 1341 (if (string-match "," mail-to) |
1049 (concat (substring mail-to 0 (match-beginning 0)) ", ...") | 1342 (concat (substring mail-to 0 (match-beginning 0)) ", ...") |
1050 mail-to)) | 1343 mail-to)) |
1051 (name-default (concat "*message* " mail-trimmed-to)) | 1344 (name-default (concat "*message* " mail-trimmed-to)) |
1052 (name (if enter-string | 1345 (name (if enter-string |
1053 (read-string "New buffer name: " name-default) | 1346 (read-string "New buffer name: " name-default) |
1054 name-default))) | 1347 name-default)) |
1055 (rename-buffer name t) | 1348 (default-directory |
1056 (setq buffer-auto-save-file-name | 1349 (file-name-as-directory message-autosave-directory))) |
1057 (format "%s%s" | 1350 (rename-buffer name t))))) |
1058 (file-name-as-directory message-autosave-directory) | |
1059 (file-name-nondirectory buffer-auto-save-file-name))))))) | |
1060 | 1351 |
1061 (defun message-fill-yanked-message (&optional justifyp) | 1352 (defun message-fill-yanked-message (&optional justifyp) |
1062 "Fill the paragraphs of a message yanked into this one. | 1353 "Fill the paragraphs of a message yanked into this one. |
1063 Numeric argument means justify as well." | 1354 Numeric argument means justify as well." |
1064 (interactive "P") | 1355 (interactive "P") |
1082 (narrow-to-region | 1373 (narrow-to-region |
1083 (goto-char start) | 1374 (goto-char start) |
1084 (if (search-forward "\n\n" nil t) | 1375 (if (search-forward "\n\n" nil t) |
1085 (1- (point)) | 1376 (1- (point)) |
1086 (point))) | 1377 (point))) |
1087 (message-remove-header message-ignored-cited-headers t))) | 1378 (message-remove-header message-ignored-cited-headers t) |
1379 (goto-char (point-max)))) | |
1380 ;; Delete blank lines at the start of the buffer. | |
1381 (while (and (point-min) | |
1382 (eolp) | |
1383 (not (eobp))) | |
1384 (message-delete-line)) | |
1385 ;; Delete blank lines at the end of the buffer. | |
1386 (goto-char (point-max)) | |
1387 (unless (eolp) | |
1388 (insert "\n")) | |
1389 (while (and (zerop (forward-line -1)) | |
1390 (looking-at "$")) | |
1391 (message-delete-line)) | |
1088 ;; Do the indentation. | 1392 ;; Do the indentation. |
1089 (if (null message-yank-prefix) | 1393 (if (null message-yank-prefix) |
1090 (indent-rigidly start (mark t) message-indentation-spaces) | 1394 (indent-rigidly start (mark t) message-indentation-spaces) |
1091 (save-excursion | 1395 (save-excursion |
1092 (goto-char start) | 1396 (goto-char start) |
1093 (while (< (point) (mark t)) | 1397 (while (< (point) (mark t)) |
1094 (insert message-yank-prefix) | 1398 (insert message-yank-prefix) |
1095 (forward-line 1))) | 1399 (forward-line 1)))) |
1096 (goto-char start)))) | 1400 (goto-char start))) |
1097 | 1401 |
1098 (defun message-yank-original (&optional arg) | 1402 (defun message-yank-original (&optional arg) |
1099 "Insert the message being replied to, if any. | 1403 "Insert the message being replied to, if any. |
1100 Puts point before the text and mark after. | 1404 Puts point before the text and mark after. |
1101 Normally indents each nonblank line ARG spaces (default 3). However, | 1405 Normally indents each nonblank line ARG spaces (default 3). However, |
1116 (unless (bolp) | 1420 (unless (bolp) |
1117 (insert ?\n)) | 1421 (insert ?\n)) |
1118 (unless modified | 1422 (unless modified |
1119 (setq message-checksum (cons (message-checksum) (buffer-size))))))) | 1423 (setq message-checksum (cons (message-checksum) (buffer-size))))))) |
1120 | 1424 |
1121 (defun message-cite-original () | 1425 (defun message-cite-original () |
1426 "Cite function in the standard Message manner." | |
1122 (let ((start (point)) | 1427 (let ((start (point)) |
1123 (functions | 1428 (functions |
1124 (when message-indent-citation-function | 1429 (when message-indent-citation-function |
1125 (if (listp message-indent-citation-function) | 1430 (if (listp message-indent-citation-function) |
1126 message-indent-citation-function | 1431 message-indent-citation-function |
1170 "Remove the signature from the text between point and mark. | 1475 "Remove the signature from the text between point and mark. |
1171 The text will also be indented the normal way." | 1476 The text will also be indented the normal way." |
1172 (save-excursion | 1477 (save-excursion |
1173 (let ((start (point)) | 1478 (let ((start (point)) |
1174 mark) | 1479 mark) |
1175 (if (not (re-search-forward message-signature-separator (mark t) t)) | 1480 (if (not (re-search-forward message-signature-separator (mark t) t)) |
1176 ;; No signature here, so we just indent the cited text. | 1481 ;; No signature here, so we just indent the cited text. |
1482 (message-indent-citation) | |
1483 ;; Find the last non-empty line. | |
1484 (forward-line -1) | |
1485 (while (looking-at "[ \t]*$") | |
1486 (forward-line -1)) | |
1487 (forward-line 1) | |
1488 (setq mark (set-marker (make-marker) (point))) | |
1489 (goto-char start) | |
1177 (message-indent-citation) | 1490 (message-indent-citation) |
1178 ;; Find the last non-empty line. | 1491 ;; Enable undoing the deletion. |
1179 (forward-line -1) | 1492 (undo-boundary) |
1180 (while (looking-at "[ \t]*$") | 1493 (delete-region mark (mark t)) |
1181 (forward-line -1)) | 1494 (set-marker mark nil))))) |
1182 (forward-line 1) | |
1183 (setq mark (set-marker (make-marker) (point))) | |
1184 (goto-char start) | |
1185 (message-indent-citation) | |
1186 ;; Enable undoing the deletion. | |
1187 (undo-boundary) | |
1188 (delete-region mark (mark t)) | |
1189 (set-marker mark nil))))) | |
1190 | 1495 |
1191 | 1496 |
1192 | 1497 |
1193 ;;; | 1498 ;;; |
1194 ;;; Sending messages | 1499 ;;; Sending messages |
1209 (message-do-actions actions)))) | 1514 (message-do-actions actions)))) |
1210 | 1515 |
1211 (defun message-dont-send () | 1516 (defun message-dont-send () |
1212 "Don't send the message you have been editing." | 1517 "Don't send the message you have been editing." |
1213 (interactive) | 1518 (interactive) |
1214 (message-bury (current-buffer)) | 1519 (let ((actions message-postpone-actions)) |
1215 (message-do-actions message-postpone-actions)) | 1520 (message-bury (current-buffer)) |
1521 (message-do-actions actions))) | |
1216 | 1522 |
1217 (defun message-kill-buffer () | 1523 (defun message-kill-buffer () |
1218 "Kill the current buffer." | 1524 "Kill the current buffer." |
1219 (interactive) | 1525 (interactive) |
1220 (let ((actions message-kill-actions)) | 1526 (let ((actions message-kill-actions)) |
1293 | 1599 |
1294 (defun message-do-actions (actions) | 1600 (defun message-do-actions (actions) |
1295 "Perform all actions in ACTIONS." | 1601 "Perform all actions in ACTIONS." |
1296 ;; Now perform actions on successful sending. | 1602 ;; Now perform actions on successful sending. |
1297 (while actions | 1603 (while actions |
1298 (condition-case nil | 1604 (ignore-errors |
1299 (cond | 1605 (cond |
1300 ;; A simple function. | 1606 ;; A simple function. |
1301 ((message-functionp (car actions)) | 1607 ((message-functionp (car actions)) |
1302 (funcall (car actions))) | 1608 (funcall (car actions))) |
1303 ;; Something to be evaled. | 1609 ;; Something to be evaled. |
1304 (t | 1610 (t |
1305 (eval (car actions)))) | 1611 (eval (car actions))))) |
1306 (error)) | |
1307 (pop actions))) | 1612 (pop actions))) |
1308 | 1613 |
1309 (defun message-send-mail (&optional arg) | 1614 (defun message-send-mail (&optional arg) |
1310 (require 'mail-utils) | 1615 (require 'mail-utils) |
1311 (let ((tembuf (generate-new-buffer " message temp")) | 1616 (let ((tembuf (message-generate-new-buffer-clone-locals " message temp")) |
1312 (case-fold-search nil) | 1617 (case-fold-search nil) |
1313 (news (message-news-p)) | 1618 (news (message-news-p)) |
1314 (mailbuf (current-buffer))) | 1619 (mailbuf (current-buffer))) |
1315 (save-restriction | 1620 (save-restriction |
1316 (message-narrow-to-headers) | 1621 (message-narrow-to-headers) |
1362 (re-search-forward | 1667 (re-search-forward |
1363 (concat "^" (regexp-quote mail-header-separator) "\n")) | 1668 (concat "^" (regexp-quote mail-header-separator) "\n")) |
1364 (replace-match "\n") | 1669 (replace-match "\n") |
1365 (backward-char 1) | 1670 (backward-char 1) |
1366 (setq delimline (point-marker)) | 1671 (setq delimline (point-marker)) |
1672 (run-hooks 'message-send-mail-hook) | |
1367 ;; Insert an extra newline if we need it to work around | 1673 ;; Insert an extra newline if we need it to work around |
1368 ;; Sun's bug that swallows newlines. | 1674 ;; Sun's bug that swallows newlines. |
1369 (goto-char (1+ delimline)) | 1675 (goto-char (1+ delimline)) |
1370 (when (eval message-mailer-swallows-blank-line) | 1676 (when (eval message-mailer-swallows-blank-line) |
1371 (newline)) | 1677 (newline)) |
1380 sendmail-program | 1686 sendmail-program |
1381 "/usr/lib/sendmail") | 1687 "/usr/lib/sendmail") |
1382 nil errbuf nil "-oi") | 1688 nil errbuf nil "-oi") |
1383 ;; Always specify who from, | 1689 ;; Always specify who from, |
1384 ;; since some systems have broken sendmails. | 1690 ;; since some systems have broken sendmails. |
1385 (list "-f" (user-login-name)) | 1691 ;; But some systems are more broken with -f, so |
1692 ;; we'll let users override this. | |
1693 (if (null message-sendmail-f-is-evil) | |
1694 (list "-f" (user-login-name))) | |
1386 ;; These mean "report errors by mail" | 1695 ;; These mean "report errors by mail" |
1387 ;; and "deliver in background". | 1696 ;; and "deliver in background". |
1388 (if (null message-interactive) '("-oem" "-odb")) | 1697 (if (null message-interactive) '("-oem" "-odb")) |
1389 ;; Get the addresses from the message | 1698 ;; Get the addresses from the message |
1390 ;; unless this is a resend. | 1699 ;; unless this is a resend. |
1404 (error "Sending...failed to %s" | 1713 (error "Sending...failed to %s" |
1405 (buffer-substring (point-min) (point-max))))) | 1714 (buffer-substring (point-min) (point-max))))) |
1406 (when (bufferp errbuf) | 1715 (when (bufferp errbuf) |
1407 (kill-buffer errbuf))))) | 1716 (kill-buffer errbuf))))) |
1408 | 1717 |
1718 (defun message-send-mail-with-qmail () | |
1719 "Pass the prepared message buffer to qmail-inject. | |
1720 Refer to the documentation for the variable `message-send-mail-function' | |
1721 to find out how to use this." | |
1722 ;; replace the header delimiter with a blank line | |
1723 (goto-char (point-min)) | |
1724 (re-search-forward | |
1725 (concat "^" (regexp-quote mail-header-separator) "\n")) | |
1726 (replace-match "\n") | |
1727 (run-hooks 'message-send-mail-hook) | |
1728 ;; send the message | |
1729 (case | |
1730 (apply | |
1731 'call-process-region 1 (point-max) message-qmail-inject-program | |
1732 nil nil nil | |
1733 ;; qmail-inject's default behaviour is to look for addresses on the | |
1734 ;; command line; if there're none, it scans the headers. | |
1735 ;; yes, it does The Right Thing w.r.t. Resent-To and it's kin. | |
1736 ;; | |
1737 ;; in general, ALL of qmail-inject's defaults are perfect for simply | |
1738 ;; reading a formatted (i. e., at least a To: or Resent-To header) | |
1739 ;; message from stdin. | |
1740 ;; | |
1741 ;; qmail also has the advantage of not having been raped by | |
1742 ;; various vendors, so we don't have to allow for that, either -- | |
1743 ;; compare this with message-send-mail-with-sendmail and weep | |
1744 ;; for sendmail's lost innocence. | |
1745 ;; | |
1746 ;; all this is way cool coz it lets us keep the arguments entirely | |
1747 ;; free for -inject-arguments -- a big win for the user and for us | |
1748 ;; since we don't have to play that double-guessing game and the user | |
1749 ;; gets full control (no gestapo'ish -f's, for instance). --sj | |
1750 message-qmail-inject-args) | |
1751 ;; qmail-inject doesn't say anything on it's stdout/stderr, | |
1752 ;; we have to look at the retval instead | |
1753 (0 nil) | |
1754 (1 (error "qmail-inject reported permanent failure.")) | |
1755 (111 (error "qmail-inject reported transient failure.")) | |
1756 ;; should never happen | |
1757 (t (error "qmail-inject reported unknown failure.")))) | |
1758 | |
1409 (defun message-send-mail-with-mh () | 1759 (defun message-send-mail-with-mh () |
1410 "Send the prepared message buffer with mh." | 1760 "Send the prepared message buffer with mh." |
1411 (let ((mh-previous-window-config nil) | 1761 (let ((mh-previous-window-config nil) |
1412 (name (make-temp-name | 1762 (name (make-temp-name |
1413 (concat (file-name-as-directory message-autosave-directory) | 1763 (concat (file-name-as-directory |
1764 (expand-file-name message-autosave-directory)) | |
1414 "msg.")))) | 1765 "msg.")))) |
1415 (setq buffer-file-name name) | 1766 (setq buffer-file-name name) |
1416 (mh-send-letter) | 1767 ;; MH wants to generate these headers itself. |
1417 (condition-case () | 1768 (when message-delete-mh-headers |
1418 (delete-file name) | 1769 (let ((headers message-deletable-headers)) |
1419 (error nil)))) | 1770 (while headers |
1771 (goto-char (point-min)) | |
1772 (and (re-search-forward | |
1773 (concat "^" (symbol-name (car headers)) ": *") nil t) | |
1774 (message-delete-line)) | |
1775 (pop headers)))) | |
1776 (run-hooks 'message-send-mail-hook) | |
1777 ;; Pass it on to mh. | |
1778 (mh-send-letter))) | |
1420 | 1779 |
1421 (defun message-send-news (&optional arg) | 1780 (defun message-send-news (&optional arg) |
1422 (let ((tembuf (generate-new-buffer " *message temp*")) | 1781 (let ((tembuf (message-generate-new-buffer-clone-locals " *message temp*")) |
1423 (case-fold-search nil) | 1782 (case-fold-search nil) |
1424 (method (if (message-functionp message-post-method) | 1783 (method (if (message-functionp message-post-method) |
1425 (funcall message-post-method arg) | 1784 (funcall message-post-method arg) |
1426 message-post-method)) | 1785 message-post-method)) |
1427 (messbuf (current-buffer)) | 1786 (messbuf (current-buffer)) |
1436 ;; Insert some headers. | 1795 ;; Insert some headers. |
1437 (message-generate-headers message-required-news-headers) | 1796 (message-generate-headers message-required-news-headers) |
1438 ;; Let the user do all of the above. | 1797 ;; Let the user do all of the above. |
1439 (run-hooks 'message-header-hook)) | 1798 (run-hooks 'message-header-hook)) |
1440 (message-cleanup-headers) | 1799 (message-cleanup-headers) |
1441 (when (message-check-news-syntax) | 1800 (if (not (message-check-news-syntax)) |
1801 (progn | |
1802 ;;(message "Posting not performed") | |
1803 nil) | |
1442 (unwind-protect | 1804 (unwind-protect |
1443 (save-excursion | 1805 (save-excursion |
1444 (set-buffer tembuf) | 1806 (set-buffer tembuf) |
1445 (buffer-disable-undo (current-buffer)) | 1807 (buffer-disable-undo (current-buffer)) |
1446 (erase-buffer) | 1808 (erase-buffer) |
1447 ;; Avoid copying text props. | 1809 ;; Avoid copying text props. |
1448 (insert (format | 1810 (insert (format |
1449 "%s" (save-excursion | 1811 "%s" (save-excursion |
1450 (set-buffer messbuf) | 1812 (set-buffer messbuf) |
1451 (buffer-string)))) | 1813 (buffer-string)))) |
1452 ;; Remove some headers. | 1814 ;; Remove some headers. |
1453 (save-restriction | 1815 (save-restriction |
1454 (message-narrow-to-headers) | 1816 (message-narrow-to-headers) |
1455 ;; Remove some headers. | 1817 ;; Remove some headers. |
1456 (message-remove-header message-ignored-news-headers t)) | 1818 (message-remove-header message-ignored-news-headers t)) |
1457 (goto-char (point-max)) | 1819 (goto-char (point-max)) |
1458 ;; require one newline at the end. | 1820 ;; require one newline at the end. |
1459 (or (= (preceding-char) ?\n) | 1821 (or (= (preceding-char) ?\n) |
1460 (insert ?\n)) | 1822 (insert ?\n)) |
1461 (let ((case-fold-search t)) | 1823 (let ((case-fold-search t)) |
1462 ;; Remove the delimeter. | 1824 ;; Remove the delimiter. |
1463 (goto-char (point-min)) | 1825 (goto-char (point-min)) |
1464 (re-search-forward | 1826 (re-search-forward |
1465 (concat "^" (regexp-quote mail-header-separator) "\n")) | 1827 (concat "^" (regexp-quote mail-header-separator) "\n")) |
1466 (replace-match "\n") | 1828 (replace-match "\n") |
1467 (backward-char 1)) | 1829 (backward-char 1)) |
1830 (run-hooks 'message-send-news-hook) | |
1468 (require (car method)) | 1831 (require (car method)) |
1469 (funcall (intern (format "%s-open-server" (car method))) | 1832 (funcall (intern (format "%s-open-server" (car method))) |
1470 (cadr method) (cddr method)) | 1833 (cadr method) (cddr method)) |
1471 (setq result | 1834 (setq result |
1472 (funcall (intern (format "%s-request-post" (car method)))))) | 1835 (funcall (intern (format "%s-request-post" (car method)))))) |
1480 | 1843 |
1481 ;;; | 1844 ;;; |
1482 ;;; Header generation & syntax checking. | 1845 ;;; Header generation & syntax checking. |
1483 ;;; | 1846 ;;; |
1484 | 1847 |
1485 (defun message-check-news-syntax () | 1848 (defmacro message-check (type &rest forms) |
1486 "Check the syntax of the message." | 1849 "Eval FORMS if TYPE is to be checked." |
1487 (and | 1850 `(or (message-check-element ,type) |
1488 ;; We narrow to the headers and check them first. | |
1489 (save-excursion | |
1490 (save-restriction | |
1491 (message-narrow-to-headers) | |
1492 (and | |
1493 ;; Check for commands in Subject. | |
1494 (or | |
1495 (message-check-element 'subject-cmsg) | |
1496 (save-excursion | |
1497 (if (string-match "^cmsg " (message-fetch-field "subject")) | |
1498 (y-or-n-p | |
1499 "The control code \"cmsg \" is in the subject. Really post? ") | |
1500 t))) | |
1501 ;; Check for multiple identical headers. | |
1502 (or (message-check-element 'multiple-headers) | |
1503 (save-excursion | |
1504 (let (found) | |
1505 (while (and (not found) | |
1506 (re-search-forward "^[^ \t:]+: " nil t)) | |
1507 (save-excursion | |
1508 (or (re-search-forward | |
1509 (concat "^" (setq found | |
1510 (buffer-substring | |
1511 (match-beginning 0) | |
1512 (- (match-end 0) 2)))) | |
1513 nil t) | |
1514 (setq found nil)))) | |
1515 (if found | |
1516 (y-or-n-p | |
1517 (format "Multiple %s headers. Really post? " found)) | |
1518 t)))) | |
1519 ;; Check for Version and Sendsys. | |
1520 (or (message-check-element 'sendsys) | |
1521 (save-excursion | |
1522 (if (re-search-forward "^Sendsys:\\|^Version:" nil t) | |
1523 (y-or-n-p | |
1524 (format "The article contains a %s command. Really post? " | |
1525 (buffer-substring (match-beginning 0) | |
1526 (1- (match-end 0))))) | |
1527 t))) | |
1528 ;; See whether we can shorten Followup-To. | |
1529 (or (message-check-element 'shorten-followup-to) | |
1530 (let ((newsgroups (message-fetch-field "newsgroups")) | |
1531 (followup-to (message-fetch-field "followup-to")) | |
1532 to) | |
1533 (when (and newsgroups (string-match "," newsgroups) | |
1534 (not followup-to) | |
1535 (not | |
1536 (zerop | |
1537 (length | |
1538 (setq to (completing-read | |
1539 "Followups to: (default all groups) " | |
1540 (mapcar (lambda (g) (list g)) | |
1541 (cons "poster" | |
1542 (message-tokenize-header | |
1543 newsgroups))))))))) | |
1544 (goto-char (point-min)) | |
1545 (insert "Followup-To: " to "\n")) | |
1546 t)) | |
1547 ;; Check "Shoot me". | |
1548 (or (message-check-element 'shoot) | |
1549 (save-excursion | |
1550 (if (re-search-forward | |
1551 "Message-ID.*.i-have-a-misconfigured-system-so-shoot-me" | |
1552 nil t) | |
1553 (y-or-n-p | |
1554 "You appear to have a misconfigured system. Really post? ") | |
1555 t))) | |
1556 ;; Check for Approved. | |
1557 (or (message-check-element 'approved) | |
1558 (save-excursion | |
1559 (if (re-search-forward "^Approved:" nil t) | |
1560 (y-or-n-p | |
1561 "The article contains an Approved header. Really post? ") | |
1562 t))) | |
1563 ;; Check the Message-Id header. | |
1564 (or (message-check-element 'message-id) | |
1565 (save-excursion | |
1566 (let* ((case-fold-search t) | |
1567 (message-id (message-fetch-field "message-id"))) | |
1568 (or (not message-id) | |
1569 (and (string-match "@" message-id) | |
1570 (string-match "@[^\\.]*\\." message-id)) | |
1571 (y-or-n-p | |
1572 (format | |
1573 "The Message-ID looks strange: \"%s\". Really post? " | |
1574 message-id)))))) | |
1575 ;; Check the Subject header. | |
1576 (or | |
1577 (message-check-element 'subject) | |
1578 (save-excursion | |
1579 (let* ((case-fold-search t) | |
1580 (subject (message-fetch-field "subject"))) | |
1581 (or | |
1582 (and subject | |
1583 (not (string-match "\\`[ \t]*\\'" subject))) | |
1584 (progn | |
1585 (message | |
1586 "The subject field is empty or missing. Posting is denied.") | |
1587 nil))))) | |
1588 ;; Check the Newsgroups & Followup-To headers. | |
1589 (or | |
1590 (message-check-element 'existing-newsgroups) | |
1591 (let* ((case-fold-search t) | |
1592 (newsgroups (message-fetch-field "newsgroups")) | |
1593 (followup-to (message-fetch-field "followup-to")) | |
1594 (groups (message-tokenize-header | |
1595 (if followup-to | |
1596 (concat newsgroups "," followup-to) | |
1597 newsgroups))) | |
1598 (hashtb (and (boundp 'gnus-active-hashtb) | |
1599 gnus-active-hashtb)) | |
1600 errors) | |
1601 (if (not hashtb) | |
1602 t | |
1603 (while groups | |
1604 (when (and (not (boundp (intern (car groups) hashtb))) | |
1605 (not (equal (car groups) "poster"))) | |
1606 (push (car groups) errors)) | |
1607 (pop groups)) | |
1608 (if (not errors) | |
1609 t | |
1610 (y-or-n-p | |
1611 (format | |
1612 "Really post to %s unknown group%s: %s " | |
1613 (if (= (length errors) 1) "this" "these") | |
1614 (if (= (length errors) 1) "" "s") | |
1615 (mapconcat 'identity errors ", "))))))) | |
1616 ;; Check the Newsgroups & Followup-To headers for syntax errors. | |
1617 (or | |
1618 (message-check-element 'valid-newsgroups) | |
1619 (let ((case-fold-search t) | |
1620 (headers '("Newsgroups" "Followup-To")) | |
1621 header error) | |
1622 (while (and headers (not error)) | |
1623 (when (setq header (mail-fetch-field (car headers))) | |
1624 (if (or | |
1625 (not | |
1626 (string-match | |
1627 "\\`\\([-+_&.a-zA-Z0-9]+\\)?\\(,[-.a-zA-Z0-9]+\\)*\\'" | |
1628 header)) | |
1629 (memq | |
1630 nil (mapcar | |
1631 (lambda (g) | |
1632 (not (string-match "\\.\\'\\|\\.\\." g))) | |
1633 (message-tokenize-header header ",")))) | |
1634 (setq error t))) | |
1635 (unless error | |
1636 (pop headers))) | |
1637 (if (not error) | |
1638 t | |
1639 (y-or-n-p | |
1640 (format "The %s header looks odd: \"%s\". Really post? " | |
1641 (car headers) header))))) | |
1642 ;; Check the From header. | |
1643 (or | |
1644 (save-excursion | |
1645 (let* ((case-fold-search t) | |
1646 (from (message-fetch-field "from"))) | |
1647 (cond | |
1648 ((not from) | |
1649 (message "There is no From line. Posting is denied.") | |
1650 nil) | |
1651 ((not (string-match "@[^\\.]*\\." from)) | |
1652 (message | |
1653 "Denied posting -- the From looks strange: \"%s\"." from) | |
1654 nil) | |
1655 ((string-match "@[^@]*@" from) | |
1656 (message | |
1657 "Denied posting -- two \"@\"'s in the From header: %s." from) | |
1658 nil) | |
1659 ((string-match "(.*).*(.*)" from) | |
1660 (message | |
1661 "Denied posting -- the From header looks strange: \"%s\"." | |
1662 from) | |
1663 nil) | |
1664 (t t)))))))) | |
1665 ;; Check for long lines. | |
1666 (or (message-check-element 'long-lines) | |
1667 (save-excursion | 1851 (save-excursion |
1668 (goto-char (point-min)) | 1852 ,@forms))) |
1669 (re-search-forward | 1853 |
1670 (concat "^" (regexp-quote mail-header-separator) "$")) | 1854 (put 'message-check 'lisp-indent-function 1) |
1671 (while (and | 1855 (put 'message-check 'edebug-form-spec '(form body)) |
1672 (progn | |
1673 (end-of-line) | |
1674 (< (current-column) 80)) | |
1675 (zerop (forward-line 1)))) | |
1676 (or (bolp) | |
1677 (eobp) | |
1678 (y-or-n-p | |
1679 "You have lines longer than 79 characters. Really post? ")))) | |
1680 ;; Check whether the article is empty. | |
1681 (or (message-check-element 'empty) | |
1682 (save-excursion | |
1683 (goto-char (point-min)) | |
1684 (re-search-forward | |
1685 (concat "^" (regexp-quote mail-header-separator) "$")) | |
1686 (forward-line 1) | |
1687 (let ((b (point))) | |
1688 (goto-char (point-max)) | |
1689 (re-search-backward message-signature-separator nil t) | |
1690 (beginning-of-line) | |
1691 (or (re-search-backward "[^ \n\t]" b t) | |
1692 (y-or-n-p "Empty article. Really post? "))))) | |
1693 ;; Check for control characters. | |
1694 (or (message-check-element 'control-chars) | |
1695 (save-excursion | |
1696 (if (re-search-forward "[\000-\007\013\015-\037\200-\237]" nil t) | |
1697 (y-or-n-p | |
1698 "The article contains control characters. Really post? ") | |
1699 t))) | |
1700 ;; Check excessive size. | |
1701 (or (message-check-element 'size) | |
1702 (if (> (buffer-size) 60000) | |
1703 (y-or-n-p | |
1704 (format "The article is %d octets long. Really post? " | |
1705 (buffer-size))) | |
1706 t)) | |
1707 ;; Check whether any new text has been added. | |
1708 (or (message-check-element 'new-text) | |
1709 (not message-checksum) | |
1710 (not (and (eq (message-checksum) (car message-checksum)) | |
1711 (eq (buffer-size) (cdr message-checksum)))) | |
1712 (y-or-n-p | |
1713 "It looks like no new text has been added. Really post? ")) | |
1714 ;; Check the length of the signature. | |
1715 (or | |
1716 (message-check-element 'signature) | |
1717 (progn | |
1718 (goto-char (point-max)) | |
1719 (if (or (not (re-search-backward message-signature-separator nil t)) | |
1720 (search-forward message-forward-end-separator nil t)) | |
1721 t | |
1722 (if (> (count-lines (point) (point-max)) 5) | |
1723 (y-or-n-p | |
1724 (format | |
1725 "Your .sig is %d lines; it should be max 4. Really post? " | |
1726 (count-lines (point) (point-max)))) | |
1727 t)))))) | |
1728 | 1856 |
1729 (defun message-check-element (type) | 1857 (defun message-check-element (type) |
1730 "Returns non-nil if this type is not to be checked." | 1858 "Returns non-nil if this type is not to be checked." |
1731 (if (eq message-syntax-checks 'dont-check-for-anything-just-trust-me) | 1859 (if (eq message-syntax-checks 'dont-check-for-anything-just-trust-me) |
1732 t | 1860 t |
1733 (let ((able (assq type message-syntax-checks))) | 1861 (let ((able (assq type message-syntax-checks))) |
1734 (and (consp able) | 1862 (and (consp able) |
1735 (eq (cdr able) 'disabled))))) | 1863 (eq (cdr able) 'disabled))))) |
1864 | |
1865 (defun message-check-news-syntax () | |
1866 "Check the syntax of the message." | |
1867 (save-excursion | |
1868 (save-restriction | |
1869 (widen) | |
1870 (and | |
1871 ;; We narrow to the headers and check them first. | |
1872 (save-excursion | |
1873 (save-restriction | |
1874 (message-narrow-to-headers) | |
1875 (message-check-news-header-syntax))) | |
1876 ;; Check the body. | |
1877 (message-check-news-body-syntax))))) | |
1878 | |
1879 (defun message-check-news-header-syntax () | |
1880 (and | |
1881 ;; Check for commands in Subject. | |
1882 (message-check 'subject-cmsg | |
1883 (if (string-match "^cmsg " (message-fetch-field "subject")) | |
1884 (y-or-n-p | |
1885 "The control code \"cmsg\" is in the subject. Really post? ") | |
1886 t)) | |
1887 ;; Check for multiple identical headers. | |
1888 (message-check 'multiple-headers | |
1889 (let (found) | |
1890 (while (and (not found) | |
1891 (re-search-forward "^[^ \t:]+: " nil t)) | |
1892 (save-excursion | |
1893 (or (re-search-forward | |
1894 (concat "^" | |
1895 (regexp-quote | |
1896 (setq found | |
1897 (buffer-substring | |
1898 (match-beginning 0) (- (match-end 0) 2)))) | |
1899 ":") | |
1900 nil t) | |
1901 (setq found nil)))) | |
1902 (if found | |
1903 (y-or-n-p (format "Multiple %s headers. Really post? " found)) | |
1904 t))) | |
1905 ;; Check for Version and Sendsys. | |
1906 (message-check 'sendsys | |
1907 (if (re-search-forward "^Sendsys:\\|^Version:" nil t) | |
1908 (y-or-n-p | |
1909 (format "The article contains a %s command. Really post? " | |
1910 (buffer-substring (match-beginning 0) | |
1911 (1- (match-end 0))))) | |
1912 t)) | |
1913 ;; See whether we can shorten Followup-To. | |
1914 (message-check 'shorten-followup-to | |
1915 (let ((newsgroups (message-fetch-field "newsgroups")) | |
1916 (followup-to (message-fetch-field "followup-to")) | |
1917 to) | |
1918 (when (and newsgroups | |
1919 (string-match "," newsgroups) | |
1920 (not followup-to) | |
1921 (not | |
1922 (zerop | |
1923 (length | |
1924 (setq to (completing-read | |
1925 "Followups to: (default all groups) " | |
1926 (mapcar (lambda (g) (list g)) | |
1927 (cons "poster" | |
1928 (message-tokenize-header | |
1929 newsgroups))))))))) | |
1930 (goto-char (point-min)) | |
1931 (insert "Followup-To: " to "\n")) | |
1932 t)) | |
1933 ;; Check "Shoot me". | |
1934 (message-check 'shoot | |
1935 (if (re-search-forward | |
1936 "Message-ID.*.i-did-not-set--mail-host-address--so-shoot-me" nil t) | |
1937 (y-or-n-p "You appear to have a misconfigured system. Really post? ") | |
1938 t)) | |
1939 ;; Check for Approved. | |
1940 (message-check 'approved | |
1941 (if (re-search-forward "^Approved:" nil t) | |
1942 (y-or-n-p "The article contains an Approved header. Really post? ") | |
1943 t)) | |
1944 ;; Check the Message-ID header. | |
1945 (message-check 'message-id | |
1946 (let* ((case-fold-search t) | |
1947 (message-id (message-fetch-field "message-id"))) | |
1948 (or (not message-id) | |
1949 (and (string-match "@" message-id) | |
1950 (string-match "@[^\\.]*\\." message-id)) | |
1951 (y-or-n-p | |
1952 (format "The Message-ID looks strange: \"%s\". Really post? " | |
1953 message-id))))) | |
1954 ;; Check the Subject header. | |
1955 (message-check 'subject | |
1956 (let* ((case-fold-search t) | |
1957 (subject (message-fetch-field "subject"))) | |
1958 (or | |
1959 (and subject | |
1960 (not (string-match "\\`[ \t]*\\'" subject))) | |
1961 (ignore | |
1962 (message | |
1963 "The subject field is empty or missing. Posting is denied."))))) | |
1964 ;; Check the Newsgroups & Followup-To headers. | |
1965 (message-check 'existing-newsgroups | |
1966 (let* ((case-fold-search t) | |
1967 (newsgroups (message-fetch-field "newsgroups")) | |
1968 (followup-to (message-fetch-field "followup-to")) | |
1969 (groups (message-tokenize-header | |
1970 (if followup-to | |
1971 (concat newsgroups "," followup-to) | |
1972 newsgroups))) | |
1973 (hashtb (and (boundp 'gnus-active-hashtb) | |
1974 gnus-active-hashtb)) | |
1975 errors) | |
1976 (if (or (not hashtb) | |
1977 (not (boundp 'gnus-read-active-file)) | |
1978 (not gnus-read-active-file) | |
1979 (eq gnus-read-active-file 'some)) | |
1980 t | |
1981 (while groups | |
1982 (when (and (not (boundp (intern (car groups) hashtb))) | |
1983 (not (equal (car groups) "poster"))) | |
1984 (push (car groups) errors)) | |
1985 (pop groups)) | |
1986 (if (not errors) | |
1987 t | |
1988 (y-or-n-p | |
1989 (format | |
1990 "Really post to %s unknown group%s: %s " | |
1991 (if (= (length errors) 1) "this" "these") | |
1992 (if (= (length errors) 1) "" "s") | |
1993 (mapconcat 'identity errors ", "))))))) | |
1994 ;; Check the Newsgroups & Followup-To headers for syntax errors. | |
1995 (message-check 'valid-newsgroups | |
1996 (let ((case-fold-search t) | |
1997 (headers '("Newsgroups" "Followup-To")) | |
1998 header error) | |
1999 (while (and headers (not error)) | |
2000 (when (setq header (mail-fetch-field (car headers))) | |
2001 (if (or | |
2002 (not | |
2003 (string-match | |
2004 "\\`\\([-+_&.a-zA-Z0-9]+\\)?\\(,[-+_&.a-zA-Z0-9]+\\)*\\'" | |
2005 header)) | |
2006 (memq | |
2007 nil (mapcar | |
2008 (lambda (g) | |
2009 (not (string-match "\\.\\'\\|\\.\\." g))) | |
2010 (message-tokenize-header header ",")))) | |
2011 (setq error t))) | |
2012 (unless error | |
2013 (pop headers))) | |
2014 (if (not error) | |
2015 t | |
2016 (y-or-n-p | |
2017 (format "The %s header looks odd: \"%s\". Really post? " | |
2018 (car headers) header))))) | |
2019 ;; Check the From header. | |
2020 (message-check 'from | |
2021 (let* ((case-fold-search t) | |
2022 (from (message-fetch-field "from")) | |
2023 (ad (nth 1 (mail-extract-address-components from)))) | |
2024 (cond | |
2025 ((not from) | |
2026 (message "There is no From line. Posting is denied.") | |
2027 nil) | |
2028 ((or (not (string-match "@[^\\.]*\\." ad)) ;larsi@ifi | |
2029 (string-match "\\.\\." ad) ;larsi@ifi..uio | |
2030 (string-match "@\\." ad) ;larsi@.ifi.uio | |
2031 (string-match "\\.$" ad) ;larsi@ifi.uio. | |
2032 (not (string-match "^[^@]+@[^@]+$" ad)) ;larsi.ifi.uio | |
2033 (string-match "(.*).*(.*)" from)) ;(lars) (lars) | |
2034 (message | |
2035 "Denied posting -- the From looks strange: \"%s\"." from) | |
2036 nil) | |
2037 (t t)))))) | |
2038 | |
2039 (defun message-check-news-body-syntax () | |
2040 (and | |
2041 ;; Check for long lines. | |
2042 (message-check 'long-lines | |
2043 (goto-char (point-min)) | |
2044 (re-search-forward | |
2045 (concat "^" (regexp-quote mail-header-separator) "$")) | |
2046 (while (and | |
2047 (progn | |
2048 (end-of-line) | |
2049 (< (current-column) 80)) | |
2050 (zerop (forward-line 1)))) | |
2051 (or (bolp) | |
2052 (eobp) | |
2053 (y-or-n-p | |
2054 "You have lines longer than 79 characters. Really post? "))) | |
2055 ;; Check whether the article is empty. | |
2056 (message-check 'empty | |
2057 (goto-char (point-min)) | |
2058 (re-search-forward | |
2059 (concat "^" (regexp-quote mail-header-separator) "$")) | |
2060 (forward-line 1) | |
2061 (let ((b (point))) | |
2062 (goto-char (point-max)) | |
2063 (re-search-backward message-signature-separator nil t) | |
2064 (beginning-of-line) | |
2065 (or (re-search-backward "[^ \n\t]" b t) | |
2066 (y-or-n-p "Empty article. Really post? ")))) | |
2067 ;; Check for control characters. | |
2068 (message-check 'control-chars | |
2069 (if (re-search-forward "[\000-\007\013\015-\037\200-\237]" nil t) | |
2070 (y-or-n-p | |
2071 "The article contains control characters. Really post? ") | |
2072 t)) | |
2073 ;; Check excessive size. | |
2074 (message-check 'size | |
2075 (if (> (buffer-size) 60000) | |
2076 (y-or-n-p | |
2077 (format "The article is %d octets long. Really post? " | |
2078 (buffer-size))) | |
2079 t)) | |
2080 ;; Check whether any new text has been added. | |
2081 (message-check 'new-text | |
2082 (or | |
2083 (not message-checksum) | |
2084 (not (and (eq (message-checksum) (car message-checksum)) | |
2085 (eq (buffer-size) (cdr message-checksum)))) | |
2086 (y-or-n-p | |
2087 "It looks like no new text has been added. Really post? "))) | |
2088 ;; Check the length of the signature. | |
2089 (message-check 'signature | |
2090 (goto-char (point-max)) | |
2091 (if (or (not (re-search-backward message-signature-separator nil t)) | |
2092 (search-forward message-forward-end-separator nil t)) | |
2093 t | |
2094 (if (> (count-lines (point) (point-max)) 5) | |
2095 (y-or-n-p | |
2096 (format | |
2097 "Your .sig is %d lines; it should be max 4. Really post? " | |
2098 (1- (count-lines (point) (point-max))))) | |
2099 t))))) | |
1736 | 2100 |
1737 (defun message-checksum () | 2101 (defun message-checksum () |
1738 "Return a \"checksum\" for the current buffer." | 2102 "Return a \"checksum\" for the current buffer." |
1739 (let ((sum 0)) | 2103 (let ((sum 0)) |
1740 (save-excursion | 2104 (save-excursion |
1775 (match-string 1 file)) | 2139 (match-string 1 file)) |
1776 ;; Save the article. | 2140 ;; Save the article. |
1777 (setq file (expand-file-name file)) | 2141 (setq file (expand-file-name file)) |
1778 (unless (file-exists-p (file-name-directory file)) | 2142 (unless (file-exists-p (file-name-directory file)) |
1779 (make-directory (file-name-directory file) t)) | 2143 (make-directory (file-name-directory file) t)) |
1780 (if (and message-fcc-handler-function | 2144 (funcall message-fcc-handler-function file))) |
1781 (not (eq message-fcc-handler-function 'rmail-output))) | 2145 |
1782 (funcall message-fcc-handler-function file) | |
1783 (if (and (file-readable-p file) (mail-file-babyl-p file)) | |
1784 (rmail-output file 1 nil t) | |
1785 (let ((mail-use-rfc822 t)) | |
1786 (rmail-output file 1 t t)))))) | |
1787 (kill-buffer (current-buffer))))) | 2146 (kill-buffer (current-buffer))))) |
2147 | |
2148 (defun message-output (filename) | |
2149 "Append this article to Unix/babyl mail file.." | |
2150 (if (and (file-readable-p filename) | |
2151 (mail-file-babyl-p filename)) | |
2152 (gnus-output-to-rmail filename t) | |
2153 (gnus-output-to-mail filename t))) | |
1788 | 2154 |
1789 (defun message-cleanup-headers () | 2155 (defun message-cleanup-headers () |
1790 "Do various automatic cleanups of the headers." | 2156 "Do various automatic cleanups of the headers." |
1791 ;; Remove empty lines in the header. | 2157 ;; Remove empty lines in the header. |
1792 (save-restriction | 2158 (save-restriction |
2001 ;; ... then undo escaping of matching parentheses, | 2367 ;; ... then undo escaping of matching parentheses, |
2002 ;; including matching nested parentheses. | 2368 ;; including matching nested parentheses. |
2003 (goto-char fullname-start) | 2369 (goto-char fullname-start) |
2004 (while (re-search-forward | 2370 (while (re-search-forward |
2005 "\\(\\=\\|[^\\]\\(\\\\\\\\\\)*\\)\\\\(\\(\\([^\\]\\|\\\\\\\\\\)*\\)\\\\)" | 2371 "\\(\\=\\|[^\\]\\(\\\\\\\\\\)*\\)\\\\(\\(\\([^\\]\\|\\\\\\\\\\)*\\)\\\\)" |
2006 nil 1) | 2372 nil 1) |
2007 (replace-match "\\1(\\3)" t) | 2373 (replace-match "\\1(\\3)" t) |
2008 (goto-char fullname-start))) | 2374 (goto-char fullname-start))) |
2009 (insert ")"))) | 2375 (insert ")"))) |
2010 (buffer-string)))) | 2376 (buffer-string)))) |
2011 | 2377 |
2021 (concat (user-login-name) "@" (message-make-domain)))) | 2387 (concat (user-login-name) "@" (message-make-domain)))) |
2022 | 2388 |
2023 (defun message-user-mail-address () | 2389 (defun message-user-mail-address () |
2024 "Return the pertinent part of `user-mail-address'." | 2390 "Return the pertinent part of `user-mail-address'." |
2025 (when user-mail-address | 2391 (when user-mail-address |
2026 (nth 1 (mail-extract-address-components user-mail-address)))) | 2392 (if (string-match " " user-mail-address) |
2393 (nth 1 (mail-extract-address-components user-mail-address)) | |
2394 user-mail-address))) | |
2027 | 2395 |
2028 (defun message-make-fqdn () | 2396 (defun message-make-fqdn () |
2029 "Return user's fully qualified domain name." | 2397 "Return user's fully qualified domain name." |
2030 (let ((system-name (system-name)) | 2398 (let ((system-name (system-name)) |
2031 (user-mail (message-user-mail-address))) | 2399 (user-mail (message-user-mail-address))) |
2042 ((and (string-match "\\." user-mail) | 2410 ((and (string-match "\\." user-mail) |
2043 (string-match "@\\(.*\\)\\'" user-mail)) | 2411 (string-match "@\\(.*\\)\\'" user-mail)) |
2044 (match-string 1 user-mail)) | 2412 (match-string 1 user-mail)) |
2045 ;; Default to this bogus thing. | 2413 ;; Default to this bogus thing. |
2046 (t | 2414 (t |
2047 (concat system-name ".i-have-a-misconfigured-system-so-shoot-me"))))) | 2415 (concat system-name ".i-did-not-set--mail-host-address--so-shoot-me"))))) |
2048 | 2416 |
2049 (defun message-make-host-name () | 2417 (defun message-make-host-name () |
2050 "Return the name of the host." | 2418 "Return the name of the host." |
2051 (let ((fqdn (message-make-fqdn))) | 2419 (let ((fqdn (message-make-fqdn))) |
2052 (string-match "^[^.]+\\." fqdn) | 2420 (string-match "^[^.]+\\." fqdn) |
2087 (concat "^" (symbol-name (car headers)) ": *") nil t) | 2455 (concat "^" (symbol-name (car headers)) ": *") nil t) |
2088 (get-text-property (1+ (match-beginning 0)) 'message-deletable) | 2456 (get-text-property (1+ (match-beginning 0)) 'message-deletable) |
2089 (message-delete-line)) | 2457 (message-delete-line)) |
2090 (pop headers))) | 2458 (pop headers))) |
2091 ;; Go through all the required headers and see if they are in the | 2459 ;; Go through all the required headers and see if they are in the |
2092 ;; articles already. If they are not, or are empty, they are | 2460 ;; articles already. If they are not, or are empty, they are |
2093 ;; inserted automatically - except for Subject, Newsgroups and | 2461 ;; inserted automatically - except for Subject, Newsgroups and |
2094 ;; Distribution. | 2462 ;; Distribution. |
2095 (while headers | 2463 (while headers |
2096 (goto-char (point-min)) | 2464 (goto-char (point-min)) |
2097 (setq elem (pop headers)) | 2465 (setq elem (pop headers)) |
2102 (setq header elem)) | 2470 (setq header elem)) |
2103 (when (or (not (re-search-forward | 2471 (when (or (not (re-search-forward |
2104 (concat "^" (downcase (symbol-name header)) ":") | 2472 (concat "^" (downcase (symbol-name header)) ":") |
2105 nil t)) | 2473 nil t)) |
2106 (progn | 2474 (progn |
2107 ;; The header was found. We insert a space after the | 2475 ;; The header was found. We insert a space after the |
2108 ;; colon, if there is none. | 2476 ;; colon, if there is none. |
2109 (if (/= (following-char) ? ) (insert " ") (forward-char 1)) | 2477 (if (/= (following-char) ? ) (insert " ") (forward-char 1)) |
2110 ;; Find out whether the header is empty... | 2478 ;; Find out whether the header is empty... |
2111 (looking-at "[ \t]*$"))) | 2479 (looking-at "[ \t]*$"))) |
2112 ;; So we find out what value we should insert. | 2480 ;; So we find out what value we should insert. |
2171 (downcase | 2539 (downcase |
2172 (cadr (mail-extract-address-components sender))) | 2540 (cadr (mail-extract-address-components sender))) |
2173 (downcase secure-sender))))) | 2541 (downcase secure-sender))))) |
2174 (goto-char (point-min)) | 2542 (goto-char (point-min)) |
2175 ;; Rename any old Sender headers to Original-Sender. | 2543 ;; Rename any old Sender headers to Original-Sender. |
2176 (when (re-search-forward "^Sender:" nil t) | 2544 (when (re-search-forward "^\\(Original-\\)*Sender:" nil t) |
2177 (beginning-of-line) | 2545 (beginning-of-line) |
2178 (insert "Original-") | 2546 (insert "Original-") |
2179 (beginning-of-line)) | 2547 (beginning-of-line)) |
2180 (insert "Sender: " secure-sender "\n")))))) | 2548 (insert "Sender: " secure-sender "\n")))))) |
2181 | 2549 |
2182 (defun message-insert-courtesy-copy () | 2550 (defun message-insert-courtesy-copy () |
2183 "Insert a courtesy message in mail copies of combined messages." | 2551 "Insert a courtesy message in mail copies of combined messages." |
2184 (save-excursion | 2552 (let (newsgroups) |
2185 (save-restriction | 2553 (save-excursion |
2186 (message-narrow-to-headers) | 2554 (save-restriction |
2187 (let ((newsgroups (message-fetch-field "newsgroups"))) | 2555 (message-narrow-to-headers) |
2188 (when newsgroups | 2556 (when (setq newsgroups (message-fetch-field "newsgroups")) |
2189 (goto-char (point-max)) | 2557 (goto-char (point-max)) |
2190 (insert "Posted-To: " newsgroups "\n")))) | 2558 (insert "Posted-To: " newsgroups "\n"))) |
2191 (forward-line 1) | 2559 (forward-line 1) |
2192 (insert message-courtesy-message))) | 2560 (when message-courtesy-message |
2561 (cond | |
2562 ((string-match "%s" message-courtesy-message) | |
2563 (insert (format message-courtesy-message newsgroups))) | |
2564 (t | |
2565 (insert message-courtesy-message))))))) | |
2193 | 2566 |
2194 ;;; | 2567 ;;; |
2195 ;;; Setting up a message buffer | 2568 ;;; Setting up a message buffer |
2196 ;;; | 2569 ;;; |
2197 | 2570 |
2306 "Kill old message buffers." | 2679 "Kill old message buffers." |
2307 ;; We might have sent this buffer already. Delete it from the | 2680 ;; We might have sent this buffer already. Delete it from the |
2308 ;; list of buffers. | 2681 ;; list of buffers. |
2309 (setq message-buffer-list (delq (current-buffer) message-buffer-list)) | 2682 (setq message-buffer-list (delq (current-buffer) message-buffer-list)) |
2310 (while (and message-max-buffers | 2683 (while (and message-max-buffers |
2684 message-buffer-list | |
2311 (>= (length message-buffer-list) message-max-buffers)) | 2685 (>= (length message-buffer-list) message-max-buffers)) |
2312 ;; Kill the oldest buffer -- unless it has been changed. | 2686 ;; Kill the oldest buffer -- unless it has been changed. |
2313 (let ((buffer (pop message-buffer-list))) | 2687 (let ((buffer (pop message-buffer-list))) |
2314 (when (and (buffer-name buffer) | 2688 (when (and (buffer-name buffer) |
2315 (not (buffer-modified-p buffer))) | 2689 (not (buffer-modified-p buffer))) |
2406 ;;; | 2780 ;;; |
2407 ;;; Commands for interfacing with message | 2781 ;;; Commands for interfacing with message |
2408 ;;; | 2782 ;;; |
2409 | 2783 |
2410 ;;;###autoload | 2784 ;;;###autoload |
2411 (defun message-mail (&optional to subject) | 2785 (defun message-mail (&optional to subject |
2786 other-headers continue switch-function | |
2787 yank-action send-actions) | |
2412 "Start editing a mail message to be sent." | 2788 "Start editing a mail message to be sent." |
2413 (interactive) | 2789 (interactive) |
2414 (message-pop-to-buffer (message-buffer-name "mail" to)) | 2790 (let ((message-this-is-mail t)) |
2415 (message-setup `((To . ,(or to "")) (Subject . ,(or subject ""))))) | 2791 (message-pop-to-buffer (message-buffer-name "mail" to)) |
2792 (message-setup | |
2793 (nconc | |
2794 `((To . ,(or to "")) (Subject . ,(or subject ""))) | |
2795 (when other-headers (list other-headers)))))) | |
2416 | 2796 |
2417 ;;;###autoload | 2797 ;;;###autoload |
2418 (defun message-news (&optional newsgroups subject) | 2798 (defun message-news (&optional newsgroups subject) |
2419 "Start editing a news article to be sent." | 2799 "Start editing a news article to be sent." |
2420 (interactive) | 2800 (interactive) |
2421 (message-pop-to-buffer (message-buffer-name "news" nil newsgroups)) | 2801 (let ((message-this-is-news t)) |
2422 (message-setup `((Newsgroups . ,(or newsgroups "")) | 2802 (message-pop-to-buffer (message-buffer-name "news" nil newsgroups)) |
2423 (Subject . ,(or subject ""))))) | 2803 (message-setup `((Newsgroups . ,(or newsgroups "")) |
2804 (Subject . ,(or subject "")))))) | |
2424 | 2805 |
2425 ;;;###autoload | 2806 ;;;###autoload |
2426 (defun message-reply (&optional to-address wide ignore-reply-to) | 2807 (defun message-reply (&optional to-address wide ignore-reply-to) |
2427 "Start editing a reply to the article in the current buffer." | 2808 "Start editing a reply to the article in the current buffer." |
2428 (interactive) | 2809 (interactive) |
2430 from subject date reply-to to cc | 2811 from subject date reply-to to cc |
2431 references message-id follow-to | 2812 references message-id follow-to |
2432 (inhibit-point-motion-hooks t) | 2813 (inhibit-point-motion-hooks t) |
2433 mct never-mct gnus-warning) | 2814 mct never-mct gnus-warning) |
2434 (save-restriction | 2815 (save-restriction |
2435 (narrow-to-region | 2816 (message-narrow-to-head) |
2436 (goto-char (point-min)) | |
2437 (if (search-forward "\n\n" nil t) | |
2438 (1- (point)) | |
2439 (point-max))) | |
2440 ;; Allow customizations to have their say. | 2817 ;; Allow customizations to have their say. |
2441 (if (not wide) | 2818 (if (not wide) |
2442 ;; This is a regular reply. | 2819 ;; This is a regular reply. |
2443 (if (message-functionp message-reply-to-function) | 2820 (if (message-functionp message-reply-to-function) |
2444 (setq follow-to (funcall message-reply-to-function))) | 2821 (setq follow-to (funcall message-reply-to-function))) |
2499 (let ((s ccalist)) | 2876 (let ((s ccalist)) |
2500 (while s | 2877 (while s |
2501 (setq ccalist (delq (assoc (car (pop s)) s) ccalist))))) | 2878 (setq ccalist (delq (assoc (car (pop s)) s) ccalist))))) |
2502 (setq follow-to (list (cons 'To (cdr (pop ccalist))))) | 2879 (setq follow-to (list (cons 'To (cdr (pop ccalist))))) |
2503 (when ccalist | 2880 (when ccalist |
2504 (push (cons 'Cc | 2881 (let ((ccs (cons 'Cc (mapconcat |
2505 (mapconcat (lambda (addr) (cdr addr)) ccalist ", ")) | 2882 (lambda (addr) (cdr addr)) ccalist ", ")))) |
2506 follow-to))))) | 2883 (when (string-match "^ +" (cdr ccs)) |
2884 (setcdr ccs (substring (cdr ccs) (match-end 0)))) | |
2885 (push ccs follow-to)))))) | |
2507 (widen)) | 2886 (widen)) |
2508 | 2887 |
2509 (message-pop-to-buffer (message-buffer-name | 2888 (message-pop-to-buffer (message-buffer-name |
2510 (if wide "wide reply" "reply") from | 2889 (if wide "wide reply" "reply") from |
2511 (if wide to-address nil))) | 2890 (if wide to-address nil))) |
2522 nil)) | 2901 nil)) |
2523 cur))) | 2902 cur))) |
2524 | 2903 |
2525 ;;;###autoload | 2904 ;;;###autoload |
2526 (defun message-wide-reply (&optional to-address) | 2905 (defun message-wide-reply (&optional to-address) |
2906 "Make a \"wide\" reply to the message in the current buffer." | |
2527 (interactive) | 2907 (interactive) |
2528 (message-reply to-address t)) | 2908 (message-reply to-address t)) |
2529 | 2909 |
2530 ;;;###autoload | 2910 ;;;###autoload |
2531 (defun message-followup () | 2911 (defun message-followup (&optional to-newsgroups) |
2912 "Follow up to the message in the current buffer. | |
2913 If TO-NEWSGROUPS, use that as the new Newsgroups line." | |
2532 (interactive) | 2914 (interactive) |
2533 (let ((cur (current-buffer)) | 2915 (let ((cur (current-buffer)) |
2534 from subject date reply-to mct | 2916 from subject date reply-to mct |
2535 references message-id follow-to | 2917 references message-id follow-to |
2536 (inhibit-point-motion-hooks t) | 2918 (inhibit-point-motion-hooks t) |
2919 (message-this-is-news t) | |
2537 followup-to distribution newsgroups gnus-warning) | 2920 followup-to distribution newsgroups gnus-warning) |
2538 (save-restriction | 2921 (save-restriction |
2539 (narrow-to-region | 2922 (narrow-to-region |
2540 (goto-char (point-min)) | 2923 (goto-char (point-min)) |
2541 (if (search-forward "\n\n" nil t) | 2924 (if (search-forward "\n\n" nil t) |
2556 mct (message-fetch-field "mail-copies-to")) | 2939 mct (message-fetch-field "mail-copies-to")) |
2557 (when (and (setq gnus-warning (message-fetch-field "gnus-warning")) | 2940 (when (and (setq gnus-warning (message-fetch-field "gnus-warning")) |
2558 (string-match "<[^>]+>" gnus-warning)) | 2941 (string-match "<[^>]+>" gnus-warning)) |
2559 (setq message-id (match-string 0 gnus-warning))) | 2942 (setq message-id (match-string 0 gnus-warning))) |
2560 ;; Remove bogus distribution. | 2943 ;; Remove bogus distribution. |
2561 (and (stringp distribution) | 2944 (when (and (stringp distribution) |
2562 (string-match "world" distribution) | 2945 (let ((case-fold-search t)) |
2563 (setq distribution nil)) | 2946 (string-match "world" distribution))) |
2947 (setq distribution nil)) | |
2564 ;; Remove any (buggy) Re:'s that are present and make a | 2948 ;; Remove any (buggy) Re:'s that are present and make a |
2565 ;; proper one. | 2949 ;; proper one. |
2566 (when (string-match "^[ \t]*[Rr][Ee]:[ \t]*" subject) | 2950 (when (string-match "^[ \t]*[Rr][Ee]:[ \t]*" subject) |
2567 (setq subject (substring subject (match-end 0)))) | 2951 (setq subject (substring subject (match-end 0)))) |
2568 (setq subject (concat "Re: " subject)) | 2952 (setq subject (concat "Re: " subject)) |
2571 (message-pop-to-buffer (message-buffer-name "followup" from newsgroups)) | 2955 (message-pop-to-buffer (message-buffer-name "followup" from newsgroups)) |
2572 | 2956 |
2573 (message-setup | 2957 (message-setup |
2574 `((Subject . ,subject) | 2958 `((Subject . ,subject) |
2575 ,@(cond | 2959 ,@(cond |
2960 (to-newsgroups | |
2961 (list (cons 'Newsgroups to-newsgroups))) | |
2576 (follow-to follow-to) | 2962 (follow-to follow-to) |
2577 ((and followup-to message-use-followup-to) | 2963 ((and followup-to message-use-followup-to) |
2578 (list | 2964 (list |
2579 (cond | 2965 (cond |
2580 ((equal (downcase followup-to) "poster") | 2966 ((equal (downcase followup-to) "poster") |
2603 If a message is posted to several newsgroups, Followup-To is often | 2989 If a message is posted to several newsgroups, Followup-To is often |
2604 used to direct the following discussion to one newsgroup only, | 2990 used to direct the following discussion to one newsgroup only, |
2605 because discussions that are spread over several newsgroup tend to | 2991 because discussions that are spread over several newsgroup tend to |
2606 be fragmented and very difficult to follow. | 2992 be fragmented and very difficult to follow. |
2607 | 2993 |
2608 Also, some source/announcment newsgroups are not indented for discussion; | 2994 Also, some source/announcement newsgroups are not indented for discussion; |
2609 responses here are directed to other newsgroups.")) | 2995 responses here are directed to other newsgroups.")) |
2610 (cons 'Newsgroups followup-to) | 2996 (cons 'Newsgroups followup-to) |
2611 (cons 'Newsgroups newsgroups)))))) | 2997 (cons 'Newsgroups newsgroups)))))) |
2612 (t | 2998 (t |
2613 `((Newsgroups . ,newsgroups)))) | 2999 `((Newsgroups . ,newsgroups)))) |
2614 ,@(and distribution (list (cons 'Distribution distribution))) | 3000 ,@(and distribution (list (cons 'Distribution distribution))) |
2615 (References . ,(concat (or references "") (and references " ") | 3001 ,@(if (or references message-id) |
2616 (or message-id ""))) | 3002 `((References . ,(concat (or references "") (and references " ") |
3003 (or message-id ""))))) | |
2617 ,@(when (and mct | 3004 ,@(when (and mct |
2618 (not (equal (downcase mct) "never"))) | 3005 (not (equal (downcase mct) "never"))) |
2619 (list (cons 'Cc (if (equal (downcase mct) "always") | 3006 (list (cons 'Cc (if (equal (downcase mct) "always") |
2620 (or reply-to from "") | 3007 (or reply-to from "") |
2621 mct))))) | 3008 mct))))) |
2657 "Control: cancel " message-id "\n" | 3044 "Control: cancel " message-id "\n" |
2658 (if distribution | 3045 (if distribution |
2659 (concat "Distribution: " distribution "\n") | 3046 (concat "Distribution: " distribution "\n") |
2660 "") | 3047 "") |
2661 mail-header-separator "\n" | 3048 mail-header-separator "\n" |
2662 "This is a cancel message from " from ".\n") | 3049 message-cancel-message) |
2663 (message "Canceling your article...") | 3050 (message "Canceling your article...") |
2664 (let ((message-syntax-checks 'dont-check-for-anything-just-trust-me)) | 3051 (let ((message-syntax-checks 'dont-check-for-anything-just-trust-me)) |
2665 (funcall message-send-news-function)) | 3052 (funcall message-send-news-function)) |
2666 (message "Canceling your article...done") | 3053 (message "Canceling your article...done") |
2667 (kill-buffer buf))))) | 3054 (kill-buffer buf))))) |
2715 | 3102 |
2716 ;;; Forwarding messages. | 3103 ;;; Forwarding messages. |
2717 | 3104 |
2718 (defun message-make-forward-subject () | 3105 (defun message-make-forward-subject () |
2719 "Return a Subject header suitable for the message in the current buffer." | 3106 "Return a Subject header suitable for the message in the current buffer." |
2720 (concat "[" (or (message-fetch-field (if (message-news-p) "newsgroups" "from")) | 3107 (save-excursion |
2721 "(nowhere)") | 3108 (save-restriction |
2722 "] " (or (message-fetch-field "Subject") ""))) | 3109 (current-buffer) |
3110 (message-narrow-to-head) | |
3111 (concat "[" (or (message-fetch-field | |
3112 (if (message-news-p) "newsgroups" "from")) | |
3113 "(nowhere)") | |
3114 "] " (or (message-fetch-field "Subject") ""))))) | |
2723 | 3115 |
2724 ;;;###autoload | 3116 ;;;###autoload |
2725 (defun message-forward (&optional news) | 3117 (defun message-forward (&optional news) |
2726 "Forward the current message via mail. | 3118 "Forward the current message via mail. |
2727 Optional NEWS will use news to forward instead of mail." | 3119 Optional NEWS will use news to forward instead of mail." |
2728 (interactive "P") | 3120 (interactive "P") |
2729 (let ((cur (current-buffer)) | 3121 (let ((cur (current-buffer)) |
2730 (subject (message-make-forward-subject))) | 3122 (subject (message-make-forward-subject)) |
3123 art-beg) | |
2731 (if news (message-news nil subject) (message-mail nil subject)) | 3124 (if news (message-news nil subject) (message-mail nil subject)) |
2732 ;; Put point where we want it before inserting the forwarded | 3125 ;; Put point where we want it before inserting the forwarded |
2733 ;; message. | 3126 ;; message. |
2734 (if message-signature-before-forwarded-message | 3127 (if message-signature-before-forwarded-message |
2735 (goto-char (point-max)) | 3128 (goto-char (point-max)) |
2739 (insert "\n")) | 3132 (insert "\n")) |
2740 ;; Narrow to the area we are to insert. | 3133 ;; Narrow to the area we are to insert. |
2741 (narrow-to-region (point) (point)) | 3134 (narrow-to-region (point) (point)) |
2742 ;; Insert the separators and the forwarded buffer. | 3135 ;; Insert the separators and the forwarded buffer. |
2743 (insert message-forward-start-separator) | 3136 (insert message-forward-start-separator) |
3137 (setq art-beg (point)) | |
2744 (insert-buffer-substring cur) | 3138 (insert-buffer-substring cur) |
2745 (goto-char (point-max)) | 3139 (goto-char (point-max)) |
2746 (insert message-forward-end-separator) | 3140 (insert message-forward-end-separator) |
2747 (set-text-properties (point-min) (point-max) nil) | 3141 (set-text-properties (point-min) (point-max) nil) |
2748 ;; Remove all unwanted headers. | 3142 ;; Remove all unwanted headers. |
2749 (goto-char (point-min)) | 3143 (goto-char art-beg) |
2750 (forward-line 1) | |
2751 (narrow-to-region (point) (if (search-forward "\n\n" nil t) | 3144 (narrow-to-region (point) (if (search-forward "\n\n" nil t) |
2752 (1- (point)) | 3145 (1- (point)) |
2753 (point))) | 3146 (point))) |
2754 (goto-char (point-min)) | 3147 (goto-char (point-min)) |
2755 (message-remove-header message-included-forward-headers t nil t) | 3148 (message-remove-header message-included-forward-headers t nil t) |
2758 | 3151 |
2759 ;;;###autoload | 3152 ;;;###autoload |
2760 (defun message-resend (address) | 3153 (defun message-resend (address) |
2761 "Resend the current article to ADDRESS." | 3154 "Resend the current article to ADDRESS." |
2762 (interactive "sResend message to: ") | 3155 (interactive "sResend message to: ") |
3156 (message "Resending message to %s..." address) | |
2763 (save-excursion | 3157 (save-excursion |
2764 (let ((cur (current-buffer)) | 3158 (let ((cur (current-buffer)) |
2765 beg) | 3159 beg) |
2766 ;; We first set up a normal mail buffer. | 3160 ;; We first set up a normal mail buffer. |
2767 (set-buffer (get-buffer-create " *message resend*")) | 3161 (set-buffer (get-buffer-create " *message resend*")) |
2791 (insert mail-header-separator) | 3185 (insert mail-header-separator) |
2792 ;; Rename all old ("Also-")Resent headers. | 3186 ;; Rename all old ("Also-")Resent headers. |
2793 (while (re-search-backward "^\\(Also-\\)?Resent-" beg t) | 3187 (while (re-search-backward "^\\(Also-\\)?Resent-" beg t) |
2794 (beginning-of-line) | 3188 (beginning-of-line) |
2795 (insert "Also-")) | 3189 (insert "Also-")) |
3190 ;; Quote any "From " lines at the beginning. | |
3191 (goto-char beg) | |
3192 (when (looking-at "From ") | |
3193 (replace-match "X-From-Line: ")) | |
2796 ;; Send it. | 3194 ;; Send it. |
2797 (message-send-mail) | 3195 (message-send-mail) |
2798 (kill-buffer (current-buffer))))) | 3196 (kill-buffer (current-buffer))) |
3197 (message "Resending message to %s...done" address))) | |
2799 | 3198 |
2800 ;;;###autoload | 3199 ;;;###autoload |
2801 (defun message-bounce () | 3200 (defun message-bounce () |
2802 "Re-mail the current message. | 3201 "Re-mail the current message. |
2803 This only makes sense if the current message is a bounce message than | 3202 This only makes sense if the current message is a bounce message than |
2903 Works by overstriking characters. | 3302 Works by overstriking characters. |
2904 Called from program, takes two arguments START and END | 3303 Called from program, takes two arguments START and END |
2905 which specify the range to operate on." | 3304 which specify the range to operate on." |
2906 (interactive "r") | 3305 (interactive "r") |
2907 (save-excursion | 3306 (save-excursion |
2908 (let ((end1 (make-marker))) | 3307 (let ((end1 (make-marker))) |
2909 (move-marker end1 (max start end)) | 3308 (move-marker end1 (max start end)) |
2910 (goto-char (min start end)) | 3309 (goto-char (min start end)) |
2911 (while (< (point) end1) | 3310 (while (< (point) end1) |
2912 (or (looking-at "[_\^@- ]") | 3311 (or (looking-at "[_\^@- ]") |
2913 (insert (following-char) "\b")) | 3312 (insert (following-char) "\b")) |
2914 (forward-char 1))))) | 3313 (forward-char 1))))) |
2915 | 3314 |
2916 ;;;###autoload | 3315 ;;;###autoload |
2917 (defun unbold-region (start end) | 3316 (defun unbold-region (start end) |
2918 "Remove all boldness (overstruck characters) in the region. | 3317 "Remove all boldness (overstruck characters) in the region. |
2919 Called from program, takes two arguments START and END | 3318 Called from program, takes two arguments START and END |
2920 which specify the range to operate on." | 3319 which specify the range to operate on." |
2921 (interactive "r") | 3320 (interactive "r") |
2922 (save-excursion | 3321 (save-excursion |
2923 (let ((end1 (make-marker))) | 3322 (let ((end1 (make-marker))) |
2924 (move-marker end1 (max start end)) | 3323 (move-marker end1 (max start end)) |
2925 (goto-char (min start end)) | 3324 (goto-char (min start end)) |
2926 (while (re-search-forward "\b" end1 t) | 3325 (while (re-search-forward "\b" end1 t) |
2927 (if (eq (following-char) (char-after (- (point) 2))) | 3326 (if (eq (following-char) (char-after (- (point) 2))) |
2928 (delete-char -2)))))) | 3327 (delete-char -2)))))) |
2929 | 3328 |
2930 (defalias 'message-exchange-point-and-mark 'exchange-point-and-mark) | 3329 (defalias 'message-exchange-point-and-mark 'exchange-point-and-mark) |
2931 | 3330 |
2932 ;; Support for toolbar | 3331 ;; Support for toolbar |
2933 (when (string-match "XEmacs\\|Lucid" emacs-version) | 3332 (when (string-match "XEmacs\\|Lucid" emacs-version) |
2948 (message-expand-group) | 3347 (message-expand-group) |
2949 (tab-to-tab-stop))) | 3348 (tab-to-tab-stop))) |
2950 | 3349 |
2951 (defvar gnus-active-hashtb) | 3350 (defvar gnus-active-hashtb) |
2952 (defun message-expand-group () | 3351 (defun message-expand-group () |
2953 (let* ((b (save-excursion (skip-chars-backward "^, :\t\n") (point))) | 3352 (let* ((b (save-excursion |
3353 (save-restriction | |
3354 (narrow-to-region | |
3355 (save-excursion | |
3356 (beginning-of-line) | |
3357 (skip-chars-forward "^:") | |
3358 (1+ (point))) | |
3359 (point)) | |
3360 (skip-chars-backward "^, \t\n") (point)))) | |
2954 (completion-ignore-case t) | 3361 (completion-ignore-case t) |
2955 (string (buffer-substring b (point))) | 3362 (string (buffer-substring b (point))) |
2956 (hashtb (and (boundp 'gnus-active-hashtb) gnus-active-hashtb)) | 3363 (hashtb (and (boundp 'gnus-active-hashtb) gnus-active-hashtb)) |
2957 (completions (all-completions string hashtb)) | 3364 (completions (all-completions string hashtb)) |
2958 (cur (current-buffer)) | 3365 (cur (current-buffer)) |
2981 (goto-char (point-min)) | 3388 (goto-char (point-min)) |
2982 (pop-to-buffer cur))))))) | 3389 (pop-to-buffer cur))))))) |
2983 | 3390 |
2984 ;;; Help stuff. | 3391 ;;; Help stuff. |
2985 | 3392 |
2986 (defmacro message-y-or-n-p (question show &rest text) | |
2987 "Ask QUESTION, displaying the rest of the arguments in a temp. buffer if SHOW" | |
2988 `(message-talkative-question 'y-or-n-p ,question ,show ,@text)) | |
2989 | |
2990 (defun message-talkative-question (ask question show &rest text) | 3393 (defun message-talkative-question (ask question show &rest text) |
2991 "Call FUNCTION with argument QUESTION, displaying the rest of the arguments in a temporary buffer if SHOW. | 3394 "Call FUNCTION with argument QUESTION, displaying the rest of the arguments in a temporary buffer if SHOW. |
2992 The following arguments may contain lists of values." | 3395 The following arguments may contain lists of values." |
2993 (if (and show | 3396 (if (and show |
2994 (setq text (message-flatten-list text))) | 3397 (setq text (message-flatten-list text))) |
2999 (mapcar 'princ text) | 3402 (mapcar 'princ text) |
3000 (goto-char (point-min)))) | 3403 (goto-char (point-min)))) |
3001 (funcall ask question)) | 3404 (funcall ask question)) |
3002 (funcall ask question))) | 3405 (funcall ask question))) |
3003 | 3406 |
3004 (defun message-flatten-list (&rest list) | 3407 (defun message-flatten-list (list) |
3005 (message-flatten-list-1 list)) | 3408 "Return a new, flat list that contains all elements of LIST. |
3006 | 3409 |
3007 (defun message-flatten-list-1 (list) | 3410 \(message-flatten-list '(1 (2 3 (4 5 (6))) 7)) |
3411 => (1 2 3 4 5 6 7)" | |
3008 (cond ((consp list) | 3412 (cond ((consp list) |
3009 (apply 'append (mapcar 'message-flatten-list-1 list))) | 3413 (apply 'append (mapcar 'message-flatten-list list))) |
3010 (list | 3414 (list |
3011 (list list)))) | 3415 (list list)))) |
3012 | 3416 |
3417 (defun message-generate-new-buffer-clone-locals (name &optional varstr) | |
3418 "Create and return a buffer with a name based on NAME using generate-new-buffer. | |
3419 Then clone the local variables and values from the old buffer to the | |
3420 new one, cloning only the locals having a substring matching the | |
3421 regexp varstr." | |
3422 (let ((oldlocals (buffer-local-variables))) | |
3423 (save-excursion | |
3424 (set-buffer (generate-new-buffer name)) | |
3425 (mapcar (lambda (dude) | |
3426 (when (and (car dude) | |
3427 (or (not varstr) | |
3428 (string-match varstr (symbol-name (car dude))))) | |
3429 (ignore-errors | |
3430 (set (make-local-variable (car dude)) | |
3431 (cdr dude))))) | |
3432 oldlocals) | |
3433 (current-buffer)))) | |
3434 | |
3013 (run-hooks 'message-load-hook) | 3435 (run-hooks 'message-load-hook) |
3014 | 3436 |
3015 (provide 'message) | 3437 (provide 'message) |
3016 | 3438 |
3017 ;;; message.el ends here | 3439 ;;; message.el ends here |