e7f210144156963ec4e47a5d4ee7ea6d9906aa84
[gnus] / lisp / message.el
1 ;;; message.el --- composing mail and news messages
2 ;; Copyright (C) 1996,97,98,99 Free Software Foundation, Inc.
3
4 ;; Author: Lars Magne Ingebrigtsen <larsi@gnus.org>
5 ;; Keywords: mail, news
6
7 ;; This file is part of GNU Emacs.
8
9 ;; GNU Emacs is free software; you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation; either version 2, or (at your option)
12 ;; any later version.
13
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
21 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 ;; Boston, MA 02111-1307, USA.
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-when-compile (require 'cl))
33
34 (require 'mailheader)
35 (require 'nnheader)
36 (require 'easymenu)
37 (require 'custom)
38 (if (string-match "XEmacs\\|Lucid" emacs-version)
39     (require 'mail-abbrevs)
40   (require 'mailabbrev))
41 (require 'mail-parse)
42 (require 'mm-bodies)
43 (require 'mm-encode)
44 (require 'mml)
45
46 (defgroup message '((user-mail-address custom-variable)
47                     (user-full-name custom-variable))
48   "Mail and news message composing."
49   :link '(custom-manual "(message)Top")
50   :group 'mail
51   :group 'news)
52
53 (put 'user-mail-address 'custom-type 'string)
54 (put 'user-full-name 'custom-type 'string)
55
56 (defgroup message-various nil
57   "Various Message Variables"
58   :link '(custom-manual "(message)Various Message Variables")
59   :group 'message)
60
61 (defgroup message-buffers nil
62   "Message Buffers"
63   :link '(custom-manual "(message)Message Buffers")
64   :group 'message)
65
66 (defgroup message-sending nil
67   "Message Sending"
68   :link '(custom-manual "(message)Sending Variables")
69   :group 'message)
70
71 (defgroup message-interface nil
72   "Message Interface"
73   :link '(custom-manual "(message)Interface")
74   :group 'message)
75
76 (defgroup message-forwarding nil
77   "Message Forwarding"
78   :link '(custom-manual "(message)Forwarding")
79   :group 'message-interface)
80
81 (defgroup message-insertion nil
82   "Message Insertion"
83   :link '(custom-manual "(message)Insertion")
84   :group 'message)
85
86 (defgroup message-headers nil
87   "Message Headers"
88   :link '(custom-manual "(message)Message Headers")
89   :group 'message)
90
91 (defgroup message-news nil
92   "Composing News Messages"
93   :group 'message)
94
95 (defgroup message-mail nil
96   "Composing Mail Messages"
97   :group 'message)
98
99 (defgroup message-faces nil
100   "Faces used for message composing."
101   :group 'message
102   :group 'faces)
103
104 (defcustom message-directory "~/Mail/"
105   "*Directory from which all other mail file variables are derived."
106   :group 'message-various
107   :type 'directory)
108
109 (defcustom message-max-buffers 10
110   "*How many buffers to keep before starting to kill them off."
111   :group 'message-buffers
112   :type 'integer)
113
114 (defcustom message-send-rename-function nil
115   "Function called to rename the buffer after sending it."
116   :group 'message-buffers
117   :type 'function)
118
119 (defcustom message-fcc-handler-function 'message-output
120   "*A function called to save outgoing articles.
121 This function will be called with the name of the file to store the
122 article in.  The default function is `message-output' which saves in Unix
123 mailbox format."
124   :type '(radio (function-item message-output)
125                 (function :tag "Other"))
126   :group 'message-sending)
127
128 (defcustom message-courtesy-message
129   "The following message is a courtesy copy of an article\nthat has been posted to %s as well.\n\n"
130   "*This is inserted at the start of a mailed copy of a posted message.
131 If the string contains the format spec \"%s\", the Newsgroups
132 the article has been posted to will be inserted there.
133 If this variable is nil, no such courtesy message will be added."
134   :group 'message-sending
135   :type 'string)
136
137 (defcustom message-ignored-bounced-headers "^\\(Received\\|Return-Path\\):"
138   "*Regexp that matches headers to be removed in resent bounced mail."
139   :group 'message-interface
140   :type 'regexp)
141
142 ;;;###autoload
143 (defcustom message-from-style 'default
144   "*Specifies how \"From\" headers look.
145
146 If `nil', they contain just the return address like:
147         king@grassland.com
148 If `parens', they look like:
149         king@grassland.com (Elvis Parsley)
150 If `angles', they look like:
151         Elvis Parsley <king@grassland.com>
152
153 Otherwise, most addresses look like `angles', but they look like
154 `parens' if `angles' would need quoting and `parens' would not."
155   :type '(choice (const :tag "simple" nil)
156                  (const parens)
157                  (const angles)
158                  (const default))
159   :group 'message-headers)
160
161 (defcustom message-syntax-checks nil
162   ; Guess this one shouldn't be easy to customize...
163   "*Controls what syntax checks should not be performed on outgoing posts.
164 To disable checking of long signatures, for instance, add
165  `(signature . disabled)' to this list.
166
167 Don't touch this variable unless you really know what you're doing.
168
169 Checks include subject-cmsg multiple-headers sendsys message-id from
170 long-lines control-chars size new-text redirected-followup signature
171 approved sender empty empty-headers message-id from subject
172 shorten-followup-to existing-newsgroups buffer-file-name unchanged
173 newsgroups."
174   :group 'message-news)
175
176 (defcustom message-required-news-headers
177   '(From Newsgroups Subject Date Message-ID
178          (optional . Organization) Lines
179          (optional . User-Agent))
180   "*Headers to be generated or prompted for when posting an article.
181 RFC977 and RFC1036 require From, Date, Newsgroups, Subject,
182 Message-ID.  Organization, Lines, In-Reply-To, Expires, and
183 User-Agent are optional.  If don't you want message to insert some
184 header, remove it from this list."
185   :group 'message-news
186   :group 'message-headers
187   :type '(repeat sexp))
188
189 (defcustom message-required-mail-headers
190   '(From Subject Date (optional . In-Reply-To) Message-ID Lines
191          (optional . User-Agent))
192   "*Headers to be generated or prompted for when mailing a message.
193 RFC822 required that From, Date, To, Subject and Message-ID be
194 included.  Organization, Lines and User-Agent are optional."
195   :group 'message-mail
196   :group 'message-headers
197   :type '(repeat sexp))
198
199 (defcustom message-deletable-headers '(Message-ID Date Lines)
200   "Headers to be deleted if they already exist and were generated by message previously."
201   :group 'message-headers
202   :type 'sexp)
203
204 (defcustom message-ignored-news-headers
205   "^NNTP-Posting-Host:\\|^Xref:\\|^[BGF]cc:\\|^Resent-Fcc:"
206   "*Regexp of headers to be removed unconditionally before posting."
207   :group 'message-news
208   :group 'message-headers
209   :type 'regexp)
210
211 (defcustom message-ignored-mail-headers "^[GF]cc:\\|^Resent-Fcc:\\|^Xref:"
212   "*Regexp of headers to be removed unconditionally before mailing."
213   :group 'message-mail
214   :group 'message-headers
215   :type 'regexp)
216
217 (defcustom message-ignored-supersedes-headers "^Path:\\|^Date\\|^NNTP-Posting-Host:\\|^Xref:\\|^Lines:\\|^Received:\\|^X-From-Line:\\|^X-Trace:\\|^X-Complaints-To:\\|Return-Path:\\|^Supersedes:\\|^NNTP-Posting-Date:\\|^X-Trace:\\|^X-Complaints-To:"
218   "*Header lines matching this regexp will be deleted before posting.
219 It's best to delete old Path and Date headers before posting to avoid
220 any confusion."
221   :group 'message-interface
222   :type 'regexp)
223
224 (defcustom message-subject-re-regexp "^[ \t]*\\([Rr][Ee]:[ \t]*\\)*[ \t]*"
225   "*Regexp matching \"Re: \" in the subject line."
226   :group 'message-various
227   :type 'regexp)
228
229 ;;;###autoload
230 (defcustom message-signature-separator "^-- *$"
231   "Regexp matching the signature separator."
232   :type 'regexp
233   :group 'message-various)
234
235 (defcustom message-elide-elipsis "\n[...]\n\n"
236   "*The string which is inserted for elided text."
237   :type 'string
238   :group 'message-various)
239
240 (defcustom message-interactive nil
241   "Non-nil means when sending a message wait for and display errors.
242 nil means let mailer mail back a message to report errors."
243   :group 'message-sending
244   :group 'message-mail
245   :type 'boolean)
246
247 (defcustom message-generate-new-buffers 'unique
248   "*Non-nil means that a new message buffer will be created whenever `message-setup' is called.
249 If this is a function, call that function with three parameters:  The type,
250 the to address and the group name.  (Any of these may be nil.)  The function
251 should return the new buffer name."
252   :group 'message-buffers
253   :type '(choice (const :tag "off" nil)
254                  (const :tag "unique" unique)
255                  (const :tag "unsent" unsent)
256                  (function fun)))
257
258 (defcustom message-kill-buffer-on-exit nil
259   "*Non-nil means that the message buffer will be killed after sending a message."
260   :group 'message-buffers
261   :type 'boolean)
262
263 (defvar gnus-local-organization)
264 (defcustom message-user-organization
265   (or (and (boundp 'gnus-local-organization)
266            (stringp gnus-local-organization)
267            gnus-local-organization)
268       (getenv "ORGANIZATION")
269       t)
270   "*String to be used as an Organization header.
271 If t, use `message-user-organization-file'."
272   :group 'message-headers
273   :type '(choice string
274                  (const :tag "consult file" t)))
275
276 ;;;###autoload
277 (defcustom message-user-organization-file "/usr/lib/news/organization"
278   "*Local news organization file."
279   :type 'file
280   :group 'message-headers)
281
282 (defcustom message-make-forward-subject-function
283   'message-forward-subject-author-subject
284  "*A list of functions that are called to generate a subject header for forwarded messages.
285 The subject generated by the previous function is passed into each
286 successive function.
287
288 The provided functions are:
289
290 * message-forward-subject-author-subject (Source of article (author or
291       newsgroup)), in brackets followed by the subject
292 * message-forward-subject-fwd (Subject of article with 'Fwd:' prepended
293       to it."
294  :group 'message-forwarding
295  :type '(radio (function-item message-forward-subject-author-subject)
296                (function-item message-forward-subject-fwd)))
297
298 (defcustom message-wash-forwarded-subjects nil
299   "*If non-nil, try to remove as much old cruft as possible from the subject of messages before generating the new subject of a forward."
300   :group 'message-forwarding
301   :type 'boolean)
302
303 (defcustom message-ignored-resent-headers "^Return-receipt\\|^X-Gnus\\|^Gnus-Warning:"
304   "*All headers that match this regexp will be deleted when resending a message."
305   :group 'message-interface
306   :type 'regexp)
307
308
309 (defcustom message-forward-ignored-headers nil
310   "*All headers that match this regexp will be deleted when forwarding a message."
311   :group 'message-forwarding
312   :type '(choice (const :tag "None" nil)
313                  regexp))
314
315 (defcustom message-ignored-cited-headers "."
316   "*Delete these headers from the messages you yank."
317   :group 'message-insertion
318   :type 'regexp)
319
320 (defcustom message-cancel-message "I am canceling my own article."
321   "Message to be inserted in the cancel message."
322   :group 'message-interface
323   :type 'string)
324
325 ;; Useful to set in site-init.el
326 ;;;###autoload
327 (defcustom message-send-mail-function 'message-send-mail-with-sendmail
328   "Function to call to send the current buffer as mail.
329 The headers should be delimited by a line whose contents match the
330 variable `mail-header-separator'.
331
332 Valid values include `message-send-mail-with-sendmail' (the default),
333 `message-send-mail-with-mh', `message-send-mail-with-qmail' and
334 `smtpmail-send-it'."
335   :type '(radio (function-item message-send-mail-with-sendmail)
336                 (function-item message-send-mail-with-mh)
337                 (function-item message-send-mail-with-qmail)
338                 (function-item smtpmail-send-it)
339                 (function :tag "Other"))
340   :group 'message-sending
341   :group 'message-mail)
342
343 (defcustom message-send-news-function 'message-send-news
344   "Function to call to send the current buffer as news.
345 The headers should be delimited by a line whose contents match the
346 variable `mail-header-separator'."
347   :group 'message-sending
348   :group 'message-news
349   :type 'function)
350
351 (defcustom message-reply-to-function nil
352   "Function that should return a list of headers.
353 This function should pick out addresses from the To, Cc, and From headers
354 and respond with new To and Cc headers."
355   :group 'message-interface
356   :type 'function)
357
358 (defcustom message-wide-reply-to-function nil
359   "Function that should return a list of headers.
360 This function should pick out addresses from the To, Cc, and From headers
361 and respond with new To and Cc headers."
362   :group 'message-interface
363   :type 'function)
364
365 (defcustom message-followup-to-function nil
366   "Function that should return a list of headers.
367 This function should pick out addresses from the To, Cc, and From headers
368 and respond with new To and Cc headers."
369   :group 'message-interface
370   :type 'function)
371
372 (defcustom message-use-followup-to 'ask
373   "*Specifies what to do with Followup-To header.
374 If nil, always ignore the header.  If it is t, use its value, but
375 query before using the \"poster\" value.  If it is the symbol `ask',
376 always query the user whether to use the value.  If it is the symbol
377 `use', always use the value."
378   :group 'message-interface
379   :type '(choice (const :tag "ignore" nil)
380                  (const use)
381                  (const ask)))
382
383 ;; stuff relating to broken sendmail in MMDF
384 (defcustom message-sendmail-f-is-evil nil
385   "*Non-nil means that \"-f username\" should not be added to the sendmail
386 command line, because it is even more evil than leaving it out."
387   :group 'message-sending
388   :type 'boolean)
389
390 ;; qmail-related stuff
391 (defcustom message-qmail-inject-program "/var/qmail/bin/qmail-inject"
392   "Location of the qmail-inject program."
393   :group 'message-sending
394   :type 'file)
395
396 (defcustom message-qmail-inject-args nil
397   "Arguments passed to qmail-inject programs.
398 This should be a list of strings, one string for each argument.
399
400 For e.g., if you wish to set the envelope sender address so that bounces
401 go to the right place or to deal with listserv's usage of that address, you
402 might set this variable to '(\"-f\" \"you@some.where\")."
403   :group 'message-sending
404   :type '(repeat string))
405
406 (defvar gnus-post-method)
407 (defvar gnus-select-method)
408 (defcustom message-post-method
409   (cond ((and (boundp 'gnus-post-method)
410               (listp gnus-post-method)
411               gnus-post-method)
412          gnus-post-method)
413         ((boundp 'gnus-select-method)
414          gnus-select-method)
415         (t '(nnspool "")))
416   "*Method used to post news.
417 Note that when posting from inside Gnus, for instance, this
418 variable isn't used."
419   :group 'message-news
420   :group 'message-sending
421   ;; This should be the `gnus-select-method' widget, but that might
422   ;; create a dependence to `gnus.el'.
423   :type 'sexp)
424
425 (defcustom message-generate-headers-first nil
426   "*If non-nil, generate all possible headers before composing."
427   :group 'message-headers
428   :type 'boolean)
429
430 (defcustom message-setup-hook nil
431   "Normal hook, run each time a new outgoing message is initialized.
432 The function `message-setup' runs this hook."
433   :group 'message-various
434   :type 'hook)
435
436 (defcustom message-cancel-hook nil
437   "Hook run when cancelling articles."
438   :group 'message-various
439   :type 'hook)
440
441 (defcustom message-signature-setup-hook nil
442   "Normal hook, run each time a new outgoing message is initialized.
443 It is run after the headers have been inserted and before
444 the signature is inserted."
445   :group 'message-various
446   :type 'hook)
447
448 (defcustom message-mode-hook nil
449   "Hook run in message mode buffers."
450   :group 'message-various
451   :type 'hook)
452
453 (defcustom message-header-hook nil
454   "Hook run in a message mode buffer narrowed to the headers."
455   :group 'message-various
456   :type 'hook)
457
458 (defcustom message-header-setup-hook nil
459   "Hook called narrowed to the headers when setting up a message buffer."
460   :group 'message-various
461   :type 'hook)
462
463 ;;;###autoload
464 (defcustom message-citation-line-function 'message-insert-citation-line
465   "*Function called to insert the \"Whomever writes:\" line."
466   :type 'function
467   :group 'message-insertion)
468
469 ;;;###autoload
470 (defcustom message-yank-prefix "> "
471   "*Prefix inserted on the lines of yanked messages."
472   :type 'string
473   :group 'message-insertion)
474
475 (defcustom message-indentation-spaces 3
476   "*Number of spaces to insert at the beginning of each cited line.
477 Used by `message-yank-original' via `message-yank-cite'."
478   :group 'message-insertion
479   :type 'integer)
480
481 ;;;###autoload
482 (defcustom message-cite-function 'message-cite-original
483   "*Function for citing an original message.
484 Predefined functions include `message-cite-original' and
485 `message-cite-original-without-signature'.
486 Note that `message-cite-original' uses `mail-citation-hook' if that is non-nil."
487   :type '(radio (function-item message-cite-original)
488                 (function-item message-cite-original-without-signature)
489                 (function-item sc-cite-original)
490                 (function :tag "Other"))
491   :group 'message-insertion)
492
493 ;;;###autoload
494 (defcustom message-indent-citation-function 'message-indent-citation
495   "*Function for modifying a citation just inserted in the mail buffer.
496 This can also be a list of functions.  Each function can find the
497 citation between (point) and (mark t).  And each function should leave
498 point and mark around the citation text as modified."
499   :type 'function
500   :group 'message-insertion)
501
502 (defvar message-abbrevs-loaded nil)
503
504 ;;;###autoload
505 (defcustom message-signature t
506   "*String to be inserted at the end of the message buffer.
507 If t, the `message-signature-file' file will be inserted instead.
508 If a function, the result from the function will be used instead.
509 If a form, the result from the form will be used instead."
510   :type 'sexp
511   :group 'message-insertion)
512
513 ;;;###autoload
514 (defcustom message-signature-file "~/.signature"
515   "*File containing the text inserted at end of message buffer."
516   :type 'file
517   :group 'message-insertion)
518
519 (defcustom message-distribution-function nil
520   "*Function called to return a Distribution header."
521   :group 'message-news
522   :group 'message-headers
523   :type 'function)
524
525 (defcustom message-expires 14
526   "Number of days before your article expires."
527   :group 'message-news
528   :group 'message-headers
529   :link '(custom-manual "(message)News Headers")
530   :type 'integer)
531
532 (defcustom message-user-path nil
533   "If nil, use the NNTP server name in the Path header.
534 If stringp, use this; if non-nil, use no host name (user name only)."
535   :group 'message-news
536   :group 'message-headers
537   :link '(custom-manual "(message)News Headers")
538   :type '(choice (const :tag "nntp" nil)
539                  (string :tag "name")
540                  (sexp :tag "none" :format "%t" t)))
541
542 (defvar message-reply-buffer nil)
543 (defvar message-reply-headers nil)
544 (defvar message-newsreader nil)
545 (defvar message-mailer nil)
546 (defvar message-sent-message-via nil)
547 (defvar message-checksum nil)
548 (defvar message-send-actions nil
549   "A list of actions to be performed upon successful sending of a message.")
550 (defvar message-exit-actions nil
551   "A list of actions to be performed upon exiting after sending a message.")
552 (defvar message-kill-actions nil
553   "A list of actions to be performed before killing a message buffer.")
554 (defvar message-postpone-actions nil
555   "A list of actions to be performed after postponing a message.")
556
557 (define-widget 'message-header-lines 'text
558   "All header lines must be LFD terminated."
559   :format "%t:%n%v"
560   :valid-regexp "^\\'"
561   :error "All header lines must be newline terminated")
562
563 (defcustom message-default-headers ""
564   "*A string containing header lines to be inserted in outgoing messages.
565 It is inserted before you edit the message, so you can edit or delete
566 these lines."
567   :group 'message-headers
568   :type 'message-header-lines)
569
570 (defcustom message-default-mail-headers ""
571   "*A string of header lines to be inserted in outgoing mails."
572   :group 'message-headers
573   :group 'message-mail
574   :type 'message-header-lines)
575
576 (defcustom message-default-news-headers ""
577   "*A string of header lines to be inserted in outgoing news
578 articles."
579   :group 'message-headers
580   :group 'message-news
581   :type 'message-header-lines)
582
583 ;; Note: could use /usr/ucb/mail instead of sendmail;
584 ;; options -t, and -v if not interactive.
585 (defcustom message-mailer-swallows-blank-line
586   (if (and (string-match "sparc-sun-sunos\\(\\'\\|[^5]\\)"
587                          system-configuration)
588            (file-readable-p "/etc/sendmail.cf")
589            (let ((buffer (get-buffer-create " *temp*")))
590              (unwind-protect
591                  (save-excursion
592                    (set-buffer buffer)
593                    (insert-file-contents "/etc/sendmail.cf")
594                    (goto-char (point-min))
595                    (let ((case-fold-search nil))
596                      (re-search-forward "^OR\\>" nil t)))
597                (kill-buffer buffer))))
598       ;; According to RFC822, "The field-name must be composed of printable
599       ;; ASCII characters (i. e., characters that have decimal values between
600       ;; 33 and 126, except colon)", i. e., any chars except ctl chars,
601       ;; space, or colon.
602       '(looking-at "[ \t]\\|[][!\"#$%&'()*+,-./0-9;<=>?@A-Z\\\\^_`a-z{|}~]+:"))
603   "*Set this non-nil if the system's mailer runs the header and body together.
604 \(This problem exists on Sunos 4 when sendmail is run in remote mode.)
605 The value should be an expression to test whether the problem will
606 actually occur."
607   :group 'message-sending
608   :type 'sexp)
609
610 ;; Ignore errors in case this is used in Emacs 19.
611 ;; Don't use ignore-errors because this is copied into loaddefs.el.
612 ;;;###autoload
613 (ignore-errors
614   (define-mail-user-agent 'message-user-agent
615     'message-mail 'message-send-and-exit
616     'message-kill-buffer 'message-send-hook))
617
618 (defvar message-mh-deletable-headers '(Message-ID Date Lines Sender)
619   "If non-nil, delete the deletable headers before feeding to mh.")
620
621 (defvar message-send-method-alist
622   '((news message-news-p message-send-via-news)
623     (mail message-mail-p message-send-via-mail))
624   "Alist of ways to send outgoing messages.
625 Each element has the form
626
627   \(TYPE PREDICATE FUNCTION)
628
629 where TYPE is a symbol that names the method; PREDICATE is a function
630 called without any parameters to determine whether the message is
631 a message of type TYPE; and FUNCTION is a function to be called if
632 PREDICATE returns non-nil.  FUNCTION is called with one parameter --
633 the prefix.")
634
635 (defvar message-mail-alias-type 'abbrev
636   "*What alias expansion type to use in Message buffers.
637 The default is `abbrev', which uses mailabbrev.  nil switches
638 mail aliases off.")
639
640 (defcustom message-auto-save-directory
641   (nnheader-concat message-directory "drafts/")
642   "*Directory where Message auto-saves buffers if Gnus isn't running.
643 If nil, Message won't auto-save."
644   :group 'message-buffers
645   :type 'directory)
646
647 (defcustom message-buffer-naming-style 'unique
648   "*The way new message buffers are named.
649 Valid valued are `unique' and `unsent'."
650   :group 'message-buffers
651   :type '(choice (const :tag "unique" unique)
652                  (const :tag "unsent" unsent)))
653
654 (defcustom message-default-charset nil
655   "Default charset used in non-MULE XEmacsen."
656   :group 'message
657   :type 'symbol)
658
659 (defcustom message-dont-reply-to-names rmail-dont-reply-to-names
660   "*A regexp specifying names to prune when doing wide replies.
661 A value of nil means exclude your own name only."
662   :group 'message
663   :type '(choice (const :tag "Yourself" nil)
664                  regexp))
665
666 ;;; Internal variables.
667 ;;; Well, not really internal.
668
669 (defvar message-mode-syntax-table
670   (let ((table (copy-syntax-table text-mode-syntax-table)))
671     (modify-syntax-entry ?% ". " table)
672     (modify-syntax-entry ?> ". " table)
673     (modify-syntax-entry ?< ". " table)
674     table)
675   "Syntax table used while in Message mode.")
676
677 (defvar message-mode-abbrev-table text-mode-abbrev-table
678   "Abbrev table used in Message mode buffers.
679 Defaults to `text-mode-abbrev-table'.")
680 (defgroup message-headers nil
681   "Message headers."
682   :link '(custom-manual "(message)Variables")
683   :group 'message)
684
685 (defface message-header-to-face
686   '((((class color)
687       (background dark))
688      (:foreground "green2" :bold t))
689     (((class color)
690       (background light))
691      (:foreground "MidnightBlue" :bold t))
692     (t
693      (:bold t :italic t)))
694   "Face used for displaying From headers."
695   :group 'message-faces)
696
697 (defface message-header-cc-face
698   '((((class color)
699       (background dark))
700      (:foreground "green4" :bold t))
701     (((class color)
702       (background light))
703      (:foreground "MidnightBlue"))
704     (t
705      (:bold t)))
706   "Face used for displaying Cc headers."
707   :group 'message-faces)
708
709 (defface message-header-subject-face
710   '((((class color)
711       (background dark))
712      (:foreground "green3"))
713     (((class color)
714       (background light))
715      (:foreground "navy blue" :bold t))
716     (t
717      (:bold t)))
718   "Face used for displaying subject headers."
719   :group 'message-faces)
720
721 (defface message-header-newsgroups-face
722   '((((class color)
723       (background dark))
724      (:foreground "yellow" :bold t :italic t))
725     (((class color)
726       (background light))
727      (:foreground "blue4" :bold t :italic t))
728     (t
729      (:bold t :italic t)))
730   "Face used for displaying newsgroups headers."