8bc7f2031c175a9385c6b98d102a9a9615f615fc
[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, or (at your option)
14 ;; 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; see the file COPYING.  If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
25
26 ;;; Commentary:
27
28 ;; This mode provides mail-sending facilities from within Emacs.  It
29 ;; consists mainly of large chunks of code from the sendmail.el,
30 ;; gnus-msg.el and rnewspost.el files.
31
32 ;;; Code:
33
34 (eval-and-compile
35   (unless (fboundp 'declare-function) (defmacro declare-function (&rest r))))
36 (eval-when-compile
37   (require 'cl))
38
39 (require 'hashcash)
40 (require 'canlock)
41 (require 'mailheader)
42 (require 'gmm-utils)
43 (require 'nnheader)
44 ;; This is apparently necessary even though things are autoloaded.
45 ;; Because we dynamically bind mail-abbrev-mode-regexp, we'd better
46 ;; require mailabbrev here.
47 (if (featurep 'xemacs)
48     (require 'mail-abbrevs)
49   (require 'mailabbrev))
50 (require 'mail-parse)
51 (require 'mml)
52 (require 'rfc822)
53 (require 'ecomplete)
54
55 (autoload 'mailclient-send-it "mailclient") ;; Emacs 22 or contrib/
56
57 (defvar gnus-message-group-art)
58 (defvar gnus-list-identifiers) ; gnus-sum is required where necessary
59 (defvar rmail-enable-mime-composing)
60
61 (defgroup message '((user-mail-address custom-variable)
62                     (user-full-name custom-variable))
63   "Mail and news message composing."
64   :link '(custom-manual "(message)Top")
65   :group 'mail
66   :group 'news)
67
68 (put 'user-mail-address 'custom-type 'string)
69 (put 'user-full-name 'custom-type 'string)
70
71 (defgroup message-various nil
72   "Various Message Variables."
73   :link '(custom-manual "(message)Various Message Variables")
74   :group 'message)
75
76 (defgroup message-buffers nil
77   "Message Buffers."
78   :link '(custom-manual "(message)Message Buffers")
79   :group 'message)
80
81 (defgroup message-sending nil
82   "Message Sending."
83   :link '(custom-manual "(message)Sending Variables")
84   :group 'message)
85
86 (defgroup message-interface nil
87   "Message Interface."
88   :link '(custom-manual "(message)Interface")
89   :group 'message)
90
91 (defgroup message-forwarding nil
92   "Message Forwarding."
93   :link '(custom-manual "(message)Forwarding")
94   :group 'message-interface)
95
96 (defgroup message-insertion nil
97   "Message Insertion."
98   :link '(custom-manual "(message)Insertion")
99   :group 'message)
100
101 (defgroup message-headers nil
102   "Message Headers."
103   :link '(custom-manual "(message)Message Headers")
104   :group 'message)
105
106 (defgroup message-news nil
107   "Composing News Messages."
108   :group 'message)
109
110 (defgroup message-mail nil
111   "Composing Mail Messages."
112   :group 'message)
113
114 (defgroup message-faces nil
115   "Faces used for message composing."
116   :group 'message
117   :group 'faces)
118
119 (defcustom message-directory "~/Mail/"
120   "*Directory from which all other mail file variables are derived."
121   :group 'message-various
122   :type 'directory)
123
124 (defcustom message-max-buffers 10
125   "*How many buffers to keep before starting to kill them off."
126   :group 'message-buffers
127   :type 'integer)
128
129 (defcustom message-send-rename-function nil
130   "Function called to rename the buffer after sending it."
131   :group 'message-buffers
132   :type '(choice function (const nil)))
133
134 (defcustom message-fcc-handler-function 'message-output
135   "*A function called to save outgoing articles.
136 This function will be called with the name of the file to store the
137 article in.  The default function is `message-output' which saves in Unix
138 mailbox format."
139   :type '(radio (function-item message-output)
140                 (function :tag "Other"))
141   :group 'message-sending)
142
143 (defcustom message-fcc-externalize-attachments nil
144   "If non-nil, attachments are included as external parts in Fcc copies."
145   :version "22.1"
146   :type 'boolean
147   :group 'message-sending)
148
149 (defcustom message-courtesy-message
150   "The following message is a courtesy copy of an article\nthat has been posted to %s as well.\n\n"
151   "*This is inserted at the start of a mailed copy of a posted message.
152 If the string contains the format spec \"%s\", the Newsgroups
153 the article has been posted to will be inserted there.
154 If this variable is nil, no such courtesy message will be added."
155   :group 'message-sending
156   :type '(radio string (const nil)))
157
158 (defcustom message-ignored-bounced-headers
159   "^\\(Received\\|Return-Path\\|Delivered-To\\):"
160   "*Regexp that matches headers to be removed in resent bounced mail."
161   :group 'message-interface
162   :type 'regexp)
163
164 (defcustom message-from-style 'default
165   "*Specifies how \"From\" headers look.
166
167 If nil, they contain just the return address like:
168         king@grassland.com
169 If `parens', they look like:
170         king@grassland.com (Elvis Parsley)
171 If `angles', they look like:
172         Elvis Parsley <king@grassland.com>
173
174 Otherwise, most addresses look like `angles', but they look like
175 `parens' if `angles' would need quoting and `parens' would not."
176   :type '(choice (const :tag "simple" nil)
177                  (const parens)
178                  (const angles)
179                  (const default))
180   :group 'message-headers)
181
182 (defcustom message-insert-canlock t
183   "Whether to insert a Cancel-Lock header in news postings."
184   :version "22.1"
185   :group 'message-headers
186   :type 'boolean)
187
188 (defcustom message-syntax-checks
189   (if message-insert-canlock '((sender . disabled)) nil)
190   ;; Guess this one shouldn't be easy to customize...
191   "*Controls what syntax checks should not be performed on outgoing posts.
192 To disable checking of long signatures, for instance, add
193  `(signature . disabled)' to this list.
194
195 Don't touch this variable unless you really know what you're doing.
196
197 Checks include `approved', `bogus-recipient', `continuation-headers',
198 `control-chars', `empty', `existing-newsgroups', `from', `illegible-text',
199 `invisible-text', `long-header-lines', `long-lines', `message-id',
200 `multiple-headers', `new-text', `newsgroups', `quoting-style',
201 `repeated-newsgroups', `reply-to', `sender', `sendsys', `shoot',
202 `shorten-followup-to', `signature', `size', `subject', `subject-cmsg'
203 and `valid-newsgroups'."
204   :group 'message-news
205   :type '(repeat sexp))                 ; Fixme: improve this
206
207 (defcustom message-required-headers '((optional . References)
208                                       From)
209   "*Headers to be generated or prompted for when sending a message.
210 Also see `message-required-news-headers' and
211 `message-required-mail-headers'."
212   :version "22.1"
213   :group 'message-news
214   :group 'message-headers
215   :link '(custom-manual "(message)Message Headers")
216   :type '(repeat sexp))
217
218 (defcustom message-draft-headers '(References From Date)
219   "*Headers to be generated when saving a draft message."
220   :version "22.1"
221   :group 'message-news
222   :group 'message-headers
223   :link '(custom-manual "(message)Message Headers")
224   :type '(repeat sexp))
225
226 (defcustom message-required-news-headers
227   '(From Newsgroups Subject Date Message-ID
228          (optional . Organization)
229          (optional . User-Agent))
230   "*Headers to be generated or prompted for when posting an article.
231 RFC977 and RFC1036 require From, Date, Newsgroups, Subject,
232 Message-ID.  Organization, Lines, In-Reply-To, Expires, and
233 User-Agent are optional.  If you don't want message to insert some
234 header, remove it from this list."
235   :group 'message-news
236   :group 'message-headers
237   :link '(custom-manual "(message)Message Headers")
238   :type '(repeat sexp))
239
240 (defcustom message-required-mail-headers
241   '(From Subject Date (optional . In-Reply-To) Message-ID
242          (optional . User-Agent))
243   "*Headers to be generated or prompted for when mailing a message.
244 It is recommended that From, Date, To, Subject and Message-ID be
245 included.  Organization and User-Agent are optional."
246   :group 'message-mail
247   :group 'message-headers
248   :link '(custom-manual "(message)Message Headers")
249   :type '(repeat sexp))
250
251 (defcustom message-deletable-headers '(Message-ID Date Lines)
252   "Headers to be deleted if they already exist and were generated by message previously."
253   :group 'message-headers
254   :link '(custom-manual "(message)Message Headers")
255   :type 'sexp)
256
257 (defcustom message-ignored-news-headers
258   "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:"
259   "*Regexp of headers to be removed unconditionally before posting."
260   :group 'message-news
261   :group 'message-headers
262   :link '(custom-manual "(message)Message Headers")
263   :type '(repeat :value-to-internal (lambda (widget value)
264                                       (custom-split-regexp-maybe value))
265                  :match (lambda (widget value)
266                           (or (stringp value)
267                               (widget-editable-list-match widget value)))
268                  regexp))
269
270 (defcustom message-ignored-mail-headers
271   "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:\\|^X-Draft-From:\\|^X-Gnus-Agent-Meta-Information:"
272   "*Regexp of headers to be removed unconditionally before mailing."
273   :group 'message-mail
274   :group 'message-headers
275   :link '(custom-manual "(message)Mail Headers")
276   :type 'regexp)
277
278 (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:"
279   "*Header lines matching this regexp will be deleted before posting.
280 It's best to delete old Path and Date headers before posting to avoid
281 any confusion."
282   :group 'message-interface
283   :link '(custom-manual "(message)Superseding")
284   :type '(repeat :value-to-internal (lambda (widget value)
285                                       (custom-split-regexp-maybe value))
286                  :match (lambda (widget value)
287                           (or (stringp value)
288                               (widget-editable-list-match widget value)))
289                  regexp))
290
291 (defcustom message-subject-re-regexp
292   "^[ \t]*\\([Rr][Ee]\\(\\[[0-9]*\\]\\)*:[ \t]*\\)*[ \t]*"
293   "*Regexp matching \"Re: \" in the subject line."
294   :group 'message-various
295   :link '(custom-manual "(message)Message Headers")
296   :type 'regexp)
297
298 ;;; Start of variables adopted from `message-utils.el'.
299
300 (defcustom message-subject-trailing-was-query 'ask
301   "*What to do with trailing \"(was: <old subject>)\" in subject lines.
302 If nil, leave the subject unchanged.  If it is the symbol `ask', query
303 the user what do do.  In this case, the subject is matched against
304 `message-subject-trailing-was-ask-regexp'.  If
305 `message-subject-trailing-was-query' is t, always strip the trailing
306 old subject.  In this case, `message-subject-trailing-was-regexp' is
307 used."
308   :version "22.1"
309   :type '(choice (const :tag "never" nil)
310                  (const :tag "always strip" t)
311                  (const ask))
312   :link '(custom-manual "(message)Message Headers")
313   :group 'message-various)
314
315 (defcustom message-subject-trailing-was-ask-regexp
316   "[ \t]*\\([[(]+[Ww][Aa][Ss][ \t]*.*[\])]+\\)"
317   "*Regexp matching \"(was: <old subject>)\" in the subject line.
318
319 The function `message-strip-subject-trailing-was' uses this regexp if
320 `message-subject-trailing-was-query' is set to the symbol `ask'.  If
321 the variable is t instead of `ask', use
322 `message-subject-trailing-was-regexp' instead.
323
324 It is okay to create some false positives here, as the user is asked."
325   :version "22.1"
326   :group 'message-various
327   :link '(custom-manual "(message)Message Headers")
328   :type 'regexp)
329
330 (defcustom message-subject-trailing-was-regexp
331   "[ \t]*\\((*[Ww][Aa][Ss]:[ \t]*.*)\\)"
332   "*Regexp matching \"(was: <old subject>)\" in the subject line.
333
334 If `message-subject-trailing-was-query' is set to t, the subject is
335 matched against `message-subject-trailing-was-regexp' in
336 `message-strip-subject-trailing-was'.  You should use a regexp creating very
337 few false positives here."
338   :version "22.1"
339   :group 'message-various
340   :link '(custom-manual "(message)Message Headers")
341   :type 'regexp)
342
343 ;;; marking inserted text
344
345 (defcustom message-mark-insert-begin
346   "--8<---------------cut here---------------start------------->8---\n"
347   "How to mark the beginning of some inserted text."
348   :version "22.1"
349   :type 'string
350   :link '(custom-manual "(message)Insertion Variables")
351   :group 'message-various)
352
353 (defcustom message-mark-insert-end
354   "--8<---------------cut here---------------end--------------->8---\n"
355   "How to mark the end of some inserted text."
356   :version "22.1"
357   :type 'string
358   :link '(custom-manual "(message)Insertion Variables")
359   :group 'message-various)
360
361 (defcustom message-archive-header "X-No-Archive: Yes\n"
362   "Header to insert when you don't want your article to be archived.
363 Archives \(such as groups.google.com\) respect this header."
364   :version "22.1"
365   :type 'string
366   :link '(custom-manual "(message)Header Commands")
367   :group 'message-various)
368
369 (defcustom message-archive-note
370   "X-No-Archive: Yes - save http://groups.google.com/"
371   "Note to insert why you wouldn't want this posting archived.
372 If nil, don't insert any text in the body."
373   :version "22.1"
374   :type '(radio string (const nil))
375   :link '(custom-manual "(message)Header Commands")
376   :group 'message-various)
377
378 ;;; Crossposts and Followups
379 ;; inspired by JoH-followup-to by Jochem Huhman <joh  at gmx.de>
380 ;; new suggestions by R. Weikusat <rw at another.de>
381
382 (defvar message-cross-post-old-target nil
383   "Old target for cross-posts or follow-ups.")
384 (make-variable-buffer-local 'message-cross-post-old-target)
385
386 (defcustom message-cross-post-default t
387   "When non-nil `message-cross-post-followup-to' will perform a crosspost.
388 If nil, `message-cross-post-followup-to' will only do a followup.  Note that
389 you can explicitly override this setting by calling
390 `message-cross-post-followup-to' with a prefix."
391   :version "22.1"
392   :type 'boolean
393   :group 'message-various)
394
395 (defcustom message-cross-post-note "Crosspost & Followup-To: "
396   "Note to insert before signature to notify of cross-post and follow-up."
397   :version "22.1"
398   :type 'string
399   :group 'message-various)
400
401 (defcustom message-followup-to-note "Followup-To: "
402   "Note to insert before signature to notify of follow-up only."
403   :version "22.1"
404   :type 'string
405   :group 'message-various)
406
407 (defcustom message-cross-post-note-function 'message-cross-post-insert-note
408   "Function to use to insert note about Crosspost or Followup-To.
409 The function will be called with four arguments.  The function should not only
410 insert a note, but also ensure old notes are deleted.  See the documentation
411 for `message-cross-post-insert-note'."
412   :version "22.1"
413   :type 'function
414   :group 'message-various)
415
416 ;;; End of variables adopted from `message-utils.el'.
417
418 (defcustom message-signature-separator "^-- $"
419   "Regexp matching the signature separator.
420 This variable is used to strip off the signature from quoted text
421 when `message-cite-function' is
422 `message-cite-original-without-signature'.  Most useful values
423 are \"^-- $\" (strict) and \"^-- *$\" (loose; allow missing
424 whitespace)."
425   :type '(choice (const :tag "strict" "^-- $")
426                  (const :tag "loose" "^-- *$")
427                  regexp)
428   :version "22.3" ;; Gnus 5.10.12 (changed default)
429   :link '(custom-manual "(message)Various Message Variables")
430   :group 'message-various)
431
432 (defcustom message-elide-ellipsis "\n[...]\n\n"
433   "*The string which is inserted for elided text."
434   :type 'string
435   :link '(custom-manual "(message)Various Commands")
436   :group 'message-various)
437
438 (defcustom message-interactive t
439   "Non-nil means when sending a message wait for and display errors.
440 nil means let mailer mail back a message to report errors."
441   :group 'message-sending
442   :group 'message-mail
443   :link '(custom-manual "(message)Sending Variables")
444   :type 'boolean)
445
446 (defcustom message-generate-new-buffers 'unique
447   "*Say whether to create a new message buffer to compose a message.
448 Valid values include:
449
450 nil
451   Generate the buffer name in the Message way (e.g., *mail*, *news*,
452   *mail to whom*, *news on group*, etc.) and continue editing in the
453   existing buffer of that name.  If there is no such buffer, it will
454   be newly created.
455
456 `unique' or t
457   Create the new buffer with the name generated in the Message way.
458
459 `unsent'
460   Similar to `unique' but the buffer name begins with \"*unsent \".
461
462 `standard'
463   Similar to nil but the buffer name is simpler like *mail message*.
464
465 function
466   If this is a function, call that function with three parameters:
467   The type, the To address and the group name (any of these may be nil).
468   The function should return the new buffer name."
469   :group 'message-buffers
470   :link '(custom-manual "(message)Message Buffers")
471   :type '(choice (const nil)
472                  (sexp :tag "unique" :format "unique\n" :value unique
473                        :match (lambda (widget value) (memq value '(unique t))))
474                  (const unsent)
475                  (const standard)
476                  (function :format "\n    %{%t%}: %v")))
477
478 (defcustom message-kill-buffer-on-exit nil
479   "*Non-nil means that the message buffer will be killed after sending a message."
480   :group 'message-buffers
481   :link '(custom-manual "(message)Message Buffers")
482   :type 'boolean)
483
484 (defcustom message-kill-buffer-query t
485   "*Non-nil means that killing a modified message buffer has to be confirmed.
486 This is used by `message-kill-buffer'."
487   :version "23.1" ;; No Gnus
488   :group 'message-buffers
489   :type 'boolean)
490
491 (defvar gnus-local-organization)
492 (defcustom message-user-organization
493   (or (and (boundp 'gnus-local-organization)
494            (stringp gnus-local-organization)
495            gnus-local-organization)
496       (getenv "ORGANIZATION")
497       t)
498   "*String to be used as an Organization header.
499 If t, use `message-user-organization-file'."
500   :group 'message-headers
501   :type '(choice string
502                  (const :tag "consult file" t)))
503
504 (defcustom message-user-organization-file
505   (let (orgfile)
506     (dolist (f (list "/etc/organization"
507                      "/etc/news/organization"
508                      "/usr/lib/news/organization"))
509       (when (file-readable-p f)
510         (setq orgfile f)))
511     orgfile)
512   "*Local news organization file."
513   :type 'file
514   :link '(custom-manual "(message)News Headers")
515   :group 'message-headers)
516
517 (defcustom message-make-forward-subject-function
518   #'message-forward-subject-name-subject
519   "*List of functions called to generate subject headers for forwarded messages.
520 The subject generated by the previous function is passed into each
521 successive function.
522
523 The provided functions are:
524
525 * `message-forward-subject-author-subject' Source of article (author or
526       newsgroup), in brackets followed by the subject
527 * `message-forward-subject-name-subject' Source of article (name of author
528       or newsgroup), in brackets followed by the subject
529 * `message-forward-subject-fwd' Subject of article with 'Fwd:' prepended
530       to it."
531   :group 'message-forwarding
532   :link '(custom-manual "(message)Forwarding")
533   :type '(radio (function-item message-forward-subject-author-subject)
534                 (function-item message-forward-subject-fwd)
535                 (function-item message-forward-subject-name-subject)
536                 (repeat :tag "List of functions" function)))
537
538 (defcustom message-forward-as-mime t
539   "*Non-nil means forward messages as an inline/rfc822 MIME section.
540 Otherwise, directly inline the old message in the forwarded message."
541   :version "21.1"
542   :group 'message-forwarding
543   :link '(custom-manual "(message)Forwarding")
544   :type 'boolean)
545
546 (defcustom message-forward-show-mml 'best
547   "*Non-nil means show forwarded messages as MML (decoded from MIME).
548 Otherwise, forwarded messages are unchanged.
549 Can also be the symbol `best' to indicate that MML should be
550 used, except when it is a bad idea to use MML.  One example where
551 it is a bad idea is when forwarding a signed or encrypted
552 message, because converting MIME to MML would invalidate the
553 digital signature."
554   :version "21.1"
555   :group 'message-forwarding
556   :type '(choice (const :tag "use MML" t)
557                  (const :tag "don't use MML " nil)
558                  (const :tag "use MML when appropriate" best)))
559
560 (defcustom message-forward-before-signature t
561   "*Non-nil means put forwarded message before signature, else after."
562   :group 'message-forwarding
563   :type 'boolean)
564
565 (defcustom message-wash-forwarded-subjects nil
566   "*Non-nil means try to remove as much cruft as possible from the subject.
567 Done before generating the new subject of a forward."
568   :group 'message-forwarding
569   :link '(custom-manual "(message)Forwarding")
570   :type 'boolean)
571
572 (defcustom message-ignored-resent-headers
573   ;; `Delivered-To' needs to be removed because some mailers use it to
574   ;; detect loops, so if you resend a message to an address that ultimately
575   ;; comes back to you (e.g. a mailing-list to which you subscribe, in which
576   ;; case you may be removed from the list on the grounds that mail to you
577   ;; bounced with a "mailing loop" error).
578   "^Return-receipt\\|^X-Gnus\\|^Gnus-Warning:\\|^>?From \\|^Delivered-To:"
579   "*All headers that match this regexp will be deleted when resending a message."
580   :group 'message-interface
581   :link '(custom-manual "(message)Resending")
582   :type '(repeat :value-to-internal (lambda (widget value)
583                                       (custom-split-regexp-maybe value))
584                  :match (lambda (widget value)
585                           (or (stringp value)
586                               (widget-editable-list-match widget value)))
587                  regexp))
588
589 (defcustom message-forward-ignored-headers "^Content-Transfer-Encoding:\\|^X-Gnus"
590   "*All headers that match this regexp will be deleted when forwarding a message."
591   :version "21.1"
592   :group 'message-forwarding
593   :type '(repeat :value-to-internal (lambda (widget value)
594                                       (custom-split-regexp-maybe value))
595                  :match (lambda (widget value)
596                           (or (stringp value)
597                               (widget-editable-list-match widget value)))
598                  regexp))
599
600 (defcustom message-ignored-cited-headers "."
601   "*Delete these headers from the messages you yank."
602   :group 'message-insertion
603   :link '(custom-manual "(message)Insertion Variables")
604   :type 'regexp)
605
606 (defcustom message-cite-prefix-regexp
607   (if (string-match "[[:digit:]]" "1")
608       ;; Support POSIX?  XEmacs 21.5.27 doesn't.
609       "\\([ \t]*[_.[:word:]]+>+\\|[ \t]*[]>|}]\\)+"
610     ;; ?-, ?_ or ?. MUST NOT be in syntax entry w.
611     (let (non-word-constituents)
612       (with-syntax-table text-mode-syntax-table
613         (setq non-word-constituents
614               (concat
615                (if (string-match "\\w" "_")  "" "_")
616                (if (string-match "\\w" ".")  "" "."))))
617       (if (equal non-word-constituents "")
618           "\\([ \t]*\\(\\w\\)+>+\\|[ \t]*[]>|}]\\)+"
619         (concat "\\([ \t]*\\(\\w\\|["
620                 non-word-constituents
621                 "]\\)+>+\\|[ \t]*[]>|}]\\)+"))))
622   "*Regexp matching the longest possible citation prefix on a line."
623   :version "22.1"
624   :group 'message-insertion
625   :link '(custom-manual "(message)Insertion Variables")
626   :type 'regexp
627   :set (lambda (symbol value)
628          (prog1
629              (custom-set-default symbol value)
630            (if (boundp 'gnus-message-cite-prefix-regexp)
631                (setq gnus-message-cite-prefix-regexp
632                      (concat "^\\(?:" value "\\)"))))))
633
634 (defcustom message-cancel-message "I am canceling my own article.\n"
635   "Message to be inserted in the cancel message."
636   :group 'message-interface
637   :link '(custom-manual "(message)Canceling News")
638   :type 'string)
639
640 (defvar smtpmail-default-smtp-server)
641
642 (defun message-send-mail-function ()
643   "Return suitable value for the variable `message-send-mail-function'."
644   (cond ((and (require 'sendmail)
645               (boundp 'sendmail-program)
646               sendmail-program
647               (executable-find sendmail-program))
648          'message-send-mail-with-sendmail)
649         ((and (locate-library "smtpmail")
650               (require 'smtpmail)
651               smtpmail-default-smtp-server)
652          'message-smtpmail-send-it)
653         ((locate-library "mailclient")
654          'message-send-mail-with-mailclient)
655         (t
656          (lambda ()
657            (error "Don't know how to send mail.  Please customize `message-send-mail-function'")))))
658
659 ;; Useful to set in site-init.el
660 (defcustom message-send-mail-function (message-send-mail-function)
661   "Function to call to send the current buffer as mail.
662 The headers should be delimited by a line whose contents match the
663 variable `mail-header-separator'.
664
665 Valid values include `message-send-mail-with-sendmail'
666 `message-send-mail-with-mh', `message-send-mail-with-qmail',
667 `message-smtpmail-send-it', `smtpmail-send-it',
668 `feedmail-send-it' and `message-send-mail-with-mailclient'.  The
669 default is system dependent and determined by the function
670 `message-send-mail-function'.
671
672 See also `send-mail-function'."
673   :type '(radio (function-item message-send-mail-with-sendmail)
674                 (function-item message-send-mail-with-mh)
675                 (function-item message-send-mail-with-qmail)
676                 (function-item message-smtpmail-send-it)
677                 (function-item smtpmail-send-it)
678                 (function-item feedmail-send-it)
679                 (function-item message-send-mail-with-mailclient
680                                :tag "Use Mailclient package")
681                 (function :tag "Other"))
682   :group 'message-sending
683   :version "23.1" ;; No Gnus
684   :initialize 'custom-initialize-default
685   :link '(custom-manual "(message)Mail Variables")
686   :group 'message-mail)
687
688 (defcustom message-send-news-function 'message-send-news
689   "Function to call to send the current buffer as news.
690 The headers should be delimited by a line whose contents match the
691 variable `mail-header-separator'."
692   :group 'message-sending
693   :group 'message-news
694   :link '(custom-manual "(message)News Variables")
695   :type 'function)
696
697 (defcustom message-reply-to-function nil
698   "If non-nil, function that should return a list of headers.
699 This function should pick out addresses from the To, Cc, and From headers
700 and respond with new To and Cc headers."
701   :group 'message-interface
702   :link '(custom-manual "(message)Reply")
703   :type '(choice function (const nil)))
704
705 (defcustom message-wide-reply-to-function nil
706   "If non-nil, function that should return a list of headers.
707 This function should pick out addresses from the To, Cc, and From headers
708 and respond with new To and Cc headers."
709   :group 'message-interface
710   :link '(custom-manual "(message)Wide Reply")
711   :type '(choice function (const nil)))
712
713 (defcustom message-followup-to-function nil
714   "If non-nil, function that should return a list of headers.
715 This function should pick out addresses from the To, Cc, and From headers
716 and respond with new To and Cc headers."
717   :group 'message-interface
718   :link '(custom-manual "(message)Followup")
719   :type '(choice function (const nil)))
720
721 (defcustom message-extra-wide-headers nil
722   "If non-nil, a list of additional address headers.
723 These are used when composing a wide reply."
724   :group 'message-sending
725   :type '(repeat string))
726
727 (defcustom message-use-followup-to 'ask
728   "*Specifies what to do with Followup-To header.
729 If nil, always ignore the header.  If it is t, use its value, but
730 query before using the \"poster\" value.  If it is the symbol `ask',
731 always query the user whether to use the value.  If it is the symbol
732 `use', always use the value."
733   :group 'message-interface
734   :link '(custom-manual "(message)Followup")
735   :type '(choice (const :tag "ignore" nil)
736                  (const :tag "use & query" t)
737                  (const use)
738                  (const ask)))
739
740 (defcustom message-use-mail-followup-to 'use
741   "*Specifies what to do with Mail-Followup-To header.
742 If nil, always ignore the header.  If it is the symbol `ask', always
743 query the user whether to use the value.  If it is the symbol `use',
744 always use the value."
745   :version "22.1"
746   :group 'message-interface
747   :link '(custom-manual "(message)Mailing Lists")
748   :type '(choice (const :tag "ignore" nil)
749                  (const use)
750                  (const ask)))
751
752 (defcustom message-subscribed-address-functions nil
753   "*Specifies functions for determining list subscription.
754 If nil, do not attempt to determine list subscription with functions.
755 If non-nil, this variable contains a list of functions which return
756 regular expressions to match lists.  These functions can be used in
757 conjunction with `message-subscribed-regexps' and
758 `message-subscribed-addresses'."
759   :version "22.1"
760   :group 'message-interface
761   :link '(custom-manual "(message)Mailing Lists")
762   :type '(repeat sexp))
763
764 (defcustom message-subscribed-address-file nil
765   "*A file containing addresses the user is subscribed to.
766 If nil, do not look at any files to determine list subscriptions.  If
767 non-nil, each line of this file should be a mailing list address."
768   :version "22.1"
769   :group 'message-interface
770   :link '(custom-manual "(message)Mailing Lists")
771   :type '(radio file (const nil)))
772
773 (defcustom message-subscribed-addresses nil
774   "*Specifies a list of addresses the user is subscribed to.
775 If nil, do not use any predefined list subscriptions.  This list of
776 addresses can be used in conjunction with
777 `message-subscribed-address-functions' and `message-subscribed-regexps'."
778   :version "22.1"
779   :group 'message-interface
780   :link '(custom-manual "(message)Mailing Lists")
781   :type '(repeat string))
782
783 (defcustom message-subscribed-regexps nil
784   "*Specifies a list of addresses the user is subscribed to.
785 If nil, do not use any predefined list subscriptions.  This list of
786 regular expressions can be used in conjunction with
787 `message-subscribed-address-functions' and `message-subscribed-addresses'."
788   :version "22.1"
789   :group 'message-interface
790   :link '(custom-manual "(message)Mailing Lists")
791   :type '(repeat regexp))
792
793 (defcustom message-allow-no-recipients 'ask
794   "Specifies what to do when there are no recipients other than Gcc/Fcc.
795 If it is the symbol `always', the posting is allowed.  If it is the
796 symbol `never', the posting is not allowed.  If it is the symbol
797 `ask', you are prompted."
798   :version "22.1"
799   :group 'message-interface
800   :link '(custom-manual "(message)Message Headers")
801   :type '(choice (const always)
802                  (const never)
803                  (const ask)))
804
805 (defcustom message-sendmail-f-is-evil nil
806   "*Non-nil means don't add \"-f username\" to the sendmail command line.
807 Doing so would be even more evil than leaving it out."
808   :group 'message-sending
809   :link '(custom-manual "(message)Mail Variables")
810   :type 'boolean)
811
812 (defcustom message-sendmail-envelope-from nil
813   "*Envelope-from when sending mail with sendmail.
814 If this is nil, use `user-mail-address'.  If it is the symbol
815 `header', use the From: header of the message."
816   :version "22.1"
817   :type '(choice (string :tag "From name")
818                  (const :tag "Use From: header from message" header)
819                  (const :tag "Use `user-mail-address'" nil))
820   :link '(custom-manual "(message)Mail Variables")
821   :group 'message-sending)
822
823 (defcustom message-sendmail-extra-arguments nil
824   "Additional arguments to `sendmail-program'."
825   ;; E.g. '("-a" "account") for msmtp
826   :version "23.1" ;; No Gnus
827   :type '(repeat string)
828   ;; :link '(custom-manual "(message)Mail Variables")
829   :group 'message-sending)
830
831 ;; qmail-related stuff
832 (defcustom message-qmail-inject-program "/var/qmail/bin/qmail-inject"
833   "Location of the qmail-inject program."
834   :group 'message-sending
835   :link '(custom-manual "(message)Mail Variables")
836   :type 'file)
837
838 (defcustom message-qmail-inject-args nil
839   "Arguments passed to qmail-inject programs.
840 This should be a list of strings, one string for each argument.  It
841 may also be a function.
842
843 For e.g., if you wish to set the envelope sender address so that bounces
844 go to the right place or to deal with listserv's usage of that address, you
845 might set this variable to '(\"-f\" \"you@some.where\")."
846   :group 'message-sending
847   :link '(custom-manual "(message)Mail Variables")
848   :type '(choice (function)
849                  (repeat string)))
850
851 (defvar gnus-post-method)
852 (defvar gnus-select-method)
853 (defcustom message-post-method
854   (cond ((and (boundp 'gnus-post-method)
855               (listp gnus-post-method)
856               gnus-post-method)
857          gnus-post-method)
858         ((boundp 'gnus-select-method)
859          gnus-select-method)
860         (t '(nnspool "")))
861   "*Method used to post news.
862 Note that when posting from inside Gnus, for instance, this
863 variable isn't used."
864   :group 'message-news
865   :group 'message-sending
866   ;; This should be the `gnus-select-method' widget, but that might
867   ;; create a dependence to `gnus.el'.
868   :type 'sexp)
869
870 ;; FIXME: This should be a temporary workaround until someone implements a
871 ;; proper solution.  If a crash happens while replying, the auto-save file
872 ;; will *not* have a `References:' header if `message-generate-headers-first'
873 ;; is nil.  See: http://article.gmane.org/gmane.emacs.gnus.general/51138
874 (defcustom message-generate-headers-first '(references)
875   "Which headers should be generated before starting to compose a message.
876 If t, generate all required headers.  This can also be a list of headers to
877 generate.  The variables `message-required-news-headers' and
878 `message-required-mail-headers' specify which headers to generate.
879
880 Note that the variable `message-deletable-headers' specifies headers which
881 are to be deleted and then re-generated before sending, so this variable
882 will not have a visible effect for those headers."
883   :group 'message-headers
884   :link '(custom-manual "(message)Message Headers")
885   :type '(choice (const :tag "None" nil)
886                  (const :tag "References" '(references))
887                  (const :tag "All" t)
888                  (repeat (sexp :tag "Header"))))
889
890 (defcustom message-fill-column 72
891   "Column beyond which automatic line-wrapping should happen.
892 Local value for message buffers.  If non-nil, also turn on
893 auto-fill in message buffers."
894   :group 'message-various
895   ;; :link '(custom-manual "(message)Message Headers")
896   :type '(choice (const :tag "Don't turn on auto fill" nil)
897                  (integer)))
898
899 (defcustom message-setup-hook nil
900   "Normal hook, run each time a new outgoing message is initialized.
901 The function `message-setup' runs this hook."
902   :group 'message-various
903   :link '(custom-manual "(message)Various Message Variables")
904   :type 'hook)
905
906 (defcustom message-cancel-hook nil
907   "Hook run when cancelling articles."
908   :group 'message-various
909   :link '(custom-manual "(message)Various Message Variables")
910   :type 'hook)
911
912 (defcustom message-signature-setup-hook nil
913   "Normal hook, run each time a new outgoing message is initialized.
914 It is run after the headers have been inserted and before
915 the signature is inserted."
916   :group 'message-various
917   :link '(custom-manual "(message)Various Message Variables")
918   :type 'hook)
919
920 (defcustom message-mode-hook nil
921   "Hook run in message mode buffers."
922   :group 'message-various
923   :type 'hook)
924
925 (defcustom message-header-hook nil
926   "Hook run in a message mode buffer narrowed to the headers."
927   :group 'message-various
928   :type 'hook)
929
930 (defcustom message-header-setup-hook nil
931   "Hook called narrowed to the headers when setting up a message buffer."
932   :group 'message-various
933   :link '(custom-manual "(message)Various Message Variables")
934   :type 'hook)
935
936 (defcustom message-minibuffer-local-map
937   (let ((map (make-sparse-keymap 'message-minibuffer-local-map)))
938     (set-keymap-parent map minibuffer-local-map)
939     map)
940   "Keymap for `message-read-from-minibuffer'."
941   :version "22.1"
942   :group 'message-various)
943
944 (defcustom message-citation-line-function 'message-insert-citation-line
945   "*Function called to insert the \"Whomever writes:\" line.
946
947 Predefined functions include `message-insert-citation-line' and
948 `message-insert-formatted-citation-line' (see the variable
949 `message-citation-line-format').
950
951 Note that Gnus provides a feature where the reader can click on
952 `writes:' to hide the cited text.  If you change this line too much,
953 people who read your message will have to change their Gnus
954 configuration.  See the variable `gnus-cite-attribution-suffix'."
955   :type '(choice
956           (function-item :tag "plain" message-insert-citation-line)
957           (function-item :tag "formatted" message-insert-formatted-citation-line)
958           (function :tag "Other"))
959   :link '(custom-manual "(message)Insertion Variables")
960   :group 'message-insertion)
961
962 (defcustom message-citation-line-format "On %a, %b %d %Y, %N wrote:\n"
963   "Format of the \"Whomever writes:\" line.
964
965 The string is formatted using `format-spec'.  The following
966 constructs are replaced:
967
968   %f   The full From, e.g. \"John Doe <john.doe@example.invalid>\".
969   %n   The mail address, e.g. \"john.doe@example.invalid\".
970   %N   The real name if present, e.g.: \"John Doe\", else fall
971        back to the mail address.
972   %F   The first name if present, e.g.: \"John\".
973   %L   The last name if present, e.g.: \"Doe\".
974
975 All other format specifiers are passed to `format-time-string'
976 which is called using the date from the article your replying to.
977 Extracting the first (%F) and last name (%L) is done
978 heuristically, so you should always check it yourself.
979
980 Please also read the note in the documentation of
981 `message-citation-line-function'."
982   :type '(choice (const :tag "Plain" "%f writes:")
983                  (const :tag "Include date" "On %a, %b %d %Y, %n wrote:")
984                  string)
985   :link '(custom-manual "(message)Insertion Variables")
986   :version "23.1" ;; No Gnus
987   :group 'message-insertion)
988
989 (defcustom message-yank-prefix "> "
990   "*Prefix inserted on the lines of yanked messages.
991 Fix `message-cite-prefix-regexp' if it is set to an abnormal value.
992 See also `message-yank-cited-prefix' and `message-yank-empty-prefix'."
993   :type 'string
994   :link '(custom-manual "(message)Insertion Variables")
995   :group 'message-insertion)
996
997 (defcustom message-yank-cited-prefix ">"
998   "*Prefix inserted on cited lines of yanked messages.
999 Fix `message-cite-prefix-regexp' if it is set to an abnormal value.
1000 See also `message-yank-prefix' and `message-yank-empty-prefix'."
1001   :version "22.1"
1002   :type 'string
1003   :link '(custom-manual "(message)Insertion Variables")
1004   :group 'message-insertion)
1005
1006 (defcustom message-yank-empty-prefix ">"
1007   "*Prefix inserted on empty lines of yanked messages.
1008 See also `message-yank-prefix' and `message-yank-cited-prefix'."
1009   :version "22.1"
1010   :type 'string
1011   :link '(custom-manual "(message)Insertion Variables")
1012   :group 'message-insertion)
1013
1014 (defcustom message-indentation-spaces 3
1015   "*Number of spaces to insert at the beginning of each cited line.
1016 Used by `message-yank-original' via `message-yank-cite'."
1017   :group 'message-insertion
1018   :link '(custom-manual "(message)Insertion Variables")
1019   :type 'integer)
1020
1021 (defcustom message-cite-function 'message-cite-original-without-signature
1022   "*Function for citing an original message.
1023 Predefined functions include `message-cite-original' and
1024 `message-cite-original-without-signature'.
1025 Note that these functions use `mail-citation-hook' if that is non-nil."
1026   :type '(radio (function-item message-cite-original)
1027                 (function-item message-cite-original-without-signature)
1028                 (function-item sc-cite-original)
1029                 (function :tag "Other"))
1030   :link '(custom-manual "(message)Insertion Variables")
1031   :version "22.3" ;; Gnus 5.10.12 (changed default)
1032   :group 'message-insertion)
1033
1034 (defcustom message-indent-citation-function 'message-indent-citation
1035   "*Function for modifying a citation just inserted in the mail buffer.
1036 This can also be a list of functions.  Each function can find the
1037 citation between (point) and (mark t).  And each function should leave
1038 point and mark around the citation text as modified."
1039   :type 'function
1040   :link '(custom-manual "(message)Insertion Variables")
1041   :group 'message-insertion)
1042
1043 (defcustom message-signature t
1044   "*String to be inserted at the end of the message buffer.
1045 If t, the `message-signature-file' file will be inserted instead.
1046 If a function, the result from the function will be used instead.
1047 If a form, the result from the form will be used instead."
1048   :type 'sexp
1049   :link '(custom-manual "(message)Insertion Variables")
1050   :group 'message-insertion)
1051
1052 (defcustom message-signature-file "~/.signature"
1053   "*Name of file containing the text inserted at end of message buffer.
1054 Ignored if the named file doesn't exist.
1055 If nil, don't insert a signature.
1056 If a path is specified, the value of `message-signature-directory' is ignored,
1057 even if set."
1058   :type '(choice file (const :tags "None" nil))
1059   :link '(custom-manual "(message)Insertion Variables")
1060   :group 'message-insertion)
1061
1062 (defcustom message-signature-directory nil
1063   "*Name of directory containing signature files.
1064 Comes in handy if you have many such files, handled via posting styles for
1065 instance.
1066 If nil, `message-signature-file' is expected to specify the directory if
1067 needed."
1068   :type '(choice string (const :tags "None" nil))
1069   :link '(custom-manual "(message)Insertion Variables")
1070   :group 'message-insertion)
1071
1072 (defcustom message-signature-insert-empty-line t
1073   "*If non-nil, insert an empty line before the signature separator."
1074   :version "22.1"
1075   :type 'boolean
1076   :link '(custom-manual "(message)Insertion Variables")
1077   :group 'message-insertion)
1078
1079 (defcustom message-distribution-function nil
1080   "*Function called to return a Distribution header."
1081   :group 'message-news
1082   :group 'message-headers
1083   :link '(custom-manual "(message)News Headers")
1084   :type '(choice function (const nil)))
1085
1086 (defcustom message-expires 14
1087   "Number of days before your article expires."
1088   :group 'message-news
1089   :group 'message-headers
1090   :link '(custom-manual "(message)News Headers")
1091   :type 'integer)
1092
1093 (defcustom message-user-path nil
1094   "If nil, use the NNTP server name in the Path header.
1095 If stringp, use this; if non-nil, use no host name (user name only)."
1096   :group 'message-news
1097   :group 'message-headers
1098   :link '(custom-manual "(message)News Headers")
1099   :type '(choice (const :tag "nntp" nil)
1100                  (string :tag "name")
1101                  (sexp :tag "none" :format "%t" t)))
1102
1103 (defvar message-reply-buffer nil)
1104 (defvar message-reply-headers nil
1105   "The headers of the current replied article.
1106 It is a vector of the following headers:
1107 \[number subject from date id references chars lines xref extra].")
1108 (defvar message-newsreader nil)
1109 (defvar message-mailer nil)
1110 (defvar message-sent-message-via nil)
1111 (defvar message-checksum nil)
1112 (defvar message-send-actions nil
1113   "A list of actions to be performed upon successful sending of a message.")
1114 (defvar message-exit-actions nil
1115   "A list of actions to be performed upon exiting after sending a message.")
1116 (defvar message-kill-actions nil
1117   "A list of actions to be performed before killing a message buffer.")
1118 (defvar message-postpone-actions nil
1119   "A list of actions to be performed after postponing a message.")
1120
1121 (define-widget 'message-header-lines 'text
1122   "All header lines must be LFD terminated."
1123   :format "%{%t%}:%n%v"
1124   :valid-regexp "^\\'"
1125   :error "All header lines must be newline terminated")
1126
1127 (defcustom message-default-headers ""
1128   "*A string containing header lines to be inserted in outgoing messages.
1129 It is inserted before you edit the message, so you can edit or delete
1130 these lines."
1131   :group 'message-headers
1132   :link '(custom-manual "(message)Message Headers")
1133   :type 'message-header-lines)
1134
1135 (defcustom message-default-mail-headers ""
1136   "*A string of header lines to be inserted in outgoing mails."
1137   :group 'message-headers
1138   :group 'message-mail
1139   :link '(custom-manual "(message)Mail Headers")
1140   :type 'message-header-lines)
1141
1142 (defcustom message-default-news-headers ""
1143   "*A string of header lines to be inserted in outgoing news articles."
1144   :group 'message-headers
1145   :group 'message-news
1146   :link '(custom-manual "(message)News Headers")
1147   :type 'message-header-lines)
1148
1149 ;; Note: could use /usr/ucb/mail instead of sendmail;
1150 ;; options -t, and -v if not interactive.
1151 (defcustom message-mailer-swallows-blank-line
1152   (if (and (string-match "sparc-sun-sunos\\(\\'\\|[^5]\\)"
1153                          system-configuration)
1154            (file-readable-p "/etc/sendmail.cf")
1155            (let ((buffer (get-buffer-create " *temp*")))
1156              (unwind-protect
1157                  (with-current-buffer buffer
1158                    (insert-file-contents "/etc/sendmail.cf")
1159                    (goto-char (point-min))
1160                    (let ((case-fold-search nil))
1161                      (re-search-forward "^OR\\>" nil t)))
1162                (kill-buffer buffer))))
1163       ;; According to RFC822, "The field-name must be composed of printable
1164       ;; ASCII characters (i. e., characters that have decimal values between
1165       ;; 33 and 126, except colon)", i. e., any chars except ctl chars,
1166       ;; space, or colon.
1167       '(looking-at "[ \t]\\|[][!\"#$%&'()*+,-./0-9;<=>?@A-Z\\\\^_`a-z{|}~]+:"))
1168   "*Set this non-nil if the system's mailer runs the header and body together.
1169 \(This problem exists on Sunos 4 when sendmail is run in remote mode.)
1170 The value should be an expression to test whether the problem will
1171 actually occur."
1172   :group 'message-sending
1173   :link '(custom-manual "(message)Mail Variables")
1174   :type 'sexp)
1175
1176 ;;;###autoload
1177 (define-mail-user-agent 'message-user-agent
1178   'message-mail 'message-send-and-exit
1179   'message-kill-buffer 'message-send-hook)
1180
1181 (defvar message-mh-deletable-headers '(Message-ID Date Lines Sender)
1182   "If non-nil, delete the deletable headers before feeding to mh.")
1183
1184 (defvar message-send-method-alist
1185   '((news message-news-p message-send-via-news)
1186     (mail message-mail-p message-send-via-mail))
1187   "Alist of ways to send outgoing messages.
1188 Each element has the form
1189
1190   \(TYPE PREDICATE FUNCTION)
1191
1192 where TYPE is a symbol that names the method; PREDICATE is a function
1193 called without any parameters to determine whether the message is
1194 a message of type TYPE; and FUNCTION is a function to be called if
1195 PREDICATE returns non-nil.  FUNCTION is called with one parameter --
1196 the prefix.")
1197
1198 (defcustom message-mail-alias-type 'abbrev
1199   "*What alias expansion type to use in Message buffers.
1200 The default is `abbrev', which uses mailabbrev.  `ecomplete' uses
1201 an electric completion mode.  nil switches mail aliases off.
1202 This can also be a list of values."
1203   :group 'message
1204   :link '(custom-manual "(message)Mail Aliases")
1205   :type '(choice (const :tag "Use Mailabbrev" abbrev)
1206                  (const :tag "Use ecomplete" ecomplete)
1207                  (const :tag "No expansion" nil)))
1208
1209 (defcustom message-self-insert-commands '(self-insert-command)
1210   "List of `self-insert-command's used to trigger ecomplete.
1211 When one of those commands is invoked to enter a character in To or Cc
1212 header, ecomplete will suggest the candidates of recipients (see also
1213 `message-mail-alias-type').  If you use some tool to enter non-ASCII
1214 text and it replaces `self-insert-command' with the other command, e.g.
1215 `egg-self-insert-command', you may want to add it to this list."
1216   :group 'message-various
1217   :type '(repeat function))
1218
1219 (defcustom message-auto-save-directory
1220   (file-name-as-directory (nnheader-concat message-directory "drafts"))
1221   "*Directory where Message auto-saves buffers if Gnus isn't running.
1222 If nil, Message won't auto-save."
1223   :group 'message-buffers
1224   :link '(custom-manual "(message)Various Message Variables")
1225   :type '(choice directory (const :tag "Don't auto-save" nil)))
1226
1227 (defcustom message-default-charset
1228   (and (not (mm-multibyte-p)) 'iso-8859-1)
1229   "Default charset used in non-MULE Emacsen.
1230 If nil, you might be asked to input the charset."
1231   :version "21.1"
1232   :group 'message
1233   :link '(custom-manual "(message)Various Message Variables")
1234   :type 'symbol)
1235
1236 (defcustom message-dont-reply-to-names
1237   (and (boundp 'rmail-dont-reply-to-names) rmail-dont-reply-to-names)
1238   "*Addresses to prune when doing wide replies.
1239 This can be a regexp or a list of regexps.  Also, a value of nil means
1240 exclude your own user name only."
1241   :version "21.1"
1242   :group 'message
1243   :link '(custom-manual "(message)Wide Reply")
1244   :type '(choice (const :tag "Yourself" nil)
1245                  regexp
1246                  (repeat :tag "Regexp List" regexp)))
1247
1248 (defsubst message-dont-reply-to-names ()
1249   (gmm-regexp-concat message-dont-reply-to-names))
1250
1251 (defvar message-shoot-gnksa-feet nil
1252   "*A list of GNKSA feet you are allowed to shoot.
1253 Gnus gives you all the opportunity you could possibly want for
1254 shooting yourself in the foot.  Also, Gnus allows you to shoot the
1255 feet of Good Net-Keeping Seal of Approval.  The following are foot
1256 candidates:
1257 `empty-article'     Allow you to post an empty article;
1258 `quoted-text-only'  Allow you to post quoted text only;
1259 `multiple-copies'   Allow you to post multiple copies;
1260 `cancel-messages'   Allow you to cancel or supersede messages from
1261                     your other email addresses.")
1262
1263 (defsubst message-gnksa-enable-p (feature)
1264   (or (not (listp message-shoot-gnksa-feet))
1265       (memq feature message-shoot-gnksa-feet)))
1266
1267 (defcustom message-hidden-headers '("^References:" "^Face:" "^X-Face:"
1268                                     "^X-Draft-From:")
1269   "Regexp of headers to be hidden when composing new messages.
1270 This can also be a list of regexps to match headers.  Or a list
1271 starting with `not' and followed by regexps."
1272   :version "22.1"
1273   :group 'message
1274   :link '(custom-manual "(message)Message Headers")
1275   :type '(choice
1276           :format "%{%t%}: %[Value Type%] %v"
1277           (regexp :menu-tag "regexp" :format "regexp\n%t: %v")
1278           (repeat :menu-tag "(regexp ...)" :format "(regexp ...)\n%v%i"
1279                   (regexp :format "%t: %v"))
1280           (cons :menu-tag "(not regexp ...)" :format "(not regexp ...)\n%v"
1281                 (const not)
1282                 (repeat :format "%v%i"
1283                         (regexp :format "%t: %v")))))
1284
1285 (defcustom message-cite-articles-with-x-no-archive t
1286   "If non-nil, cite text from articles that has X-No-Archive set."
1287   :group 'message
1288   :type 'boolean)
1289
1290 ;;; Internal variables.
1291 ;;; Well, not really internal.
1292
1293 (defvar message-mode-syntax-table
1294   (let ((table (copy-syntax-table text-mode-syntax-table)))
1295     (modify-syntax-entry ?% ". " table)
1296     (modify-syntax-entry ?> ". " table)
1297     (modify-syntax-entry ?< ". " table)
1298     table)
1299   "Syntax table used while in Message mode.")
1300
1301 (defface message-header-to
1302   '((((class color)
1303       (background dark))
1304      (:foreground "DarkOliveGreen1" :bold t))
1305     (((class color)
1306       (background light))
1307      (:foreground "MidnightBlue" :bold t))
1308     (t
1309      (:bold t :italic t)))
1310   "Face used for displaying From headers."
1311   :group 'message-faces)
1312 ;; backward-compatibility alias
1313 (put 'message-header-to-face 'face-alias 'message-header-to)
1314
1315 (defface message-header-cc
1316   '((((class color)
1317       (background dark))
1318      (:foreground "chartreuse1" :bold t))
1319     (((class color)
1320       (background light))
1321      (:foreground "MidnightBlue"))
1322     (t
1323      (:bold t)))
1324   "Face used for displaying Cc headers."
1325   :group 'message-faces)
1326 ;; backward-compatibility alias
1327 (put 'message-header-cc-face 'face-alias 'message-header-cc)
1328
1329 (defface message-header-subject
1330   '((((class color)
1331       (background dark))
1332      (:foreground "OliveDrab1"))
1333     (((class color)
1334       (background light))
1335      (:foreground "navy blue" :bold t))
1336     (t
1337      (:bold t)))
1338   "Face used for displaying subject headers."
1339   :group 'message-faces)
1340 ;; backward-compatibility alias
1341 (put 'message-header-subject-face 'face-alias 'message-header-subject)
1342
1343 (defface message-header-newsgroups
1344   '((((class color)
1345       (background dark))
1346      (:foreground "yellow" :bold t :italic t))
1347     (((class color)
1348       (background light))
1349      (:foreground "blue4" :bold t :italic t))
1350     (t
1351      (:bold t :italic t)))
1352   "Face used for displaying newsgroups headers."
1353   :group 'message-faces)
1354 ;; backward-compatibility alias
1355 (put 'message-header-newsgroups-face 'face-alias 'message-header-newsgroups)
1356
1357 (defface message-header-other
1358   '((((class color)
1359       (background dark))
1360      (:foreground "VioletRed1"))
1361     (((class color)
1362       (background light))
1363      (:foreground "steel blue"))
1364     (t
1365      (:bold t :italic t)))
1366   "Face used for displaying newsgroups headers."
1367   :group 'message-faces)
1368 ;; backward-compatibility alias
1369 (put 'message-header-other-face 'face-alias 'message-header-other)
1370
1371 (defface message-header-name
1372   '((((class color)
1373       (background dark))
1374      (:foreground "green"))
1375     (((class color)
1376       (background light))
1377      (:foreground "cornflower blue"))
1378     (t
1379      (:bold t)))
1380   "Face used for displaying header names."
1381   :group 'message-faces)
1382 ;; backward-compatibility alias
1383 (put 'message-header-name-face 'face-alias 'message-header-name)
1384
1385 (defface message-header-xheader
1386   '((((class color)
1387       (background dark))
1388      (:foreground "DeepSkyBlue1"))
1389     (((class color)
1390       (background light))
1391      (:foreground "blue"))
1392     (t
1393      (:bold t)))
1394   "Face used for displaying X-Header headers."
1395   :group 'message-faces)
1396 ;; backward-compatibility alias
1397 (put 'message-header-xheader-face 'face-alias 'message-header-xheader)
1398
1399 (defface message-separator
1400   '((((class color)
1401       (background dark))
1402      (:foreground "LightSkyBlue1"))
1403     (((class color)
1404       (background light))
1405      (:foreground "brown"))
1406     (t
1407      (:bold t)))
1408   "Face used for displaying the separator."
1409   :group 'message-faces)
1410 ;; backward-compatibility alias
1411 (put 'message-separator-face 'face-alias 'message-separator)
1412
1413 (defface message-cited-text
1414   '((((class color)
1415       (background dark))
1416      (:foreground "LightPink1"))
1417     (((class color)
1418       (background light))
1419      (:foreground "red"))
1420     (t
1421      (:bold t)))
1422   "Face used for displaying cited text names."
1423   :group 'message-faces)
1424 ;; backward-compatibility alias
1425 (put 'message-cited-text-face 'face-alias 'message-cited-text)
1426
1427 (defface message-mml
1428   '((((class color)
1429       (background dark))
1430      (:foreground "MediumSpringGreen"))
1431     (((class color)
1432       (background light))
1433      (:foreground "ForestGreen"))
1434     (t
1435      (:bold t)))
1436   "Face used for displaying MML."
1437   :group 'message-faces)
1438 ;; backward-compatibility alias
1439 (put 'message-mml-face 'face-alias 'message-mml)
1440
1441 (defun message-font-lock-make-header-matcher (regexp)
1442   (let ((form
1443          `(lambda (limit)
1444             (let ((start (point)))
1445               (save-restriction
1446                 (widen)
1447                 (goto-char (point-min))
1448                 (if (re-search-forward
1449                      (concat "^" (regexp-quote mail-header-separator) "$")
1450                      nil t)
1451                     (setq limit (min limit (match-beginning 0))))
1452                 (goto-char start))
1453               (and (< start limit)
1454                    (re-search-forward ,regexp limit t))))))
1455     (if (featurep 'bytecomp)
1456         (byte-compile form)
1457       form)))
1458
1459 (defvar message-font-lock-keywords
1460   (let ((content "[ \t]*\\(.+\\(\n[ \t].*\\)*\\)\n?"))
1461     `((,(message-font-lock-make-header-matcher
1462          (concat "^\\([Tt]o:\\)" content))
1463        (1 'message-header-name)
1464        (2 'message-header-to nil t))
1465       (,(message-font-lock-make-header-matcher
1466          (concat "^\\(^[GBF]?[Cc][Cc]:\\|^[Rr]eply-[Tt]o:\\)" content))
1467        (1 'message-header-name)
1468        (2 'message-header-cc nil t))
1469       (,(message-font-lock-make-header-matcher
1470          (concat "^\\([Ss]ubject:\\)" content))
1471        (1 'message-header-name)
1472        (2 'message-header-subject nil t))
1473       (,(message-font-lock-make-header-matcher
1474          (concat "^\\([Nn]ewsgroups:\\|Followup-[Tt]o:\\)" content))
1475        (1 'message-header-name)
1476        (2 'message-header-newsgroups nil t))
1477       (,(message-font-lock-make-header-matcher
1478          (concat "^\\(X-[A-Za-z0-9-]+:\\|In-Reply-To:\\)" content))
1479        (1 'message-header-name)
1480        (2 'message-header-xheader))
1481       (,(message-font-lock-make-header-matcher
1482          (concat "^\\([A-Z][^: \n\t]+:\\)" content))
1483        (1 'message-header-name)
1484        (2 'message-header-other nil t))
1485       ,@(if (and mail-header-separator
1486                  (not (equal mail-header-separator "")))
1487             `((,(concat "^\\(" (regexp-quote mail-header-separator) "\\)$")
1488                1 'message-separator))
1489           nil)
1490       ((lambda (limit)
1491          (re-search-forward (concat "^\\("
1492                                     message-cite-prefix-regexp
1493                                     "\\).*")
1494                             limit t))
1495        (0 'message-cited-text))
1496       ("<#/?\\(multipart\\|part\\|external\\|mml\\|secure\\)[^>]*>"
1497        (0 'message-mml))))
1498   "Additional expressions to highlight in Message mode.")
1499
1500
1501 ;; XEmacs does it like this.  For Emacs, we have to set the
1502 ;; `font-lock-defaults' buffer-local variable.
1503 (put 'message-mode 'font-lock-defaults '(message-font-lock-keywords t))
1504
1505 (defvar message-face-alist
1506   '((bold . message-bold-region)
1507     (underline . underline-region)
1508     (default . (lambda (b e)
1509                  (message-unbold-region b e)
1510                  (ununderline-region b e))))
1511   "Alist of mail and news faces for facemenu.
1512 The cdr of each entry is a function for applying the face to a region.")
1513
1514 (defcustom message-send-hook nil
1515   "Hook run before sending messages.
1516 This hook is run quite early when sending."
1517   :group 'message-various
1518   :options '(ispell-message)
1519   :link '(custom-manual "(message)Various Message Variables")
1520   :type 'hook)
1521
1522 (defcustom message-send-mail-hook nil
1523   "Hook run before sending mail messages.
1524 This hook is run very late -- just before the message is sent as