019fb626eeb93c025d75470cf912fff7214d13ac
[gnus] / lisp / message.el
1 ;;; message.el --- composing mail and news messages
2
3 ;; Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
4 ;;   2005, 2006, 2007, 2008 Free Software Foundation, Inc.
5
6 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
7 ;; Keywords: mail, news
8
9 ;; This file is part of GNU Emacs.
10
11 ;; GNU Emacs is free software: you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation, either version 3 of the License, or
14 ;; (at your option) any later version.
15
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.
23
24 ;;; Commentary:
25
26 ;; This mode provides mail-sending facilities from within Emacs.  It
27 ;; consists mainly of large chunks of code from the sendmail.el,
28 ;; gnus-msg.el and rnewspost.el files.
29
30 ;;; Code:
31
32 (eval-and-compile
33   (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
34 (eval-when-compile
35   (require 'cl))
36
37 (require 'hashcash)
38 (require 'canlock)
39 (require 'mailheader)
40 (require 'gmm-utils)
41 (require 'nnheader)
42 ;; This is apparently necessary even though things are autoloaded.
43 ;; Because we dynamically bind mail-abbrev-mode-regexp, we'd better
44 ;; require mailabbrev here.
45 (if (featurep 'xemacs)
46     (require 'mail-abbrevs)
47   (require 'mailabbrev))
48 (require 'mail-parse)
49 (require 'mml)
50 (require 'rfc822)
51 (require 'ecomplete)
52
53 (autoload 'mailclient-send-it "mailclient") ;; Emacs 22 or contrib/
54
55 (defvar gnus-message-group-art)
56 (defvar gnus-list-identifiers) ; gnus-sum is required where necessary
57 (defvar rmail-enable-mime-composing)
58
59 (defgroup message '((user-mail-address custom-variable)
60                     (user-full-name custom-variable))
61   "Mail and news message composing."
62   :link '(custom-manual "(message)Top")
63   :group 'mail
64   :group 'news)
65
66 (put 'user-mail-address 'custom-type 'string)
67 (put 'user-full-name 'custom-type 'string)
68
69 (defgroup message-various nil
70   "Various Message Variables."
71   :link '(custom-manual "(message)Various Message Variables")
72   :group 'message)
73
74 (defgroup message-buffers nil
75   "Message Buffers."
76   :link '(custom-manual "(message)Message Buffers")
77   :group 'message)
78
79 (defgroup message-sending nil
80   "Message Sending."
81   :link '(custom-manual "(message)Sending Variables")
82   :group 'message)
83
84 (defgroup message-interface nil
85   "Message Interface."
86   :link '(custom-manual "(message)Interface")
87   :group 'message)
88
89 (defgroup message-forwarding nil
90   "Message Forwarding."
91   :link '(custom-manual "(message)Forwarding")
92   :group 'message-interface)
93
94 (defgroup message-insertion nil
95   "Message Insertion."
96   :link '(custom-manual "(message)Insertion")
97   :group 'message)
98
99 (defgroup message-headers nil
100   "Message Headers."
101   :link '(custom-manual "(message)Message Headers")
102   :group 'message)
103
104 (defgroup message-news nil
105   "Composing News Messages."
106   :group 'message)
107
108 (defgroup message-mail nil
109   "Composing Mail Messages."
110   :group 'message)
111
112 (defgroup message-faces nil
113   "Faces used for message composing."
114   :group 'message
115   :group 'faces)
116
117 (defcustom message-directory "~/Mail/"
118   "*Directory from which all other mail file variables are derived."
119   :group 'message-various
120   :type 'directory)
121
122 (defcustom message-max-buffers 10
123   "*How many buffers to keep before starting to kill them off."
124   :group 'message-buffers
125   :type 'integer)
126
127 (defcustom message-send-rename-function nil
128   "Function called to rename the buffer after sending it."
129   :group 'message-buffers
130   :type '(choice function (const nil)))
131
132 (defcustom message-fcc-handler-function 'message-output
133   "*A function called to save outgoing articles.
134 This function will be called with the name of the file to store the
135 article in.  The default function is `message-output' which saves in Unix
136 mailbox format."
137   :type '(radio (function-item message-output)
138                 (function :tag "Other"))
139   :group 'message-sending)
140
141 (defcustom message-fcc-externalize-attachments nil
142   "If non-nil, attachments are included as external parts in Fcc copies."
143   :version "22.1"
144   :type 'boolean
145   :group 'message-sending)
146
147 (defcustom message-courtesy-message
148   "The following message is a courtesy copy of an article\nthat has been posted to %s as well.\n\n"
149   "*This is inserted at the start of a mailed copy of a posted message.
150 If the string contains the format spec \"%s\", the Newsgroups
151 the article has been posted to will be inserted there.
152 If this variable is nil, no such courtesy message will be added."
153   :group 'message-sending
154   :type '(radio string (const nil)))
155
156 (defcustom message-ignored-bounced-headers
157   "^\\(Received\\|Return-Path\\|Delivered-To\\):"
158   "*Regexp that matches headers to be removed in resent bounced mail."
159   :group 'message-interface
160   :type 'regexp)
161
162 (defcustom message-from-style 'default
163   "*Specifies how \"From\" headers look.
164
165 If nil, they contain just the return address like:
166         king@grassland.com
167 If `parens', they look like:
168         king@grassland.com (Elvis Parsley)
169 If `angles', they look like:
170         Elvis Parsley <king@grassland.com>
171
172 Otherwise, most addresses look like `angles', but they look like
173 `parens' if `angles' would need quoting and `parens' would not."
174   :type '(choice (const :tag "simple" nil)
175                  (const parens)
176                  (const angles)
177                  (const default))
178   :group 'message-headers)
179
180 (defcustom message-insert-canlock t
181   "Whether to insert a Cancel-Lock header in news postings."
182   :version "22.1"
183   :group 'message-headers
184   :type 'boolean)
185
186 (defcustom message-syntax-checks
187   (if message-insert-canlock '((sender . disabled)) nil)
188   ;; Guess this one shouldn't be easy to customize...
189   "*Controls what syntax checks should not be performed on outgoing posts.
190 To disable checking of long signatures, for instance, add
191  `(signature . disabled)' to this list.
192
193 Don't touch this variable unless you really know what you're doing.
194
195 Checks include `approved', `bogus-recipient', `continuation-headers',
196 `control-chars', `empty', `existing-newsgroups', `from', `illegible-text',
197 `invisible-text', `long-header-lines', `long-lines', `message-id',
198 `multiple-headers', `new-text', `newsgroups', `quoting-style',
199 `repeated-newsgroups', `reply-to', `sender', `sendsys', `shoot',
200 `shorten-followup-to', `signature', `size', `subject', `subject-cmsg'
201 and `valid-newsgroups'."
202   :group 'message-news
203   :type '(repeat sexp))                 ; Fixme: improve this
204
205 (defcustom message-required-headers '((optional . References)
206                                       From)
207   "*Headers to be generated or prompted for when sending a message.
208 Also see `message-required-news-headers' and
209 `message-required-mail-headers'."
210   :version "22.1"
211   :group 'message-news
212   :group 'message-headers
213   :link '(custom-manual "(message)Message Headers")
214   :type '(repeat sexp))
215
216 (defcustom message-draft-headers '(References From Date)
217   "*Headers to be generated when saving a draft message."
218   :version "22.1"
219   :group 'message-news
220   :group 'message-headers
221   :link '(custom-manual "(message)Message Headers")
222   :type '(repeat sexp))
223
224 (defcustom message-required-news-headers
225   '(From Newsgroups Subject Date Message-ID
226          (optional . Organization)
227          (optional . User-Agent))
228   "*Headers to be generated or prompted for when posting an article.
229 RFC977 and RFC1036 require From, Date, Newsgroups, Subject,
230 Message-ID.  Organization, Lines, In-Reply-To, Expires, and
231 User-Agent are optional.  If you don't want message to insert some
232 header, remove it from this list."
233   :group 'message-news
234   :group 'message-headers
235   :link '(custom-manual "(message)Message Headers")
236   :type '(repeat sexp))
237
238 (defcustom message-required-mail-headers
239   '(From Subject Date (optional . In-Reply-To) Message-ID
240          (optional . User-Agent))
241   "*Headers to be generated or prompted for when mailing a message.
242 It is recommended that From, Date, To, Subject and Message-ID be
243 included.  Organization and User-Agent are optional."
244   :group 'message-mail
245   :group 'message-headers
246   :link '(custom-manual "(message)Message Headers")
247   :type '(repeat sexp))
248
249 (defcustom message-deletable-headers '(Message-ID Date Lines)
250   "Headers to be deleted if they already exist and were generated by message previously."
251   :group 'message-headers
252   :link '(custom-manual "(message)Message Headers")
253   :type 'sexp)
254
255 (defcustom message-ignored-news-headers
256   "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:"
257   "*Regexp of headers to be removed unconditionally before posting."
258   :group 'message-news
259   :group 'message-headers
260   :link '(custom-manual "(message)Message Headers")
261   :type '(repeat :value-to-internal (lambda (widget value)
262                                       (custom-split-regexp-maybe value))
263                  :match (lambda (widget value)
264                           (or (stringp value)
265                               (widget-editable-list-match widget value)))
266                  regexp))
267
268 (defcustom message-ignored-mail-headers
269   "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:"
270   "*Regexp of headers to be removed unconditionally before mailing."
271   :group 'message-mail
272   :group 'message-headers
273   :link '(custom-manual "(message)Mail Headers")
274   :type 'regexp)
275
276 (defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-ID:\\|^X-Complaints-To:\\|Return-Path:\\|^Supersedes:\\|^NNTP-Posting-Date:\\|^X-Trace:\\|^X-Complaints-To:\\|^Cancel-Lock:\\|^Cancel-Key:\\|^X-Hashcash:\\|^X-Payment:\\|^Approved:"
277   "*Header lines matching this regexp will be deleted before posting.
278 It's best to delete old Path and Date headers before posting to avoid
279 any confusion."
280   :group 'message-interface
281   :link '(custom-manual "(message)Superseding")
282   :type '(repeat :value-to-internal (lambda (widget value)
283                                       (custom-split-regexp-maybe value))
284                  :match (lambda (widget value)
285                           (or (stringp value)
286                               (widget-editable-list-match widget value)))
287                  regexp))
288
289 (defcustom message-subject-re-regexp
290   "^[ \t]*\\([Rr][Ee]\\(\\[[0-9]*\\]\\)*:[ \t]*\\)*[ \t]*"
291   "*Regexp matching \"Re: \" in the subject line."
292   :group 'message-various
293   :link '(custom-manual "(message)Message Headers")
294   :type 'regexp)
295
296 ;;; Start of variables adopted from `message-utils.el'.
297
298 (defcustom message-subject-trailing-was-query 'ask
299   "*What to do with trailing \"(was: <old subject>)\" in subject lines.
300 If nil, leave the subject unchanged.  If it is the symbol `ask', query
301 the user what do do.  In this case, the subject is matched against
302 `message-subject-trailing-was-ask-regexp'.  If
303 `message-subject-trailing-was-query' is t, always strip the trailing
304 old subject.  In this case, `message-subject-trailing-was-regexp' is
305 used."
306   :version "22.1"
307   :type '(choice (const :tag "never" nil)
308                  (const :tag "always strip" t)
309                  (const ask))
310   :link '(custom-manual "(message)Message Headers")
311   :group 'message-various)
312
313 (defcustom message-subject-trailing-was-ask-regexp
314   "[ \t]*\\([[(]+[Ww][Aa][Ss][ \t]*.*[\])]+\\)"
315   "*Regexp matching \"(was: <old subject>)\" in the subject line.
316
317 The function `message-strip-subject-trailing-was' uses this regexp if
318 `message-subject-trailing-was-query' is set to the symbol `ask'.  If
319 the variable is t instead of `ask', use
320 `message-subject-trailing-was-regexp' instead.
321
322 It is okay to create some false positives here, as the user is asked."
323   :version "22.1"
324   :group 'message-various
325   :link '(custom-manual "(message)Message Headers")
326   :type 'regexp)
327
328 (defcustom message-subject-trailing-was-regexp
329   "[ \t]*\\((*[Ww][Aa][Ss]:[ \t]*.*)\\)"
330   "*Regexp matching \"(was: <old subject>)\" in the subject line.
331
332 If `message-subject-trailing-was-query' is set to t, the subject is
333 matched against `message-subject-trailing-was-regexp' in
334 `message-strip-subject-trailing-was'.  You should use a regexp creating very
335 few false positives here."
336   :version "22.1"
337   :group 'message-various
338   :link '(custom-manual "(message)Message Headers")
339   :type 'regexp)
340
341 ;;; marking inserted text
342
343 (defcustom message-mark-insert-begin
344   "--8<---------------cut here---------------start------------->8---\n"
345   "How to mark the beginning of some inserted text."
346   :version "22.1"
347   :type 'string
348   :link '(custom-manual "(message)Insertion Variables")
349   :group 'message-various)
350
351 (defcustom message-mark-insert-end
352   "--8<---------------cut here---------------end--------------->8---\n"
353   "How to mark the end of some inserted text."
354   :version "22.1"
355   :type 'string
356   :link '(custom-manual "(message)Insertion Variables")
357   :group 'message-various)
358
359 (defcustom message-archive-header "X-No-Archive: Yes\n"
360   "Header to insert when you don't want your article to be archived.
361 Archives \(such as groups.google.com\) respect this header."
362   :version "22.1"
363   :type 'string
364   :link '(custom-manual "(message)Header Commands")
365   :group 'message-various)
366
367 (defcustom message-archive-note
368   "X-No-Archive: Yes - save http://groups.google.com/"
369   "Note to insert why you wouldn't want this posting archived.
370 If nil, don't insert any text in the body."
371   :version "22.1"
372   :type '(radio string (const nil))
373   :link '(custom-manual "(message)Header Commands")
374   :group 'message-various)
375
376 ;;; Crossposts and Followups
377 ;; inspired by JoH-followup-to by Jochem Huhman <joh  at gmx.de>
378 ;; new suggestions by R. Weikusat <rw at another.de>
379
380 (defvar message-cross-post-old-target nil
381   "Old target for cross-posts or follow-ups.")
382 (make-variable-buffer-local 'message-cross-post-old-target)
383
384 (defcustom message-cross-post-default t
385   "When non-nil `message-cross-post-followup-to' will perform a crosspost.
386 If nil, `message-cross-post-followup-to' will only do a followup.  Note that
387 you can explicitly override this setting by calling
388 `message-cross-post-followup-to' with a prefix."
389   :version "22.1"
390   :type 'boolean
391   :group 'message-various)
392
393 (defcustom message-cross-post-note "Crosspost & Followup-To: "
394   "Note to insert before signature to notify of cross-post and follow-up."
395   :version "22.1"
396   :type 'string
397   :group 'message-various)
398
399 (defcustom message-followup-to-note "Followup-To: "
400   "Note to insert before signature to notify of follow-up only."
401   :version "22.1"
402   :type 'string
403   :group 'message-various)
404
405 (defcustom message-cross-post-note-function 'message-cross-post-insert-note
406   "Function to use to insert note about Crosspost or Followup-To.
407 The function will be called with four arguments.  The function should not only
408 insert a note, but also ensure old notes are deleted.  See the documentation
409 for `message-cross-post-insert-note'."
410   :version "22.1"
411   :type 'function
412   :group 'message-various)
413
414 ;;; End of variables adopted from `message-utils.el'.
415
416 (defcustom message-signature-separator "^-- $"
417   "Regexp matching the signature separator.
418 This variable is used to strip off the signature from quoted text
419 when `message-cite-function' is
420 `message-cite-original-without-signature'.  Most useful values
421 are \"^-- $\" (strict) and \"^-- *$\" (loose; allow missing
422 whitespace)."
423   :type '(choice (const :tag "strict" "^-- $")
424                  (const :tag "loose" "^-- *$")
425                  regexp)
426   :version "22.3" ;; Gnus 5.10.12 (changed default)
427   :link '(custom-manual "(message)Various Message Variables")
428   :group 'message-various)
429
430 (defcustom message-elide-ellipsis "\n[...]\n\n"
431   "*The string which is inserted for elided text."
432   :type 'string
433   :link '(custom-manual "(message)Various Commands")
434   :group 'message-various)
435
436 (defcustom message-interactive t
437   "Non-nil means when sending a message wait for and display errors.
438 nil means let mailer mail back a message to report errors."
439   :group 'message-sending
440   :group 'message-mail
441   :link '(custom-manual "(message)Sending Variables")
442   :type 'boolean)
443
444 (defcustom message-confirm-send nil
445   "When non-nil, ask for confirmation when sending a message."
446   :group 'message-sending
447   :group 'message-mail
448   :version "23.1" ;; No Gnus
449   :link '(custom-manual "(message)Sending Variables")
450   :type 'boolean)
451
452 (defcustom message-generate-new-buffers 'unique
453   "*Say whether to create a new message buffer to compose a message.
454 Valid values include:
455
456 nil
457   Generate the buffer name in the Message way (e.g., *mail*, *news*,
458   *mail to whom*, *news on group*, etc.) and continue editing in the
459   existing buffer of that name.  If there is no such buffer, it will
460   be newly created.
461
462 `unique' or t
463   Create the new buffer with the name generated in the Message way.
464
465 `unsent'
466   Similar to `unique' but the buffer name begins with \"*unsent \".
467
468 `standard'
469   Similar to nil but the buffer name is simpler like *mail message*.
470
471 function
472   If this is a function, call that function with three parameters:
473   The type, the To address and the group name (any of these may be nil).
474   The function should return the new buffer name."
475   :group 'message-buffers
476   :link '(custom-manual "(message)Message Buffers")
477   :type '(choice (const nil)
478                  (sexp :tag "unique" :format "unique\n" :value unique
479                        :match (lambda (widget value) (memq value '(unique t))))
480                  (const unsent)
481                  (const standard)
482                  (function :format "\n    %{%t%}: %v")))
483
484 (defcustom message-kill-buffer-on-exit nil
485   "*Non-nil means that the message buffer will be killed after sending a message."
486   :group 'message-buffers
487   :link '(custom-manual "(message)Message Buffers")
488   :type 'boolean)
489
490 (defcustom message-kill-buffer-query t
491   "*Non-nil means that killing a modified message buffer has to be confirmed.
492 This is used by `message-kill-buffer'."
493   :version "23.1" ;; No Gnus
494   :group 'message-buffers
495   :type 'boolean)
496
497 (defvar gnus-local-organization)
498 (defcustom message-user-organization
499   (or (and (boundp 'gnus-local-organization)
500            (stringp gnus-local-organization)
501            gnus-local-organization)
502       (getenv "ORGANIZATION")
503       t)
504   "*String to be used as an Organization header.
505 If t, use `message-user-organization-file'."
506   :group 'message-headers
507   :type '(choice string
508                  (const :tag "consult file" t)))
509
510 (defcustom message-user-organization-file
511   (let (orgfile)
512     (dolist (f (list "/etc/organization"
513                      "/etc/news/organization"
514                      "/usr/lib/news/organization"))
515       (when (file-readable-p f)
516         (setq orgfile f)))
517     orgfile)
518   "*Local news organization file."
519   :type 'file
520   :link '(custom-manual "(message)News Headers")
521   :group 'message-headers)
522
523 (defcustom message-make-forward-subject-function
524   #'message-forward-subject-name-subject
525   "*List of functions called to generate subject headers for forwarded messages.
526 The subject generated by the previous function is passed into each
527 successive function.
528
529 The provided functions are:
530
531 * `message-forward-subject-author-subject' Source of article (author or
532       newsgroup), in brackets followed by the subject
533 * `message-forward-subject-name-subject' Source of article (name of author
534       or newsgroup), in brackets followed by the subject
535 * `message-forward-subject-fwd' Subject of article with 'Fwd:' prepended
536       to it."
537   :group 'message-forwarding
538   :link '(custom-manual "(message)Forwarding")
539   :type '(radio (function-item message-forward-subject-author-subject)
540                 (function-item message-forward-subject-fwd)
541                 (function-item message-forward-subject-name-subject)
542                 (repeat :tag "List of functions" function)))
543
544 (defcustom message-forward-as-mime t
545   "*Non-nil means forward messages as an inline/rfc822 MIME section.
546 Otherwise, directly inline the old message in the forwarded message."
547   :version "21.1"
548   :group 'message-forwarding
549   :link '(custom-manual "(message)Forwarding")
550   :type 'boolean)
551
552 (defcustom message-forward-show-mml 'best
553   "*Non-nil means show forwarded messages as MML (decoded from MIME).
554 Otherwise, forwarded messages are unchanged.
555 Can also be the symbol `best' to indicate that MML should be
556 used, except when it is a bad idea to use MML.  One example where
557 it is a bad idea is when forwarding a signed or encrypted
558 message, because converting MIME to MML would invalidate the
559 digital signature."
560   :version "21.1"
561   :group 'message-forwarding
562   :type '(choice (const :tag "use MML" t)
563                  (const :tag "don't use MML " nil)
564                  (const :tag "use MML when appropriate" best)))
565
566 (defcustom message-forward-before-signature t
567   "*Non-nil means put forwarded message before signature, else after."
568   :group 'message-forwarding
569   :type 'boolean)
570
571 (defcustom message-wash-forwarded-subjects nil
572   "*Non-nil means try to remove as much cruft as possible from the subject.
573 Done before generating the new subject of a forward."
574   :group 'message-forwarding
575   :link '(custom-manual "(message)Forwarding")
576   :type 'boolean)
577
578 (defcustom message-ignored-resent-headers
579   ;; `Delivered-To' needs to be removed because some mailers use it to
580   ;; detect loops, so if you resend a message to an address that ultimately
581   ;; comes back to you (e.g. a mailing-list to which you subscribe, in which
582   ;; case you may be removed from the list on the grounds that mail to you
583   ;; bounced with a "mailing loop" error).
584   "^Return-receipt\\|^X-Gnus\\|^Gnus-Warning:\\|^>?From \\|^Delivered-To:"
585   "*All headers that match this regexp will be deleted when resending a message."
586   :group 'message-interface
587   :link '(custom-manual "(message)Resending")
588   :type '(repeat :value-to-internal (lambda (widget value)
589                                       (custom-split-regexp-maybe value))
590                  :match (lambda (widget value)
591                           (or (stringp value)
592                               (widget-editable-list-match widget value)))
593                  regexp))
594
595 (defcustom message-forward-ignored-headers "^Content-Transfer-Encoding:\\|^X-Gnus"
596   "*All headers that match this regexp will be deleted when forwarding a message."
597   :version "21.1"
598   :group 'message-forwarding
599   :type '(repeat :value-to-internal (lambda (widget value)
600                                       (custom-split-regexp-maybe value))
601                  :match (lambda (widget value)
602                           (or (stringp value)
603                               (widget-editable-list-match widget value)))
604                  regexp))
605
606 (defcustom message-ignored-cited-headers "."
607   "*Delete these headers from the messages you yank."
608   :group 'message-insertion
609   :link '(custom-manual "(message)Insertion Variables")
610   :type 'regexp)
611
612 (defcustom message-cite-prefix-regexp
613   (if (string-match "[[:digit:]]" "1")
614       ;; Support POSIX?  XEmacs 21.5.27 doesn't.
615       "\\([ \t]*[_.[:word:]]+>+\\|[ \t]*[]>|}]\\)+"
616     ;; ?-, ?_ or ?. MUST NOT be in syntax entry w.
617     (let (non-word-constituents)
618       (with-syntax-table text-mode-syntax-table
619         (setq non-word-constituents
620               (concat
621                (if (string-match "\\w" "_")  "" "_")
622                (if (string-match "\\w" ".")  "" "."))))
623       (if (equal non-word-constituents "")
624           "\\([ \t]*\\(\\w\\)+>+\\|[ \t]*[]>|}]\\)+"
625         (concat "\\([ \t]*\\(\\w\\|["
626                 non-word-constituents
627                 "]\\)+>+\\|[ \t]*[]>|}]\\)+"))))
628   "*Regexp matching the longest possible citation prefix on a line."
629   :version "22.1"
630   :group 'message-insertion
631   :link '(custom-manual "(message)Insertion Variables")
632   :type 'regexp
633   :set (lambda (symbol value)
634          (prog1
635              (custom-set-default symbol value)
636            (if (boundp 'gnus-message-cite-prefix-regexp)
637                (setq gnus-message-cite-prefix-regexp
638                      (concat "^\\(?:" value "\\)"))))))
639
640 (defcustom message-cancel-message "I am canceling my own article.\n"
641   "Message to be inserted in the cancel message."
642   :group 'message-interface
643   :link '(custom-manual "(message)Canceling News")
644   :type 'string)
645
646 (defvar smtpmail-default-smtp-server)
647
648 (defun message-send-mail-function ()
649   "Return suitable value for the variable `message-send-mail-function'."
650   (cond ((and (require 'sendmail)
651               (boundp 'sendmail-program)
652               sendmail-program
653               (executable-find sendmail-program))
654          'message-send-mail-with-sendmail)
655         ((and (locate-library "smtpmail")
656               (require 'smtpmail)
657               smtpmail-default-smtp-server)
658          'message-smtpmail-send-it)
659         ((locate-library "mailclient")
660          'message-send-mail-with-mailclient)
661         (t
662          (lambda ()
663            (error "Don't know how to send mail.  Please customize `message-send-mail-function'")))))
664
665 ;; Useful to set in site-init.el
666 (defcustom message-send-mail-function (message-send-mail-function)
667   "Function to call to send the current buffer as mail.
668 The headers should be delimited by a line whose contents match the
669 variable `mail-header-separator'.
670
671 Valid values include `message-send-mail-with-sendmail'
672 `message-send-mail-with-mh', `message-send-mail-with-qmail',
673 `message-smtpmail-send-it', `smtpmail-send-it',
674 `feedmail-send-it' and `message-send-mail-with-mailclient'.  The
675 default is system dependent and determined by the function
676 `message-send-mail-function'.
677
678 See also `send-mail-function'."
679   :type '(radio (function-item message-send-mail-with-sendmail)
680                 (function-item message-send-mail-with-mh)
681                 (function-item message-send-mail-with-qmail)
682                 (function-item message-smtpmail-send-it)
683                 (function-item smtpmail-send-it)
684                 (function-item feedmail-send-it)
685                 (function-item message-send-mail-with-mailclient
686                                :tag "Use Mailclient package")
687                 (function :tag "Other"))
688   :group 'message-sending
689   :version "23.1" ;; No Gnus
690   :initialize 'custom-initialize-default
691   :link '(custom-manual "(message)Mail Variables")
692   :group 'message-mail)
693
694 (defcustom message-send-news-function 'message-send-news
695   "Function to call to send the current buffer as news.
696 The headers should be delimited by a line whose contents match the
697 variable `mail-header-separator'."
698   :group 'message-sending
699   :group 'message-news
700   :link '(custom-manual "(message)News Variables")
701   :type 'function)
702
703 (defcustom message-reply-to-function nil
704   "If non-nil, function that should return a list of headers.
705 This function should pick out addresses from the To, Cc, and From headers
706 and respond with new To and Cc headers."
707   :group 'message-interface
708   :link '(custom-manual "(message)Reply")
709   :type '(choice function (const nil)))
710
711 (defcustom message-wide-reply-to-function nil
712   "If non-nil, function that should return a list of headers.
713 This function should pick out addresses from the To, Cc, and From headers
714 and respond with new To and Cc headers."
715   :group 'message-interface
716   :link '(custom-manual "(message)Wide Reply")
717   :type '(choice function (const nil)))
718
719 (defcustom message-followup-to-function nil
720   "If non-nil, function that should return a list of headers.
721 This function should pick out addresses from the To, Cc, and From headers
722 and respond with new To and Cc headers."
723   :group 'message-interface
724   :link '(custom-manual "(message)Followup")
725   :type '(choice function (const nil)))
726
727 (defcustom message-extra-wide-headers nil
728   "If non-nil, a list of additional address headers.
729 These are used when composing a wide reply."
730   :group 'message-sending
731   :type '(repeat string))
732
733 (defcustom message-use-followup-to 'ask
734   "*Specifies what to do with Followup-To header.
735 If nil, always ignore the header.  If it is t, use its value, but
736 query before using the \"poster\" value.  If it is the symbol `ask',
737 always query the user whether to use the value.  If it is the symbol
738 `use', always use the value."
739   :group 'message-interface
740   :link '(custom-manual "(message)Followup")
741   :type '(choice (const :tag "ignore" nil)
742                  (const :tag "use & query" t)
743                  (const use)
744                  (const ask)))
745
746 (defcustom message-use-mail-followup-to 'use
747   "*Specifies what to do with Mail-Followup-To header.
748 If nil, always ignore the header.  If it is the symbol `ask', always
749 query the user whether to use the value.  If it is the symbol `use',
750 always use the value."
751   :version "22.1"
752   :group 'message-interface
753   :link '(custom-manual "(message)Mailing Lists")
754   :type '(choice (const :tag "ignore" nil)
755                  (const use)
756                  (const ask)))
757
758 (defcustom message-subscribed-address-functions nil
759   "*Specifies functions for determining list subscription.
760 If nil, do not attempt to determine list subscription with functions.
761 If non-nil, this variable contains a list of functions which return
762 regular expressions to match lists.  These functions can be used in
763 conjunction with `message-subscribed-regexps' and
764 `message-subscribed-addresses'."
765   :version "22.1"