
Index: font-lock.el
===================================================================
RCS file: /pack/xemacscvs/XEmacs/xemacs/lisp/font-lock.el,v
retrieving revision 1.29
diff -u -r1.29 font-lock.el
--- lisp/font-lock.el	2005/01/26 04:18:15	1.29
+++ lisp/font-lock.el	2005/02/10 02:41:21
@@ -10,6 +10,7 @@
 ;; Next Author: RMS
 ;; Next Author: Simon Marshall <simon@gnu.ai.mit.edu>
 ;; Latest XEmacs Author: Ben Wing
+;; Synched to FSF 21.2 by Ben Wing.
 ;; Maintainer: XEmacs Development Team
 ;; Keywords: languages, faces
 
@@ -30,8 +31,11 @@
 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 ;; Boston, MA 02111-1307, USA.
 
-;;; Synched up with: FSF 19.30 except for the code to initialize the faces.
+;;; Synched up with: FSF 21.2 except for the Java keywords.
+;;; Sync sections specifically marked.
 
+;; BEGIN SYNCHED WITH FSF 21.2.
+
 ;;; Commentary:
 
 ;; Font-lock-mode is a minor mode that causes your comments to be
@@ -45,73 +49,175 @@
 ;;  displayed in `font-lock-function-name-face'.
 ;; Reserved words will be displayed in `font-lock-keyword-face'.
 ;;
+;; Regexps are used to display selected patterns in other faces.
+;;
+;; To make the text you type be fontified, use M-x font-lock-mode RET.
+;; When this minor mode is on, the faces of the current line are updated with
+;; every insertion or deletion.
+;;
+;; To turn Font Lock mode on automatically, add this to your ~/.emacs file:
+;;
+;;  (add-hook 'emacs-lisp-mode-hook 'turn-on-font-lock)
+;;
+;; Or if you want to turn Font Lock mode on in many modes:
+;;
+;;  (global-font-lock-mode t)
+;;
+;; Fontification for a particular mode may be available in a number of levels
+;; of decoration.  The higher the level, the more decoration, but the more time
+;; it takes to fontify.  See the variable `font-lock-maximum-decoration', and
+;; also the variable `font-lock-maximum-size'.  Support modes for Font Lock
+;; mode can be used to speed up Font Lock mode.  See `font-lock-support-mode'.
+
 ;; Don't let the name fool you: you can highlight things using different
 ;; colors or background stipples instead of fonts, though that is not the
 ;; default.  See the variables `font-lock-use-colors' and
 ;; `font-lock-use-fonts' for broad control over this, or see the
 ;; documentation on faces and how to change their attributes for
 ;; fine-grained control.
+
+;;; How Font Lock mode fontifies:
+
+;; When Font Lock mode is turned on in a buffer, it (a) fontifies the entire
+;; buffer and (b) installs one of its fontification functions on one of the
+;; hook variables that are run by Emacs after every buffer change (i.e., an
+;; insertion or deletion).  Fontification means the replacement of `face' text
+;; properties in a given region; Emacs displays text with these `face' text
+;; properties appropriately.
+;;
+;; Fontification normally involves syntactic (i.e., strings and comments) and
+;; regexp (i.e., keywords and everything else) passes.  There are actually
+;; three passes; (a) the syntactic keyword pass, (b) the syntactic pass and (c)
+;; the keyword pass.  Confused?
+;;
+;; The syntactic keyword pass places `syntax-table' text properties in the
+;; buffer according to the variable `font-lock-syntactic-keywords'.  It is
+;; necessary because Emacs' syntax table is not powerful enough to describe all
+;; the different syntactic constructs required by the sort of people who decide
+;; that a single quote can be syntactic or not depending on the time of day.
+;; (What sort of person could decide to overload the meaning of a quote?)
+;; Obviously the syntactic keyword pass must occur before the syntactic pass.
+;;
+;; The syntactic pass places `face' text properties in the buffer according to
+;; syntactic context, i.e., according to the buffer's syntax table and buffer
+;; text's `syntax-table' text properties.  It involves using a syntax parsing
+;; function to determine the context of different parts of a region of text.  A
+;; syntax parsing function is necessary because generally strings and/or
+;; comments can span lines, and so the context of a given region is not
+;; necessarily apparent from the content of that region.  Because the keyword
+;; pass only works within a given region, it is not generally appropriate for
+;; syntactic fontification.  This is the first fontification pass that makes
+;; changes visible to the user; it fontifies strings and comments.
+;;
+;; The keyword pass places `face' text properties in the buffer according to
+;; the variable `font-lock-keywords'.  It involves searching for given regexps
+;; (or calling given search functions) within the given region.  This is the
+;; second fontification pass that makes changes visible to the user; it
+;; fontifies language reserved words, etc.
+;;
+;; Oh, and the answer is, "Yes, obviously just about everything should be done
+;; in a single syntactic pass, but the only syntactic parser available
+;; understands only strings and comments."  Perhaps one day someone will write
+;; some syntactic parsers for common languages and a son-of-font-lock.el could
+;; use them rather then relying so heavily on the keyword (regexp) pass.
+
+;;; How Font Lock mode supports modes or is supported by modes:
+
+;; Modes that support Font Lock mode do so by defining one or more variables
+;; whose values specify the fontification.  Font Lock mode knows of these
+;; variable names from (a) the buffer local variable `font-lock-defaults', if
+;; non-nil, or (b) the global variable `font-lock-defaults-alist', if the major
+;; mode has an entry.  (Font Lock mode is set up via (a) where a mode's
+;; patterns are distributed with the mode's package library, and (b) where a
+;; mode's patterns are distributed with font-lock.el itself.  An example of (a)
+;; is Pascal mode, an example of (b) is Lisp mode.  Normally, the mechanism is
+;; (a); (b) is used where it is not clear which package library should contain
+;; the pattern definitions.)  Font Lock mode chooses which variable to use for
+;; fontification based on `font-lock-maximum-decoration'.
+;;
+;; Font Lock mode fontification behaviour can be modified in a number of ways.
+;; See the below comments and the comments distributed throughout this file.
+
+;;; Constructing patterns:
+
+;; See the documentation for the variable `font-lock-keywords'.
+;;
+;; Efficient regexps for use as MATCHERs for `font-lock-keywords' and
+;; `font-lock-syntactic-keywords' can be generated via the function
+;; `regexp-opt'.
+
+;;; Adding patterns for modes that already support Font Lock:
+
+;; Though Font Lock highlighting patterns already exist for many modes, it's
+;; likely there's something that you want fontified that currently isn't, even
+;; at the maximum fontification level.  You can add highlighting patterns via
+;; `font-lock-add-keywords'.  For example, say in some C
+;; header file you #define the token `and' to expand to `&&', etc., to make
+;; your C code almost readable.  In your ~/.emacs there could be:
+;;
+;;  (font-lock-add-keywords 'c-mode '("\\<\\(and\\|or\\|not\\)\\>"))
+;;
+;; Some modes provide specific ways to modify patterns based on the values of
+;; other variables.  For example, additional C types can be specified via the
+;; variable `c-font-lock-extra-types'.
+
+;;; Adding patterns for modes that do not support Font Lock:
+
+;; Not all modes support Font Lock mode.  If you (as a user of the mode) add
+;; patterns for a new mode, you must define in your ~/.emacs a variable or
+;; variables that specify regexp fontification.  Then, you should indicate to
+;; Font Lock mode, via the mode hook setting `font-lock-defaults', exactly what
+;; support is required.  For example, say Foo mode should have the following
+;; regexps fontified case-sensitively, and comments and strings should not be
+;; fontified automagically.  In your ~/.emacs there could be:
+;;
+;;  (defvar foo-font-lock-keywords
+;;    '(("\\<\\(one\\|two\\|three\\)\\>" . font-lock-keyword-face)
+;;      ("\\<\\(four\\|five\\|six\\)\\>" . font-lock-type-face))
+;;    "Default expressions to highlight in Foo mode.")
+;;
+;;  (add-hook 'foo-mode-hook
+;;   (function (lambda ()
+;;               (make-local-variable 'font-lock-defaults)
+;;               (setq font-lock-defaults '(foo-font-lock-keywords t)))))
+
+;;; Adding Font Lock support for modes:
+
+;; Of course, it would be better that the mode already supports Font Lock mode.
+;; The package author would do something similar to above.  The mode must
+;; define at the top-level a variable or variables that specify regexp
+;; fontification.  Then, the mode command should indicate to Font Lock mode,
+;; via `font-lock-defaults', exactly what support is required.  For example,
+;; say Bar mode should have the following regexps fontified case-insensitively,
+;; and comments and strings should be fontified automagically.  In bar.el there
+;; could be:
+;;
+;;  (defvar bar-font-lock-keywords
+;;    '(("\\<\\(uno\\|due\\|tre\\)\\>" . font-lock-keyword-face)
+;;      ("\\<\\(quattro\\|cinque\\|sei\\)\\>" . font-lock-type-face))
+;;    "Default expressions to highlight in Bar mode.")
 ;;
-;; To make the text you type be fontified, use M-x font-lock-mode.  When
-;; this minor mode is on, the fonts of the current line will be updated
-;; with every insertion or deletion.
-;;
-;; By default, font-lock will automatically put newly loaded files
-;; into font-lock-mode if it knows about the file's mode.  See the
-;; variables `font-lock-auto-fontify', `font-lock-mode-enable-list',
-;; and `font-lock-mode-disable-list' for control over this.
-;;
-;; The `font-lock-keywords' variable defines other patterns to highlight.
-;; The default font-lock-mode-hook sets it to the value of the variables
-;; lisp-font-lock-keywords, c-font-lock-keywords, etc, as appropriate.
-;; The easiest way to change the highlighting patterns is to change the
-;; values of c-font-lock-keywords and related variables.  See the doc
-;; string of the variable `font-lock-keywords' for the appropriate syntax.
-;;
-;; The default value for `lisp-font-lock-keywords' is the value of the variable
-;; `lisp-font-lock-keywords-1'.  You may like `lisp-font-lock-keywords-2' 
-;; better; it highlights many more words, but is slower and makes your buffers
-;; be very visually noisy.
-;;
-;; The same is true of `c-font-lock-keywords-1' and `c-font-lock-keywords-2';
-;; the former is subdued, the latter is loud.
-;;
-;; You can make font-lock default to the gaudier variety of keyword
-;; highlighting by setting the variable `font-lock-maximum-decoration'
-;; before loading font-lock, or by calling the functions
-;; `font-lock-use-default-maximal-decoration' or
-;; `font-lock-use-default-minimal-decoration'.
-;;
-;; On a Sparc10, the initial fontification takes about 6 seconds for a typical
-;; 140k file of C code, using the default configuration.  The actual speed
-;; depends heavily on the type of code in the file, and how many non-syntactic
-;; patterns match; for example, Xlib.h takes 23 seconds for 101k, because many
-;; patterns match in it.  You can speed this up substantially by removing some
-;; of the patterns that are highlighted by default.  Fontifying lisp code is
-;; significantly faster, because lisp has a more regular syntax than C, so the
-;; regular expressions don't have to be as complicated.
+;; and within `bar-mode' there could be:
 ;;
+;;  (make-local-variable 'font-lock-defaults)
+;;  (setq font-lock-defaults '(bar-font-lock-keywords nil t))
+
+;;
 ;; It's called font-lock-mode here because on the Lispms it was called
 ;; "Electric Font Lock Mode."  It was called that because there was an older
 ;; mode called "Electric Caps Lock Mode" which had the function of causing all
 ;; of your source code to be in upper case except for strings and comments,
 ;; without you having to blip the caps lock key by hand all the time (thus the
-;; "electric", as in `electric-c-brace'.)
+;; "electric", as in `electric-c-brace').
 
-;; See also the related packages `fast-lock' and `lazy-lock'.  Both
-;; attempt to speed up the initial fontification.  `fast-lock' saves
-;; the fontification info when you exit Emacs and reloads it next time
-;; you load the file, so that the file doesn't have to be fontified
-;; again.  `lazy-lock' does "lazy" fontification -- i.e. it only
-;; fontifies the text as it becomes visible rather than fontifying
-;; the whole file when it's first loaded in.
-
-;; Further comments from the FSF:
-
-;; Nasty regexps of the form "bar\\(\\|lo\\)\\|f\\(oo\\|u\\(\\|bar\\)\\)\\|lo"
-;; are made thusly: (regexp-opt '("foo" "fu" "fubar" "bar" "barlo" "lo")) for
-;; efficiency.
-
+;; See also the related packages `fast-lock', `lazy-lock' and `lazy-shot'.
+;; All attempt to speed up the initial fontification.  `fast-lock' saves
+;; the fontification info when you exit Emacs and reloads it next time you
+;; load the file, so that the file doesn't have to be fontified again.
+;; `lazy-lock' does "lazy" fontification -- i.e. it only fontifies the text
+;; as it becomes visible rather than fontifying the whole file when it's
+;; first loaded in.
+
 ;; What is fontification for?  You might say, "It's to make my code look nice."
 ;; I think it should be for adding information in the form of cues.  These cues
 ;; should provide you with enough information to both (a) distinguish between
@@ -121,15 +227,18 @@
 ;; doesn't work.  Or maybe it allows you to think less and drift off to sleep.
 ;;
 ;; So, here are my opinions/advice/guidelines:
-;; 
+;;
+;; - Highlight conceptual objects, such as function and variable names, and
+;;   different objects types differently, i.e., (a) and (b) above, highlight
+;;   function names differently to variable names.
+;; - Keep the faces distinct from each other as far as possible.
+;;   i.e., (a) above.
 ;; - Use the same face for the same conceptual object, across all modes.
 ;;   i.e., (b) above, all modes that have items that can be thought of as, say,
 ;;   keywords, should be highlighted with the same face, etc.
-;; - Keep the faces distinct from each other as far as possible.
-;;   i.e., (a) above.
 ;; - Make the face attributes fit the concept as far as possible.
-;;   i.e., function names might be a bold color such as blue, comments might
-;;   be a bright color such as red, character strings might be brown, because,
+;;   i.e., function names might be a bold colour such as blue, comments might
+;;   be a bright colour such as red, character strings might be brown, because,
 ;;   err, strings are brown (that was not the reason, please believe me).
 ;; - Don't use a non-nil OVERRIDE unless you have a good reason.
 ;;   Only use OVERRIDE for special things that are easy to define, such as the
@@ -140,10 +249,6 @@
 
 ;;; Code:
 
-(require 'fontl-hooks)
-
-;;;;;;;;;;;;;;;;;;;;;;      user variables       ;;;;;;;;;;;;;;;;;;;;;;
-
 (defgroup font-lock nil
   "Decorate source files with fonts/colors based on syntax.
 Font-lock-mode is a minor mode that causes your comments to be
@@ -157,19 +262,49 @@
  in `font-lock-function-name-face'.
 Reserved words will be displayed in `font-lock-keyword-face'.
 Preprocessor conditionals will be displayed in `font-lock-preprocessor-face'."
+:link '(custom-manual "(emacs)Font Lock")
+:link '(custom-manual "(elisp)Font Lock Mode")
   :group 'languages)
 
+;; Called font-lock-highlighting-faces in FSF 21.2.
 (defgroup font-lock-faces nil
-  "Faces used by the font-lock package."
+  "Faces for highlighting text using the font-lock package."
+:prefix "font-lock-"
   :group 'font-lock
   :group 'faces)
 
+(defgroup font-lock-extra-types nil
+  "Extra mode-specific type names for highlighting declarations."
+:group 'font-lock)
+
+;; Define support mode groups here to impose `font-lock' group order.
+(defgroup fast-lock nil
+  "Font Lock support mode to cache fontification."
+:link '(custom-manual "(emacs)Support Modes")
+:load 'fast-lock
+:group 'font-lock)
 
-(defcustom font-lock-verbose t
-  "*If non-nil, means show status messages when fontifying.
-See also `font-lock-message-threshold'."
-:type 'boolean
+(defgroup lazy-lock nil
+  "Font Lock support mode to fontify lazily."
+:link '(custom-manual "(emacs)Support Modes")
+:load 'lazy-lock
+:group 'font-lock)
+
+(defgroup lazy-shot nil
+  "Font Lock support mode to fontify with lazy-shot."
+:link '(custom-manual "(emacs)Support Modes")
+:version "21.1"
+:load 'lazy-shot
+:group 'font-lock)
+
+(defgroup jit-lock nil
+  "Font Lock support mode to fontify just-in-time."
+:link '(custom-manual "(emacs)Support Modes")
+:version "21.1"
+:load 'jit-lock
   :group 'font-lock)
+
+;; User variables.
 
 (defcustom font-lock-message-threshold 6000
   "*Minimum size of region being fontified for status messages to appear.
@@ -187,28 +322,6 @@
   :group 'font-lock)
 
 ;;;###autoload
-(defcustom font-lock-auto-fontify t
-  "*Whether font-lock should automatically fontify files as they're loaded.
-This will only happen if font-lock has fontifying keywords for the major
-mode of the file.  You can get finer-grained control over auto-fontification
-by using this variable in combination with `font-lock-mode-enable-list' or
-`font-lock-mode-disable-list'."
-:type 'boolean
-:group 'font-lock)
-
-;;;###autoload
-(defcustom font-lock-mode-enable-list nil
-  "*List of modes to auto-fontify, if `font-lock-auto-fontify' is nil."
-:type '(repeat (symbol :tag "Mode"))
-:group 'font-lock)
-
-;;;###autoload
-(defcustom font-lock-mode-disable-list nil
-  "*List of modes not to auto-fontify, if `font-lock-auto-fontify' is t."
-:type '(repeat (symbol :tag "Mode"))
-:group 'font-lock)
-
-;;;###autoload
 (defcustom font-lock-use-colors '(color)
   "*Specification for when Font Lock will set up color defaults.
 Normally this should be '(color), meaning that Font Lock will set up
@@ -261,16 +374,39 @@
   :group 'font-lock)
 
 ;;;###autoload
+(defcustom font-lock-maximum-size 256000
+  "*Maximum size of a buffer for buffer fontification.
+Only buffers less than this can be fontified when Font Lock mode is turned on.
+If nil, means size is irrelevant.
+If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE),
+where MAJOR-MODE is a symbol or t (meaning the default).  For example:
+ ((c-mode . 256000) (c++-mode . 256000) (rmail-mode . 1048576))
+means that the maximum size is 250K for buffers in C or C++ modes, one megabyte
+for buffers in Rmail mode, and size is irrelevant otherwise."
+:type '(choice (const :tag "none" nil)
+		 (integer :tag "size")
+		 (repeat :menu-tag "mode specific" :tag "mode specific"
+			 :value ((t . nil))
+			 (cons :tag "Instance"
+			       (radio :tag "Mode"
+				      (const :tag "all" t)
+				      (symbol :tag "name"))
+			       (radio :tag "Size"
+				      (const :tag "none" nil)
+				      (integer :tag "size")))))
+:group 'font-lock)
+
+;;;###autoload
 (defcustom font-lock-maximum-decoration t
-  "*If non-nil, the maximum decoration level for fontifying.
-If nil, use the minimum decoration (equivalent to level 0).
+  "*Maximum decoration level for fontification.
+If nil, use the default decoration (typically the minimum available).
 If t, use the maximum decoration available.
 If a number, use that level of decoration (or if not available the maximum).
 If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL),
 where MAJOR-MODE is a symbol or t (meaning the default).  For example:
- ((c++-mode . 2) (c-mode . t) (t . 1))
-means use level 2 decoration for buffers in `c++-mode', the maximum decoration
-available for buffers in `c-mode', and level 1 decoration otherwise."
+ ((c-mode . t) (c++-mode . 2) (t . 1))
+means use the maximum decoration available for buffers in C mode, level 2
+decoration for buffers in C++ mode, and level 1 decoration otherwise."
   :type '(choice (const :tag "default" nil)
 		 (const :tag "maximum" t)
 		 (integer :tag "level" 1)
@@ -286,31 +422,12 @@
 				      (integer :tag "level" 1)))))
   :group 'font-lock)
 
-;;;###autoload
-(define-obsolete-variable-alias 'font-lock-use-maximal-decoration
-  'font-lock-maximum-decoration)
-
-;;;###autoload
-(defcustom font-lock-maximum-size (* 250 1024)
-  "*If non-nil, the maximum size for buffers for fontifying.
-Only buffers less than this can be fontified when Font Lock mode is turned on.
-If nil, means size is irrelevant.
-If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE),
-where MAJOR-MODE is a symbol or t (meaning the default).  For example:
- ((c++-mode . 256000) (c-mode . 256000) (rmail-mode . 1048576))
-means that the maximum size is 250K for buffers in `c++-mode' or `c-mode', one
-megabyte for buffers in `rmail-mode', and size is irrelevant otherwise."
-:type '(choice (const :tag "none" nil)
-		 (integer :tag "size")
-		 (repeat :menu-tag "mode specific" :tag "mode specific"
-			 :value ((t . nil))
-			 (cons :tag "Instance"
-			       (radio :tag "Mode"
-				      (const :tag "all" t)
-				      (symbol :tag "name"))
-			       (radio :tag "Size"
-				      (const :tag "none" nil)
-				      (integer :tag "size")))))
+(defcustom font-lock-verbose 0
+  "*If non-nil, means show status messages for buffer fontification.
+If a number, only buffers greater than this size have fontification messages."
+:type '(choice (const :tag "never" nil)
+		 (other :tag "always" t)
+		 (integer :tag "size"))
   :group 'font-lock)
 
 ;;;###autoload
@@ -327,6 +444,90 @@
   :type '(choice string
 		 (const :tag "none" nil))
   :group 'font-lock)
+
+
+;;; Initialization of faces.
+
+;; #### barf gag retch.  Horrid FSF lossage that we need to
+;; keep around for compatibility with font-lock-keywords that
+;; forget to properly quote their faces.  I tried just let-binding
+;; them when we eval the face expression, but that fails because
+;; some	files actually use the variables directly in their init code
+;; without quoting them. --ben
+
+;; FSF 21.2 says:
+
+;; Originally these variable values were face names such as `bold' etc.
+;; Now we create our own faces, but we keep these variables for compatibility
+;; and they give users another mechanism for changing face appearance.
+;; We now allow a FACENAME in `font-lock-keywords' to be any expression that
+;; returns a face.  So the easiest thing is to continue using these variables,
+;; rather than sometimes evaling FACENAME and sometimes not.  sm.
+(defvar font-lock-comment-face 'font-lock-comment-face
+  "Face name to use for comments.  This variable should not be set.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+(defvar font-lock-string-face 'font-lock-string-face
+  "Face name to use for strings.  This variable should not be set.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+(defvar font-lock-doc-string-face 'font-lock-doc-string-face
+  "Face name to use for documentation.  This variable should not be set.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+;; GNU compatibility
+(define-compatible-variable-alias
+  'font-lock-doc-face 'font-lock-doc-string-face)
+(defvar font-lock-keyword-face 'font-lock-keyword-face
+  "Face name to use for keywords.  This variable should not be set.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+(defvar font-lock-builtin-face 'font-lock-builtin-face
+  "Face name to use for builtins.  This variable should not be set.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+(defvar font-lock-function-name-face 'font-lock-function-name-face
+  "Face name to use for function names.  This variable should not be set.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+(defvar font-lock-variable-name-face 'font-lock-variable-name-face
+  "Face name to use for variable names.  This variable should not be set.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+(defvar font-lock-type-face 'font-lock-type-face
+  "Face name to use for type and class names.  This variable should not be set.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+(defvar font-lock-constant-face 'font-lock-constant-face
+  "Face name to use for constants and label names.  Do not set this variable.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+(defvar font-lock-warning-face		'font-lock-warning-face
+  "Face name to use for things that should stand out.  Do not set this variable.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+(defvar font-lock-preprocessor-face 'font-lock-preprocessor-face
+  "Face name to use for processor declarations.  Do not set this variable.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+(defvar font-lock-reference-face	'font-lock-constant-face
+  "This variable is obsolete.  Use `font-lock-constant-face'.
+Do not set this variable.
+It is present only for horrid FSF compatibility reasons.
+The corresponding face should be set using `edit-faces' or the
+`set-face-*' functions.")
+
 
 ;; Fontification variables:
 
@@ -347,15 +548,25 @@
                       | A variable containing a regexp to search for.
                       | A function to call to make the search.
                         It is called with one arg, the limit of the search,
-                        and should leave MATCH results in the XEmacs global
-                        match data.
+                        and should return non-nil if it succeeds and leave
+                        MATCH results in the XEmacs global match data.
+                        MATCHER regexps can be generated via the function
+                        `regexp-opt'.
 
  MATCH              :== An integer match subexpression number from MATCHER.
 
  FACE-FORM           :== The symbol naming a defined face.
-                      | Expression whos value is the face name to use.  If you
+                      | Expression whose value is the face name to use.  If you
                         want FACE-FORM to be a symbol that evaluates to a face,
-                        use a form like \"(progn sym)\".
+                        use a form like \"(progn sym)\".  Face default
+                        attributes can be modified via \\[customize].  Instead
+                        of a face, FACE-FORM can evaluate to a property list of
+                        the form (face VAL1 PROP2 VAL2 PROP3 VAL3 ...) in which
+                        case all the listed text-properties will be set rather
+                        than just `face'.  In such a case, you will most likely
+                        want to put those properties in
+                        `font-lock-extra-managed-props' or to override
+                        `font-lock-unfontify-region-function'.
 
  HIGHLIGHT          :== MATCH-HIGHLIGHT
                       | MATCH-ANCHORED
@@ -436,78 +647,47 @@
   Therefore \"item\" is initially searched for starting from the end of the
   match of \"anchor\", and searching for subsequent instance of \"anchor\"
   resumes from where searching for \"item\" concluded.)
-
-For highlighting single items, typically only MATCH-HIGHLIGHT is required.
-However, if an item or (typically) several items are to be highlighted
-following the instance of another item (the anchor) then MATCH-ANCHORED may be
-required.
-
-These regular expressions should not match text which spans lines.  While
-\\[font-lock-fontify-buffer] handles multi-line patterns correctly, updating when you
-edit the buffer does not, since it considers text one line at a time.
-
-Be very careful composing regexps for this list; the wrong pattern can
-dramatically slow things down!
-")
-;;;###autoload
-(make-variable-buffer-local 'font-lock-keywords)
-
-;;;###autoload
-(defvar font-lock-syntactic-keywords nil
-  "A list of the syntactic keywords to highlight.
-Can be the list or the name of a function or variable whose value is the list.
-See `font-lock-keywords' for a description of the form of this list;
-the differences are listed below.  MATCH-HIGHLIGHT should be of the form:
-
- (MATCH SYNTAX OVERRIDE LAXMATCH)
-
-where SYNTAX can be of the form (SYNTAX-CODE . MATCHING-CHAR), the name of a
-syntax table, or an expression whose value is such a form or a syntax table.
-OVERRIDE cannot be `prepend' or `append'.
-
-For example, an element of the form highlights syntactically:
-
- (\"\\\\$\\\\(#\\\\)\" 1 (1 . nil))
 
- a hash character when following a dollar character, with a SYNTAX-CODE of
- 1 (meaning punctuation syntax).  Assuming that the buffer syntax table does
- specify hash characters to have comment start syntax, the element will only
- highlight hash characters that do not follow dollar characters as comments
- syntactically.
-
- (\"\\\\('\\\\).\\\\('\\\\)\"
-  (1 (7 . ?'))
-  (2 (7 . ?')))
-
- both single quotes which surround a single character, with a SYNTAX-CODE of
- 7 (meaning string quote syntax) and a MATCHING-CHAR of a single quote (meaning
- a single quote matches a single quote).  Assuming that the buffer syntax table
- does not specify single quotes to have quote syntax, the element will only
- highlight single quotes of the form 'c' as strings syntactically.
- Other forms, such as foo'bar or 'fubar', will not be highlighted as strings.
+For highlighting single items, for example each instance of the word
+\"foo\", typically only MATCH-HIGHLIGHT is required.  However, if an item
+or (typically) items are to be highlighted following the instance of
+another item (the anchor), for example each instance of the word \"bar\"
+following the word \"anchor\" then MATCH-ANCHORED may be required.
+
+These regular expressions can match text which spans lines, although it is
+better to avoid it if possible since updating them while editing text is
+slower, and while \\[font-lock-fontify-buffer] handles multi-line patterns
+correctly, updating when you edit the buffer may not, and you may also run into
+problems with support modes like jit-lock or lazy-lock.
+
+This variable is set by major modes via the variable `font-lock-defaults'.
+Be careful when composing regexps for this list; a poorly written pattern can
+dramatically slow things down!")
 
-This is normally set via `font-lock-defaults'."
-)
+;;; XEmacs addition:
 ;;;###autoload
-(make-variable-buffer-local 'font-lock-syntactic-keywords)
+(make-variable-buffer-local 'font-lock-keywords)
 
+;; This variable is used by mode packages that support Font Lock mode by
+;; defining their own keywords to use for `font-lock-keywords'.  (The mode
+;; command should make it buffer-local and set it to provide the set up.)
 (defvar font-lock-defaults nil
-  "The defaults font Font Lock mode for the current buffer.
+  "Defaults for Font Lock mode specified by the major mode.
 Normally, do not set this directly.  If you are writing a major mode,
 put a property of `font-lock-defaults' on the major-mode symbol with
 the desired value.
 
-It should be a list
+Defaults should be of the form:
 
-\(KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN)
+ (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN ...)
 
-KEYWORDS may be a symbol (a variable or function whose value is the keywords
-to use for fontification) or a list of symbols.  If KEYWORDS-ONLY is non-nil,
-syntactic fontification (strings and comments) is not performed.  If CASE-FOLD
-is non-nil, the case of the keywords is ignored when fontifying.  If
-SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form (CHAR
-. STRING) used to set the local Font Lock syntax table, for keyword and
-syntactic fontification (see `modify-syntax-entry').
+KEYWORDS may be a symbol (a variable or function whose value is the keywords to
+use for fontification) or a list of symbols.  If KEYWORDS-ONLY is non-nil,
+syntactic fontification (strings and comments) is not performed.
+If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
+If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
+\(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
+keyword and syntactic fontification (see `modify-syntax-entry').
 
 If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
 backwards outside any enclosing syntactic block, for syntactic fontification.
@@ -521,11 +701,30 @@
 `font-lock-keywords', `font-lock-keywords-only',
 `font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
 `font-lock-beginning-of-syntax-function', respectively.
+
+Further item elements are alists of the form (VARIABLE . VALUE) and are in no
+particular order.  Each VARIABLE is made buffer-local before set to VALUE.
 
-Alternatively, if the value is a symbol, it should name a major mode,
-and the defaults for that mode will apply.")
+Currently, appropriate variables include `font-lock-mark-block-function'.
+If this is non-nil, it should be a function with no args used to mark any
+enclosing block of text, for fontification via \\[font-lock-fontify-block].
+Typical values are `mark-defun' for programming modes or `mark-paragraph' for
+textual modes (i.e., the mode-dependent function is known to put point and mark
+around a text block relevant to that mode).
+
+Other variables include that for syntactic keyword fontification,
+`font-lock-syntactic-keywords'
+and those for buffer-specialised fontification functions,
+`font-lock-fontify-buffer-function', `font-lock-unfontify-buffer-function',
+`font-lock-fontify-region-function', `font-lock-unfontify-region-function',
+`font-lock-inhibit-thing-lock' and `font-lock-maximum-size'.")
+;;;###autoload
 (make-variable-buffer-local 'font-lock-defaults)
 
+;; #### OLD COMMENT FROM THE PREVIOUS DOC STRING IN XEMACS:
+;; Alternatively, if the value is a symbol, it should name a major mode,
+;; and the defaults for that mode will apply.
+
 ;; FSF uses `font-lock-defaults-alist' and expects the major mode to
 ;; set a value for `font-lock-defaults', but I don't like either of
 ;; these -- requiring the mode to set `font-lock-defaults' makes it
@@ -534,8 +733,69 @@
 ;; decentralized. (Who knows what strange modes might want
 ;; font-locking?)
 
+; ;; This variable is used where font-lock.el itself supplies the keywords.
+; (defvar font-lock-defaults-alist
+;   (let (;; We use `beginning-of-defun', rather than nil, for SYNTAX-BEGIN.
+; 	;; Thus the calculation of the cache is usually faster but not
+; 	;; infallible, so we risk mis-fontification.  sm.
+; 	(c-mode-defaults
+; 	 '((c-font-lock-keywords c-font-lock-keywords-1
+; 	    c-font-lock-keywords-2 c-font-lock-keywords-3)
+; 	   nil nil ((?_ . "w")) beginning-of-defun
+; 	   (font-lock-mark-block-function . mark-defun)))
+; 	(c++-mode-defaults
+; 	 '((c++-font-lock-keywords c++-font-lock-keywords-1
+; 	    c++-font-lock-keywords-2 c++-font-lock-keywords-3)
+; 	   nil nil ((?_ . "w")) beginning-of-defun
+; 	   (font-lock-mark-block-function . mark-defun)))
+; 	(objc-mode-defaults
+; 	 '((objc-font-lock-keywords objc-font-lock-keywords-1
+; 	    objc-font-lock-keywords-2 objc-font-lock-keywords-3)
+; 	   nil nil ((?_ . "w") (?$ . "w")) nil
+; 	   (font-lock-mark-block-function . mark-defun)))
+; 	(java-mode-defaults
+; 	 '((java-font-lock-keywords java-font-lock-keywords-1
+; 	    java-font-lock-keywords-2 java-font-lock-keywords-3)
+; 	   nil nil ((?_ . "w") (?$ . "w")) nil
+; 	   (font-lock-mark-block-function . mark-defun)))
+; 	(lisp-mode-defaults
+; 	 '((lisp-font-lock-keywords
+; 	    lisp-font-lock-keywords-1 lisp-font-lock-keywords-2)
+; 	   nil nil (("+-*/.<>=!?$%_&~^:" . "w")) beginning-of-defun
+; 	   (font-lock-mark-block-function . mark-defun))))
+;     (list
+;      (cons 'c-mode			c-mode-defaults)
+;      (cons 'c++-mode			c++-mode-defaults)
+;      (cons 'objc-mode			objc-mode-defaults)
+;      (cons 'java-mode			java-mode-defaults)
+;      (cons 'emacs-lisp-mode		lisp-mode-defaults)
+;      (cons 'lisp-mode			lisp-mode-defaults)
+;      (cons 'lisp-interaction-mode	lisp-mode-defaults)))
+;   "Alist of fall-back Font Lock defaults for major modes.
+
+; This variable should not be used any more.
+; Set the buffer-local `font-lock-keywords' in the major mode instead.
+
+; Each item should be a list of the form:
+
+;  (MAJOR-MODE . FONT-LOCK-DEFAULTS)
+
+; where MAJOR-MODE is a symbol and FONT-LOCK-DEFAULTS is a list of default
+; settings.  See the variable `font-lock-defaults', which takes precedence.")
+; (make-obsolete-variable 'font-lock-defaults-alist 'font-lock-defaults)
+
+(defvar font-lock-keywords-alist nil
+  "*Alist of `font-lock-keywords' local to a `major-mode'.
+This is normally set via `font-lock-add-keywords' and
+`font-lock-remove-keywords'.")
+
+(defvar font-lock-removed-keywords-alist nil
+  "*Alist of `font-lock-keywords' removed from `major-mode'.
+This is normally set via `font-lock-add-keywords' and
+`font-lock-remove-keywords'.")
+
 (defvar font-lock-keywords-only nil
-  "Non-nil means Font Lock should not do syntactic fontification.
+  "*Non-nil means Font Lock should not do syntactic fontification.
 This is normally set via `font-lock-defaults'.
 
 This should be nil for all ``language'' modes, but other modes, like
@@ -550,37 +810,97 @@
 (make-variable-buffer-local 'font-lock-keywords-only)
 
 (defvar font-lock-keywords-case-fold-search nil
-  "Whether the strings in `font-lock-keywords' should be case-folded.
-This variable is automatically buffer-local, as the correct value depends
-on the language in use.")
+  "*Non-nil means the patterns in `font-lock-keywords' are case-insensitive.
+This is normally set via `font-lock-defaults'.")
 (make-variable-buffer-local 'font-lock-keywords-case-fold-search)
 
+(defvar font-lock-syntactically-fontified 0
+  "Point up to which `font-lock-syntactic-keywords' has been applied.
+If nil, this is ignored, in which case the syntactic fontification may
+sometimes be slightly incorrect.")
+(make-variable-buffer-local 'font-lock-syntactically-fontified)
+
+(defvar font-lock-syntactic-face-function
+  (lambda (state)
+    (if (nth 3 state)
+	;; XEmacs addition to separate doc-string face from string face
+	;; #### Do we really want to keep doing this?
+	(if (and (= (nth 0 state) 1) ;; depth is 1
+		 (font-lock-lisp-like major-mode))
+	    font-lock-doc-string-face
+	  font-lock-string-face)
+      font-lock-comment-face))
+  "Function to determine which face to use when fontifying syntactically.
+The function is called with a single parameter (the state as returned by
+`parse-partial-sexp' at the beginning of the region to highlight) and
+should return a face.")
+
+;;;###autoload
+(defvar font-lock-syntactic-keywords nil
+  "A list of the syntactic keywords to highlight.
+Can be the list or the name of a function or variable whose value is the list.
+See `font-lock-keywords' for a description of the form of this list;
+the differences are listed below.  MATCH-HIGHLIGHT should be of the form:
+
+ (MATCH SYNTAX OVERRIDE LAXMATCH)
+
+where SYNTAX can be a string (as taken by `modify-syntax-entry'), a syntax
+table, a cons cell (as returned by `string-to-syntax') or an expression whose
+value is such a form.  OVERRIDE cannot be `prepend' or `append'.
+
+For example, an element of the form highlights syntactically:
+
+ (\"\\\\$\\\\(#\\\\)\" 1 \".\")
+
+ a hash character when following a dollar character, with a SYNTAX of
+ \".\" (meaning punctuation syntax).  Assuming that the buffer syntax table does
+ specify hash characters to have comment start syntax, the element will only
+ highlight hash characters that do not follow dollar characters as comments
+ syntactically.
+
+ (\"\\\\('\\\\).\\\\('\\\\)\"
+  (1 \"\\\"\")
+  (2 \"\\\"\"))
+
+ both single quotes which surround a single character, with a SYNTAX of
+ \"\\\"\" (meaning string quote syntax).  Assuming that the buffer syntax table
+ does not specify single quotes to have quote syntax, the element will only
+ highlight single quotes of the form 'c' as strings syntactically.
+ Other forms, such as foo'bar or 'fubar', will not be highlighted as strings.
+
+This is normally set via `font-lock-defaults'.")
+
+;;;###autoload
+(make-variable-buffer-local 'font-lock-syntactic-keywords)
+
+;; XEmacs addition:
 (defvar font-lock-after-fontify-buffer-hook nil
   "Function or functions to run after completion of font-lock-fontify-buffer.")
 
+;; XEmacs addition:
+(defvar font-lock-after-unfontify-buffer-hook nil
+  "Function or functions to run after completion of font-lock-fontify-buffer.")
+
 (defvar font-lock-syntax-table nil
   "Non-nil means use this syntax table for fontifying.
 If this is nil, the major mode's syntax table is used.
 This is normally set via `font-lock-defaults'.")
 (make-variable-buffer-local 'font-lock-syntax-table)
 
-;; These record the parse state at a particular position, always the start of a
-;; line.  Used to make `font-lock-fontify-syntactically-region' faster.
-;; Previously, `font-lock-cache-position' was just a buffer position.  However,
-;; under certain situations, this occasionally resulted in mis-fontification.
-;; I think the "situations" were deletion with Lazy Lock mode's deferral.  sm.
-(defvar font-lock-cache-state nil)
-(defvar font-lock-cache-position nil)
-(make-variable-buffer-local 'font-lock-cache-state)
-(make-variable-buffer-local 'font-lock-cache-position)
-
 ;; If this is nil, we only use the beginning of the buffer if we can't use
 ;; `font-lock-cache-position' and `font-lock-cache-state'.
 (defvar font-lock-beginning-of-syntax-function nil
-  "Non-nil means use this function to move back outside of a syntactic block.
+  "*Non-nil means use this function to move back outside of a syntactic block.
+When called with no args it should leave point at the beginning of any
+enclosing syntactic block.
 If this is nil, the beginning of the buffer is used (in the worst case).
+This is normally set via `font-lock-defaults'.")
+
+(defvar font-lock-mark-block-function nil
+  "*Non-nil means use this function to mark a block of text.
+When called with no args it should leave point at the beginning of any
+enclosing textual block and mark at the end.
 This is normally set via `font-lock-defaults'.")
-(make-variable-buffer-local 'font-lock-beginning-of-syntax-function)
 
 (defvar font-lock-fontify-buffer-function 'font-lock-default-fontify-buffer
   "Function to use for fontifying the buffer.
@@ -607,6 +927,13 @@
 Currently, valid mode names as `fast-lock-mode' and `lazy-lock-mode'.
 This is normally set via `font-lock-defaults'.")
 
+(defvar font-lock-multiline nil
+  "Whether font-lock should cater to multiline keywords.
+If nil, don't try to handle multiline patterns.
+If t, always handle multiline patterns.
+If `undecided', don't try to handle multiline patterns until you see one.
+Major/minor modes can set this variable if they know which option applies.")
+
 ;;;###autoload
 (defcustom font-lock-mode nil ;; customized for the option menu. dverna
   "Non nil means `font-lock-mode' is on"
@@ -617,258 +944,15 @@
   :set #'(lambda (var val) (font-lock-mode (or val 0)))
   )
 
-(defvar font-lock-fontified nil) ; whether we have hacked this buffer
+(defvar font-lock-fontified nil)	; Whether we have fontified the buffer.
 (put 'font-lock-fontified 'permanent-local t)
 
-;;;###autoload
-(defvar font-lock-mode-hook nil
-  "Function or functions to run on entry to font-lock-mode.")
-
-; whether font-lock-set-defaults has already been run.
-(defvar font-lock-defaults-computed nil)
-(make-variable-buffer-local 'font-lock-defaults-computed)
+(defvar font-lock-set-defaults nil)	; Whether we have set up defaults.
+(make-variable-buffer-local 'font-lock-set-defaults)
 
 
-;;; Initialization of faces.
+;; Font Lock mode: The user level functions.
 
-;; #### barf gag retch.  Horrid FSF lossage that we need to
-;; keep around for compatibility with font-lock-keywords that
-;; forget to properly quote their faces.  I tried just let-binding
-;; them when we eval the face expression, but that fails because
-;; some	files actually use the variables directly in their init code
-;; without quoting them. --ben
-(defvar font-lock-comment-face 'font-lock-comment-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-(defvar font-lock-doc-string-face 'font-lock-doc-string-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-;; GNU compatibility
-(define-compatible-variable-alias
-  'font-lock-doc-face 'font-lock-doc-string-face)
-(defvar font-lock-string-face 'font-lock-string-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-(defvar font-lock-keyword-face 'font-lock-keyword-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-(defvar font-lock-builtin-face 'font-lock-builtin-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-(defvar font-lock-function-name-face 'font-lock-function-name-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-(defvar font-lock-variable-name-face 'font-lock-variable-name-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-(defvar font-lock-type-face 'font-lock-type-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-(defvar font-lock-constant-face 'font-lock-constant-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-(defvar font-lock-reference-face 'font-lock-reference-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-(defvar font-lock-preprocessor-face 'font-lock-preprocessor-face
-  "This variable should not be set.
-It is present only for horrid FSF compatibility reasons.
-The corresponding face should be set using `edit-faces' or the
-`set-face-*' functions.")
-
-(defconst font-lock-face-list
-  '(font-lock-comment-face
-    font-lock-string-face
-    font-lock-doc-string-face
-    font-lock-keyword-face
-    font-lock-builtin-face
-    font-lock-function-name-face
-    font-lock-variable-name-face
-    font-lock-type-face
-    font-lock-constant-face
-    font-lock-reference-face
-    font-lock-preprocessor-face
-    font-lock-warning-face))
-
-(defface font-lock-comment-face
-  '((((class color) (background dark)) (:foreground "gray80"))
-    ;; blue4 is hardly different from black on windows.
-    (((class color) (background light) (type mswindows)) (:foreground "blue"))
-    (((class color) (background light)) (:foreground "blue4"))
-    (((class grayscale) (background light))
-     (:foreground "DimGray" :bold t :italic t))
-    (((class grayscale) (background dark))
-     (:foreground "LightGray" :bold t :italic t))
-    (t (:bold t)))
-  "Font Lock mode face used to highlight comments."
-:group 'font-lock-faces)
-
-(defface font-lock-string-face
-  '((((class color) (background dark)) (:foreground "tan"))
-    (((class color) (background light)) (:foreground "green4"))
-    (((class grayscale) (background light)) (:foreground "DimGray" :italic t))
-    (((class grayscale) (background dark)) (:foreground "LightGray" :italic t))
-    (t (:bold t)))
-  "Font Lock mode face used to highlight strings."
-:group 'font-lock-faces)
-
-(defface font-lock-doc-string-face
-  '((((class color) (background dark)) (:foreground "light coral"))
-    (((class color) (background light)) (:foreground "green4"))
-    (t (:bold t)))
-  "Font Lock mode face used to highlight documentation strings.
-This is currently supported only in Lisp-like modes, which are those
-with \"lisp\" or \"scheme\" in their name.  You can explicitly make
-a mode Lisp-like by putting a non-nil `font-lock-lisp-like' property
-on the major mode's symbol."
-:group 'font-lock-faces)
-
-(defface font-lock-keyword-face
-  '((((class color) (background dark)) (:foreground "cyan"))
-    ;; red4 is hardly different from black on windows.
-    (((class color) (background light) (type mswindows)) (:foreground "red"))
-    (((class color) (background light)) (:foreground "red4"))
-    (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
-    (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
-    (t (:bold t)))
-  "Font Lock mode face used to highlight keywords."
-:group 'font-lock-faces)
-
-(defface font-lock-builtin-face
-  '((((class color) (background light)) (:foreground "Purple"))
-    (((class color) (background dark)) (:foreground "Cyan"))
-    (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
-    (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
-    (t (:bold t)))
-  "Font Lock mode face used to highlight builtins."
-:group 'font-lock-faces)
-
-(defface font-lock-function-name-face
-  '((((class color) (background dark)) (:foreground "aquamarine"))
-    ;; brown4 is hardly different from black on windows.
-    ;; I changed it to red because IMO it's pointless and ugly to
-    ;; use a million slightly different colors for niggly syntactic
-    ;; differences. --ben
-    (((class color) (background light) (type mswindows)) (:foreground "red"))
-    (((class color) (background light)) (:foreground "brown4"))
-    (t (:bold t :underline t)))
-  "Font Lock mode face used to highlight function names."
-:group 'font-lock-faces)
-
-(defface font-lock-variable-name-face
-  '((((class color) (background dark)) (:foreground "cyan3"))
-    (((class color) (background light)) (:foreground "magenta4"))
-    (((class grayscale) (background light))
-     (:foreground "Gray90" :bold t :italic t))
-    (((class grayscale) (background dark))
-     (:foreground "DimGray" :bold t :italic t))
-    (t (:underline t)))
-  "Font Lock mode face used to highlight variable names."
-:group 'font-lock-faces)
-
-(defface font-lock-type-face
-  '((((class color) (background dark)) (:foreground "wheat"))
-    (((class color) (background light)) (:foreground "steelblue"))
-    (((class grayscale) (background light)) (:foreground "Gray90" :bold t))
-    (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
-    (t (:bold t)))
-  "Font Lock mode face used to highlight types."
-:group 'font-lock-faces)
-
-(defface font-lock-constant-face
-  '((((class color) (background light)) (:foreground "CadetBlue"))
-    (((class color) (background dark)) (:foreground "Aquamarine"))
-    (((class grayscale) (background light))
-     (:foreground "LightGray" :bold t :underline t))
-    (((class grayscale) (background dark))
-     (:foreground "Gray50" :bold t :underline t))
-    (t (:bold t :underline t)))
-  "Font Lock mode face used to highlight constants and labels."
-:group 'font-lock-faces)
-
-(defface font-lock-reference-face
-  '((((class color) (background dark)) (:foreground "cadetblue2"))
-    (((class color) (background light)) (:foreground "red3"))
-    (((class grayscale) (background light))
-     (:foreground "LightGray" :bold t :underline t))
-    (((class grayscale) (background dark))
-     (:foreground "Gray50" :bold t :underline t)))
-  "Font Lock mode face used to highlight references."
-:group 'font-lock-faces)
-
-(defface font-lock-preprocessor-face
-  '((((class color) (background dark)) (:foreground "steelblue1"))
-    (((class color) (background light)) (:foreground "blue3"))
-    (t (:underline t)))
-  "Font Lock Mode face used to highlight preprocessor conditionals."
-:group 'font-lock-faces)
-
-(defface font-lock-warning-face
-  '((((class color) (background light)) (:foreground "Red" :bold t))
-    (((class color) (background dark)) (:foreground "Pink" :bold t))
-    (t (:inverse-video t :bold t)))
-  "Font Lock mode face used to highlight warnings."
-:group 'font-lock-faces)
-
-(defun font-lock-recompute-variables ()
-  ;; Is this a Draconian thing to do?
-  (mapc #'(lambda (buffer)
-	    (with-current-buffer buffer
-	      (font-lock-mode 0)
-	      (font-lock-set-defaults t)))
-	(buffer-list)))
-
-;; Backwards-compatible crud.
-
-(defun font-lock-reset-all-faces ()
-  (dolist (face font-lock-face-list)
-    (face-spec-set face (get face 'face-defface-spec))))
-
-(defun font-lock-use-default-fonts ()
-  "Reset the font-lock faces to a default set of fonts."
-  (interactive)
-  ;; #### !!!!
-  (font-lock-reset-all-faces))
-
-(defun font-lock-use-default-colors ()
-  "Reset the font-lock faces to a default set of colors."
-  (interactive)
-  ;; #### !!!!
-  (font-lock-reset-all-faces))
-
-(defun font-lock-use-default-minimal-decoration ()
-  "Reset the font-lock patterns to a fast, minimal set of decorations."
-  (and font-lock-maximum-decoration
-       (setq font-lock-maximum-decoration nil)
-       (font-lock-recompute-variables)))
-
-(defun font-lock-use-default-maximal-decoration ()
-  "Reset the font-lock patterns to a larger set of decorations."
-  (and (not (eq t font-lock-maximum-decoration))
-       (setq font-lock-maximum-decoration t)
-       (font-lock-recompute-variables)))
-
-
 ;;;;;;;;;;;;;;;;;;;;;;        actual code        ;;;;;;;;;;;;;;;;;;;;;;
 
 ;;; To fontify the whole buffer by language syntax, we go through it a
@@ -899,115 +983,568 @@
 ;;; for example, inserting spaces into `intfoo () {}'.
 ;;;
 
-
-;; The user level functions
+(eval-when-compile
+  ;;
+  ;; We don't do this at the top-level as we only use non-autoloaded macros.
+  (require 'cl)
+  ;;
+  ;; Borrowed from lazy-lock.el.
+  ;; We use this to preserve or protect things when modifying text properties.
+  (defmacro save-buffer-state (varlist &rest body)
+    "Bind variables according to VARLIST and eval BODY restoring buffer state."
+    `(let* ,(append varlist
+		    '((modified (buffer-modified-p)) (buffer-undo-list t)
+		      (inhibit-read-only t)
+		      ;; FSF 21.2: (inhibit-point-motion-hooks t)
+		      ;; FSF 21.2: (inhibit-modification-hooks t)
+		      ;; FSF 21.2: deactivate-mark
+		      buffer-file-name buffer-file-truename))
+       ,@body
+       (when (and (not modified) (buffer-modified-p))
+	 (set-buffer-modified-p nil))))
+  (put 'save-buffer-state 'lisp-indent-function 1)
+  ;; FSF 21.2: (def-edebug-spec save-buffer-state let)
+  ;;
+  ;; Shut up the byte compiler.
+  (defvar font-lock-face-attributes))	; Obsolete but respected if set.
 
 ;;;###autoload
-(defun font-lock-mode (&optional arg)
+(define-minor-mode font-lock-mode
   "Toggle Font Lock Mode.
-With arg, turn font-lock mode on if and only if arg is positive.
-
-When Font Lock mode is enabled, text is fontified as you type it:
-
- - Comments are displayed in `font-lock-comment-face';
- - Strings are displayed in `font-lock-string-face';
- - Documentation strings (in Lisp-like languages) are displayed in
+With arg, turn Font Lock mode off if and only if arg is a non-positive
+number; if arg is nil, toggle Font Lock mode; anything else turns Font
+Lock on.
+\(Font Lock is also known as \"syntax highlighting\".)
+
+When Font Lock mode is enabled, text is fontified as you type it, in the
+following faces:
+
+ - Comments in `font-lock-comment-face';
+ - Strings in `font-lock-string-face';
+ - Documentation strings (in Lisp-like languages) in
    `font-lock-doc-string-face';
- - Language keywords (\"reserved words\") are displayed in
-   `font-lock-keyword-face';
- - Function names in their defining form are displayed in
-   `font-lock-function-name-face';
- - Variable names in their defining form are displayed in
-   `font-lock-variable-name-face';
- - Type names are displayed in `font-lock-type-face';
- - References appearing in help files and the like are displayed
-   in `font-lock-reference-face';
- - Preprocessor declarations are displayed in
-  `font-lock-preprocessor-face';
+ - Language keywords (\"reserved words\") in `font-lock-keyword-face';
+ - Builtins in `font-lock-builtin-face';
+ - Function names in their defining form in `font-lock-function-name-face';
+ - Variable names in their defining form in `font-lock-variable-name-face';
+ - Type and class names in `font-lock-type-face';
+ - Constants and label names in `font-lock-constant-face';
+ - Things that should stand out in `font-lock-warning-face';
+ - Preprocessor declarations in `font-lock-preprocessor-face';
 
    and
 
  - Certain other expressions are displayed in other faces according
    to the value of the variable `font-lock-keywords'.
+
+To customize the faces (colors, fonts, etc.) used by Font Lock for
+fontifying different parts of buffer text, use \\[customize-face].
 
-Where modes support different levels of fontification, you can use the variable
+You can enable Font Lock mode in any major mode automatically by turning on in
+the major mode's hook.  For example, put in your ~/.emacs:
+
+ (add-hook 'c-mode-hook 'turn-on-font-lock)
+
+Alternatively, you can use Global Font Lock mode to automagically turn on Font
+Lock mode in buffers whose major mode supports it and whose major mode is one
+of `font-lock-global-modes'.  For example, put in your ~/.emacs:
+
+ (global-font-lock-mode t)
+
+There are a number of support modes that may be used to speed up Font Lock mode
+in various ways, specified via the variable `font-lock-support-mode'.  Where
+major modes support different levels of fontification, you can use the variable
 `font-lock-maximum-decoration' to specify which level you generally prefer.
 When you turn Font Lock mode on/off the buffer is fontified/defontified, though
 fontification occurs only if the buffer is less than `font-lock-maximum-size'.
-To fontify a buffer without turning on Font Lock mode, and regardless of buffer
+
+For example, to specify that Font Lock mode use use Lazy Lock mode as a support
+mode and use maximum levels of fontification, put in your ~/.emacs:
+
+ (setq font-lock-support-mode 'lazy-lock-mode)
+ (setq font-lock-maximum-decoration t)
+
+To add your own highlighting for some major mode, and modify the highlighting
+selected automatically via the variable `font-lock-maximum-decoration', you can
+use `font-lock-add-keywords'.
+
+To fontify a buffer, without turning on Font Lock mode and regardless of buffer
 size, you can use \\[font-lock-fontify-buffer].
 
-See the variable `font-lock-keywords' for customization."
-  (interactive "P")
-  (let ((on-p (if arg (> (prefix-numeric-value arg) 0) (not font-lock-mode)))
-	(maximum-size (if (not (consp font-lock-maximum-size))
-			  font-lock-maximum-size
-			(cdr (or (assq major-mode font-lock-maximum-size)
-				 (assq t font-lock-maximum-size))))))
-    ;; Font-lock mode will refuse to turn itself on if in batch mode
-    ;; to avoid potential (probably not actual, though) slowdown.  We
-    ;; used to try to "be nice" by avoiding doing this in temporary
-    ;; buffers.  But with the deferral code we don't need this, and it
-    ;; definitely screws some things up.
-    (if (noninteractive)
-	(setq on-p nil))
-    (cond (on-p
-	   (make-local-hook 'after-change-functions)
-	   (add-hook 'after-change-functions
-		     'font-lock-after-change-function nil t)
-	   (add-hook 'pre-idle-hook 'font-lock-pre-idle-hook))
-	  (t
-	   (remove-hook 'after-change-functions
-			'font-lock-after-change-function t)
-	   (setq font-lock-defaults-computed nil
-		 font-lock-keywords nil)
-	   ;; We have no business doing this here, since 
-	   ;; pre-idle-hook is global.	Other buffers may
-	   ;; still be in font-lock mode.  -dkindred@cs.cmu.edu
-	   ;; (remove-hook 'pre-idle-hook 'font-lock-pre-idle-hook)
-	   ))
-    (set (make-local-variable 'font-lock-mode) on-p)
-    (cond (on-p
-	   (font-lock-set-defaults-1)
-	   (run-hooks 'font-lock-mode-hook)
-	   (cond (font-lock-fontified
-		  nil)
-		 ((or (null maximum-size) (<= (buffer-size) maximum-size))
-		  (font-lock-fontify-buffer))
-		 (font-lock-verbose
-		  (progress-feedback-with-label
-		   'font-lock
-		   "Fontifying %s... buffer too big." 'abort
-		   (buffer-name)))))
-	  (font-lock-fontified
-	   (setq font-lock-fontified nil)
-	   (font-lock-unfontify-region (point-min) (point-max))
-	   (font-lock-thing-lock-cleanup))
-	  (t
-	   (font-lock-thing-lock-cleanup)))
-    (redraw-modeline)))
+To fontify a block (the function or paragraph containing point, or a number of
+lines around point), perhaps because modification on the current line caused
+syntactic change on other lines, you can use \\[font-lock-fontify-block].
+
+The Font Lock mode default settings can be found by retrieving a property
+named `font-lock-defaults' on the symbol naming the major mode.  You can
+set your own default settings for some mode, by setting a buffer local
+value for `font-lock-defaults', via its mode hook.
+
+See the variable `font-lock-keywords' for a description of the format of
+the settings."
+  nil nil nil
+  ;; Font-lock mode will refuse to turn itself on if in batch mode to avoid
+  ;; potential (probably not actual, though) slowdown.  We used to try to
+  ;; "be nice" by avoiding doing this in temporary (aka invisible) buffers.
+  ;; But with the deferral code we don't need this, and it definitely
+  ;; screws some things up.
+  (when (or (noninteractive)
+	    ;; (eq (aref (buffer-name) 0) ?\ ))
+	    )
+    (setq font-lock-mode nil))
+
+  ;; Turn on Font Lock mode.
+  (when font-lock-mode
+    (add-hook 'after-change-functions 'font-lock-after-change-function t t)
+    (add-hook 'pre-idle-hook 'font-lock-pre-idle-hook)
+    (font-lock-set-defaults)
+    (font-lock-turn-on-thing-lock)
+    ;; Fontify the buffer if we have to.
+    (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
+      (cond (font-lock-fontified
+	     nil)
+	    ((or (null max-size) (> max-size (buffer-size)))
+	     (font-lock-fontify-buffer))
+	    (font-lock-verbose
+	     (progress-feedback-with-label
+	      'font-lock
+	      "Fontifying %s...buffer too big." 'abort
+	      (buffer-name))))))
+
+  ;; Turn off Font Lock mode.
+  (unless font-lock-mode
+    (remove-hook 'after-change-functions 'font-lock-after-change-function t)
+    ;; We have no business doing this here, since 
+    ;; pre-idle-hook is global.	Other buffers may
+    ;; still be in font-lock mode.  -dkindred@cs.cmu.edu
+    ;; (remove-hook 'pre-idle-hook 'font-lock-pre-idle-hook)
+    (font-lock-unfontify-buffer)
+    (font-lock-turn-off-thing-lock)
+    (font-lock-unset-defaults)))
 
 ;; For init-file hooks
 ;;;###autoload
 (defun turn-on-font-lock ()
   "Unconditionally turn on Font Lock mode."
   (interactive)
-  (font-lock-mode 1))
+  (unless font-lock-mode
+    (font-lock-mode)))
 
 ;;;###autoload
 (defun turn-off-font-lock ()
   "Unconditionally turn off Font Lock mode."
   (interactive)
-  (font-lock-mode 0))
+  (when font-lock-mode
+    (font-lock-mode)))
+
+;;;###autoload
+(defun font-lock-add-keywords (mode keywords &optional append)
+  "Add highlighting KEYWORDS for MODE.
+MODE should be a symbol, the major mode command name, such as `c-mode'
+or nil.  If nil, highlighting keywords are added for the current buffer.
+KEYWORDS should be a list; see the variable `font-lock-keywords'.
+By default they are added at the beginning of the current highlighting list.
+If optional argument APPEND is `set', they are used to replace the current
+highlighting list.  If APPEND is any other non-nil value, they are added at the
+end of the current highlighting list.
+
+For example:
+
+ (font-lock-add-keywords 'c-mode
+  '((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 font-lock-warning-face prepend)
+    (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" . font-lock-keyword-face)))
+
+adds two fontification patterns for C mode, to fontify `FIXME:' words, even in
+comments, and to fontify `and', `or' and `not' words as keywords.
+
+When used from an elisp package (such as a minor mode), it is recommended
+to use nil for MODE (and place the call in a loop or on a hook) to avoid
+subtle problems due to details of the implementation.
+
+Note that some modes have specialised support for additional patterns, e.g.,
+see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types',
+`objc-font-lock-extra-types' and `java-font-lock-extra-types'."
+  (cond (mode
+	 ;; If MODE is non-nil, add the KEYWORDS and APPEND spec to
+	 ;; `font-lock-keywords-alist' so `font-lock-set-defaults' uses them.
+	 (let ((spec (cons keywords append)) cell)
+	   (if (setq cell (assq mode font-lock-keywords-alist))
+	       (if (eq append 'set)
+		   (setcdr cell (list spec))
+		 (setcdr cell (append (cdr cell) (list spec))))
+	     (push (list mode spec) font-lock-keywords-alist)))
+	 ;; Make sure that `font-lock-removed-keywords-alist' does not
+	 ;; contain the new keywords.
+	 (font-lock-update-removed-keyword-alist mode keywords append))
+	(t
+	 ;; Otherwise set or add the keywords now.
+	 (font-lock-set-defaults)
+ 	 (if (eq append 'set)
+ 	     (setq font-lock-keywords keywords)
+	   (font-lock-remove-keywords nil keywords) ;to avoid duplicates
+	   (let ((old (if (eq (car-safe font-lock-keywords) t)
+			  (cdr font-lock-keywords)
+			font-lock-keywords)))
+	     (setq font-lock-keywords (if append
+					  (append old keywords)
+					(append keywords old))))))))
+
+(defun font-lock-update-removed-keyword-alist (mode keywords append)
+  ;; Update `font-lock-removed-keywords-alist' when adding new
+  ;; KEYWORDS to MODE.
+  ;;
+  ;; When font-lock is enabled first all keywords in the list
+  ;; `font-lock-keywords-alist' are added, then all keywords in the
+  ;; list `font-lock-removed-keywords-alist' are removed.  If a
+  ;; keyword was once added, removed, and then added again it must be
+  ;; removed from the removed-keywords list.  Otherwise the second add
+  ;; will not take effect.
+  (let ((cell (assq mode font-lock-removed-keywords-alist)))
+    (if cell
+	(if (eq append 'set)
+	    ;; A new set of keywords is defined.  Forget all about
+	    ;; our old keywords that should be removed.
+	    (setq font-lock-removed-keywords-alist
+		  (delq cell font-lock-removed-keywords-alist))
+	  ;; Delete all previously removed keywords.
+	  (dolist (kword keywords)
+	    (setcdr cell (delete kword (cdr cell))))
+	  ;; Delete the mode cell if empty.
+	  (if (null (cdr cell))
+	      (setq font-lock-removed-keywords-alist
+		    (delq cell font-lock-removed-keywords-alist)))))))
+
+;; Written by Anders Lindgren <andersl@andersl.com>.
+;;
+;; Case study:
+;; (I)  The keywords are removed from a major mode.
+;;      In this case the keyword could be local (i.e. added earlier by
+;;      `font-lock-add-keywords'), global, or both.
+;;
+;;      (a) In the local case we remove the keywords from the variable
+;;          `font-lock-keywords-alist'.
+;;
+;;      (b) The actual global keywords are not known at this time.
+;;          All keywords are added to `font-lock-removed-keywords-alist',
+;;          when font-lock is enabled those keywords are removed.
+;;
+;;      Note that added keywords are taken out of the list of removed
+;;      keywords.  This ensure correct operation when the same keyword
+;;      is added and removed several times.
+;;
+;; (II) The keywords are removed from the current buffer.
+;;;###autoload
+(defun font-lock-remove-keywords (mode keywords)
+  "Remove highlighting KEYWORDS for MODE.
 
-;;; FSF has here:
+MODE should be a symbol, the major mode command name, such as `c-mode'
+or nil.  If nil, highlighting keywords are removed for the current buffer.
 
-;; support for add-keywords, global-font-lock-mode and
-;; font-lock-support-mode (unified support for various *-lock modes).
+When used from an elisp package (such as a minor mode), it is recommended
+to use nil for MODE (and place the call in a loop or on a hook) to avoid
+subtle problems due to details of the implementation."
+  (cond (mode
+	 ;; Remove one keyword at the time.
+	 (dolist (keyword keywords)
+	   (let ((top-cell (assq mode font-lock-keywords-alist)))
+	     ;; If MODE is non-nil, remove the KEYWORD from
+	     ;; `font-lock-keywords-alist'.
+	     (when top-cell
+	       (dolist (keyword-list-append-pair (cdr top-cell))
+		 ;; `keywords-list-append-pair' is a cons with a list of
+		 ;; keywords in the car top-cell and the original append
+		 ;; argument in the cdr top-cell.
+		 (setcar keyword-list-append-pair
+			 (delete keyword (car keyword-list-append-pair))))
+	       ;; Remove keyword list/append pair when the keyword list
+	       ;; is empty and append doesn't specify `set'.  (If it
+	       ;; should be deleted then previously deleted keywords
+	       ;; would appear again.)
+	       (let ((cell top-cell))
+		 (while (cdr cell)
+		   (if (and (null (car (car (cdr cell))))
+			    (not (eq (cdr (car (cdr cell))) 'set)))
+		       (setcdr cell (cdr (cdr cell)))
+		     (setq cell (cdr cell)))))
+	       ;; Final cleanup, remove major mode cell if last keyword
+	       ;; was deleted.
+	       (if (null (cdr top-cell))
+		   (setq font-lock-keywords-alist
+			 (delq top-cell font-lock-keywords-alist))))
+	     ;; Remember the keyword in case it is not local.
+	     (let ((cell (assq mode font-lock-removed-keywords-alist)))
+	       (if cell
+		   (unless (member keyword (cdr cell))
+		     (nconc cell (list keyword)))
+		 (push (cons mode (list keyword))
+		       font-lock-removed-keywords-alist))))))
+	(t
+	 ;; Otherwise remove it immediately.
+	 (font-lock-set-defaults)
+	 (setq font-lock-keywords (copy-sequence font-lock-keywords))
+	 (dolist (keyword keywords)
+	   (setq font-lock-keywords
+		 (delete keyword
+			 ;; The keywords might be compiled.
+			 (delete (font-lock-compile-keyword keyword)
+				 font-lock-keywords)))))))
+
+;;; Global Font Lock mode.
+
+;; XEmacs: Formerly, we had a mechanism where, if `font-lock-auto-fontify' was
+;; non-nil, loading `font-lock' automatically turned on font lock and
+;; insinuated itself into various modes -- all by default for which font-lock
+;; had keywords. Variables `font-lock-mode-enable-list' or
+;; `font-lock-mode-disable-list' could get you finer-grained control.  The new
+;; scheme is clearly better -- instead of having a one-time non-reversible way
+;; of turning on font-lock for many modes, and the no-no of having things
+;; automatically happen when a file is loaded, there's a
+;; `global-font-lock-mode' to turn font lock on and off globally whenever you
+;; want.  The new `font-lock-global-modes' is allows for finer grained control
+;; ala the two lists we had before.  We could try to implement backwards
+;; compatibility for the lists, but since we can't (and won't) be
+;; backwards-compatible with `font-lock-auto-fontify' and the automagical
+;; behavior of loading font-lock, we may as well just make the user adjust
+;; completely to the new scheme.  It's not hard by any means.  We should be
+;; able to keep option menu compatibility, though.
+
+;; Old variables:
+
+; ;;;###autoload
+; (defcustom font-lock-auto-fontify t
+;   "*Whether font-lock should automatically fontify files as they're loaded.
+; This will only happen if font-lock has fontifying keywords for the major
+; mode of the file.  You can get finer-grained control over auto-fontification
+; by using this variable in combination with `font-lock-mode-enable-list' or
+; `font-lock-mode-disable-list'."
+;:type 'boolean
+;:group 'font-lock)
+
+; ;;;###autoload
+; (defcustom font-lock-mode-enable-list nil
+;   "*List of modes to auto-fontify, if `font-lock-auto-fontify' is nil."
+;:type '(repeat (symbol :tag "Mode"))
+;:group 'font-lock)
+
+; ;;;###autoload
+; (defcustom font-lock-mode-disable-list nil
+;   "*List of modes not to auto-fontify, if `font-lock-auto-fontify' is t."
+;:type '(repeat (symbol :tag "Mode"))
+;:group 'font-lock)
+
+;; A few people have hassled in the past for a way to make it easier to turn on
+;; Font Lock mode, without the user needing to know for which modes s/he has to
+;; turn it on, perhaps the same way hilit19.el/hl319.el does.  I've always
+;; balked at that way, as I see it as just re-moulding the same problem in
+;; another form.  That is; some person would still have to keep track of which
+;; modes (which may not even be distributed with Emacs) support Font Lock mode.
+;; The list would always be out of date.  And that person might have to be me.
 
+;; Implementation.
+;;
+;; In a previous discussion the following hack came to mind.  It is a gross
+;; hack, but it generally works.  We use the convention that major modes start
+;; by calling the function `kill-all-local-variables', which in turn runs
+;; functions on the hook variable `change-major-mode-hook'.  We attach our
+;; function `font-lock-change-major-mode' to that hook.  Of course, when this
+;; hook is run, the major mode is in the process of being changed and we do not
+;; know what the final major mode will be.  So, `font-lock-change-major-mode'
+;; only (a) notes the name of the current buffer, and (b) adds our function
+;; `turn-on-font-lock-if-enabled' to the hook variables `find-file-hooks' and
+;; `post-command-hook' (for buffers that are not visiting files).  By the time
+;; the functions on the first of these hooks to be run are run, the new major
+;; mode is assumed to be in place.  This way we get a Font Lock function run
+;; when a major mode is turned on, without knowing major modes or their hooks.
+;;
+;; Naturally this requires that (a) major modes run `kill-all-local-variables',
+;; as they are supposed to do, and (b) the major mode is in place after the
+;; file is visited or the command that ran `kill-all-local-variables' has
+;; finished, whichever the sooner.  Arguably, any major mode that does not
+;; follow the convension (a) is broken, and I can't think of any reason why (b)
+;; would not be met (except `gnudoit' on non-files).  However, it is not clean.
+;;
+;; Probably the cleanest solution is to have each major mode function run some
+;; hook, e.g., `major-mode-hook', but maybe implementing that change is
+;; impractical.  I am personally against making `setq' a macro or be advised,
+;; or have a special function such as `set-major-mode', but maybe someone can
+;; come up with another solution?
+
+;; User interface.
+;;
+;; Although Global Font Lock mode is a pseudo-mode, I think that the user
+;; interface should conform to the usual Emacs convention for modes, i.e., a
+;; command to toggle the feature (`global-font-lock-mode') with a variable for
+;; finer control of the mode's behaviour (`font-lock-global-modes').
+;;
+;; The feature should not be enabled by loading font-lock.el, since other
+;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
+;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
+;; turned on everywhere.  That would not be intuitive or informative because
+;; loading a file tells you nothing about the feature or how to control it.  It
+;; would also be contrary to the Principle of Least Surprise.  sm.
+
+(defcustom font-lock-global-modes t
+  "*Modes for which Font Lock mode is automagically turned on.
+Global Font Lock mode is controlled by the command `global-font-lock-mode'.
+If nil, means no modes have Font Lock mode automatically turned on.
+If t, all modes that support Font Lock mode have it automatically turned on.
+If a list, it should be a list of `major-mode' symbol names for which Font Lock
+mode should be automatically turned on.  The sense of the list is negated if it
+begins with `not'.  For example:
+ (c-mode c++-mode)
+means that Font Lock mode is turned on for buffers in C and C++ modes only."
+:type '(choice (const :tag "none" nil)
+		 (const :tag "all" t)
+		 (set :menu-tag "mode specific" :tag "modes"
+		      :value (not)
+		      (const :tag "Except" not)
+		      (repeat :inline t (symbol :tag "mode"))))
+:group 'font-lock)
+
+(defun turn-on-font-lock-if-enabled ()
+  (when (and (or font-lock-defaults
+		 (font-lock-find-font-lock-defaults major-mode))
+	     (or (eq font-lock-global-modes t)
+		 (if (eq (car-safe font-lock-global-modes) 'not)
+		     (not (memq major-mode (cdr font-lock-global-modes)))
+		   (memq major-mode font-lock-global-modes))))
+    (let (inhibit-quit)
+      (turn-on-font-lock))))
+
+;;;###autoload
+(easy-mmode-define-global-mode
+ global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled
+:extra-args (dummy))
+
+;;; End of Global Font Lock mode.
 
-;; Fontification functions.
+;;; Font Lock Support mode.
+
+;; This is the code used to interface font-lock.el with any of its add-on
+;; packages, and provide the user interface.  Packages that have their own
+;; local buffer fontification functions (see below) may have to call
+;; `font-lock-after-fontify-buffer' and/or `font-lock-after-unfontify-buffer'
+;; themselves.
+
+(defcustom font-lock-support-mode 'lazy-lock-mode
+  "*Support mode for Font Lock mode.
+Support modes speed up Font Lock mode by being choosy about when
+fontification occurs.  Known support modes are Fast Lock mode (symbol
+`fast-lock-mode'), Lazy Lock mode (symbol `lazy-lock-mode'), Lazy Shot mode
+\(symbol `lazy-shot-mode'), and Just-in-time Lock mode (symbol
+`jit-lock-mode').  See those modes for more info.
+If nil, means support for Font Lock mode is never performed.
+If a symbol, use that support mode.
+If a list, each element should be of the form (MAJOR-MODE . SUPPORT-MODE),
+where MAJOR-MODE is a symbol or t (meaning the default).  For example:
+ ((c-mode . fast-lock-mode) (c++-mode . fast-lock-mode) (t . lazy-lock-mode))
+means that Fast Lock mode is used to support Font Lock mode for buffers in C or
+C++ modes, and Lazy Lock mode is used to support Font Lock mode otherwise.
+
+The value of this variable is used when Font Lock mode is turned on."
+:type '(choice (const :tag "none" nil)
+		 (const :tag "fast lock" fast-lock-mode)
+		 (const :tag "lazy lock" lazy-lock-mode)
+		 (const :tag "lazy shot" lazy-shot-mode)
+		 (const :tag "jit lock" jit-lock-mode)
+		 (repeat :menu-tag "mode specific" :tag "mode specific"
+			 :value ((t . jit-lock-mode))
+			 (cons :tag "Instance"
+			       (radio :tag "Mode"
+				      (const :tag "all" t)
+				      (symbol :tag "name"))
+			       (radio :tag "Support"
+				      (const :tag "none" nil)
+				      (const :tag "fast lock" fast-lock-mode)
+				      (const :tag "lazy lock" lazy-lock-mode)
+				      (const :tag "lazy shot" lazy-shot-mode)
+				      (const :tag "JIT lock" jit-lock-mode)))
+			 ))
+:version "21.1"
+:group 'font-lock)
+
+(defvar fast-lock-mode nil)
+(defvar lazy-lock-mode nil)
+(defvar lazy-shot-mode nil)
+(defvar jit-lock-mode nil)
+
+(defun font-lock-turn-on-thing-lock ()
+  (let ((thing-mode (font-lock-value-in-major-mode font-lock-support-mode)))
+    (cond ((eq thing-mode 'fast-lock-mode)
+	   (declare-fboundp (fast-lock-mode t)))
+	  ((eq thing-mode 'lazy-lock-mode)
+	   (declare-fboundp (lazy-lock-mode t)))
+	  ((eq thing-mode 'lazy-shot-mode)
+	   (declare-fboundp (lazy-shot-mode t)))
+	  ((eq thing-mode 'jit-lock-mode)
+	   ;; Prepare for jit-lock
+	   (remove-hook 'after-change-functions
+			'font-lock-after-change-function t)
+	   (set (make-local-variable 'font-lock-fontify-buffer-function)
+		'jit-lock-refontify)
+	   ;; Don't fontify eagerly (and don't abort is the buffer is large).
+	   (set (make-local-variable 'font-lock-fontified) t)
+	   ;; Use jit-lock.
+	   (declare-fboundp
+	    (jit-lock-register 'font-lock-fontify-region
+			       (not font-lock-keywords-only)))))))
+
+(defun font-lock-turn-off-thing-lock ()
+  (cond (fast-lock-mode
+	 (declare-fboundp (fast-lock-mode -1)))
+	(jit-lock-mode
+	 (declare-fboundp
+	  (jit-lock-unregister 'font-lock-fontify-region))
+	 ;; Reset local vars to the non-jit-lock case.
+	 (kill-local-variable 'font-lock-fontify-buffer-function))
+	(lazy-lock-mode
+	 (declare-fboundp (lazy-lock-mode -1)))
+	(lazy-shot-mode
+	 (declare-fboundp (lazy-shot-mode -1)))))
+
+
+;; Various functions.
+
+;; FSF, for inexplicable reasons that make sense only to rms, does not use a
+;; hook for obvious hook-like functions, instead hard-coding the calls.
+;; There's really no reason to be this bizarre so we go ahead and have hooks.
+
+;; Turn off other related packages if they're on.  I prefer a hook. --sm.
+;; These explicit calls are easier to understand
+;; because people know what they will do.
+;; A hook is a mystery because it might do anything whatever. --rms.
+
+
+(defun font-lock-after-fontify-buffer ()
+  (run-hooks 'font-lock-after-fontify-buffer-hook)
+;   (cond ((and-boundp 'fast-lock-mode fast-lock-mode)
+; 	 (declare-fboundp (fast-lock-after-fontify-buffer)))
+; 	;; Useless now that jit-lock intercepts font-lock-fontify-buffer.  -sm
+; 	;;((and-boundp 'jit-lock-mode jit-lock-mode)
+; 	;; (declare-fboundp (jit-lock-after-fontify-buffer)))
+; 	((and-boundp 'lazy-lock-mode lazy-lock-mode)
+; 	 (declare-fboundp (lazy-lock-after-fontify-buffer))))
+  )
 
+(defun font-lock-after-unfontify-buffer ()
+  (run-hooks 'font-lock-after-unfontify-buffer-hook)
+;   (cond ((and-boundp 'fast-lock-mode fast-lock-mode)
+; 	 (declare-fboundp (fast-lock-after-unfontify-buffer)))
+; 	;; Useless as well.  It's only called when:
+; 	;; - turning off font-lock: it does not matter if we leave spurious
+; 	;;   `fontified' text props around since jit-lock-mode is also off.
+; 	;; - font-lock-default-fontify-buffer fails: this is not run
+; 	;;   any more anyway.   -sm
+; 	;;
+; 	;;((and-boundp 'jit-lock-mode jit-lock-mode)
+; 	;; (declare-fboundp (jit-lock-after-unfontify-buffer)))
+; 	((and-boundp 'lazy-lock-mode lazy-lock-mode)
+; 	 (declare-fboundp (lazy-lock-after-unfontify-buffer))))
+  )
+
+;;; End of Font Lock Support mode.
+
+
 ;; We first define some defsubsts to encapsulate the way we add
 ;; faces to a region of text.  I am planning on modifying the
 ;; text-property mechanism so that multiple independent classes
@@ -1026,9 +1563,7 @@
 (defsubst font-lock-remove-face (start end)
   ;; Remove any syntax highlighting on the characters in the range.
   (put-nonduplicable-text-property start end 'face nil)
-  (put-nonduplicable-text-property start end 'font-lock nil)
-  (if lookup-syntax-properties
-      (put-nonduplicable-text-property start end 'syntax-table nil)))
+  (put-nonduplicable-text-property start end 'font-lock nil))
 
 (defsubst font-lock-set-syntax (start end syntax)
   ;; Set the face on the characters in the range.
@@ -1052,6 +1587,7 @@
   ;; of `text-property-not-all'.  #### If so, `text-property-not-all'
   ;; should be fixed ...
   ;;
+  ;;(text-property-not-all start end 'font-lock nil)
   (map-extents 'extent-property (current-buffer) start (1- end) 'font-lock))
 
 
@@ -1099,8 +1635,6 @@
 ;;;###autoload
 (defun font-lock-fontify-buffer ()
   "Fontify the current buffer the way `font-lock-mode' would.
-See `font-lock-mode' for details.
-
 This can take a while for large buffers."
   (interactive)
   (let ((font-lock-verbose (or font-lock-verbose (interactive-p))))
@@ -1116,62 +1650,96 @@
   (funcall font-lock-unfontify-region-function beg end loudly))
 
 (defun font-lock-default-fontify-buffer ()
-  (interactive)
-  ;; if we don't widen, then the C code will fail to
-  ;; realize that we're inside a comment.
-  (save-restriction
-    (widen)
-    (let ((was-on font-lock-mode)
-	  (font-lock-verbose (or font-lock-verbose (interactive-p)))
-	  (font-lock-message-threshold 0)
-	  (aborted nil))
-      ;; Turn it on to run hooks and get the right font-lock-keywords.
-      (or was-on (font-lock-mode 1))
-      (font-lock-unfontify-region (point-min) (point-max) t)
-      ;;    (buffer-syntactic-context-flush-cache)
-    
-      ;; If a ^G is typed during fontification, abort the fontification, but
-      ;; return normally (do not signal.)  This is to make it easy to abort
-      ;; fontification if it's taking a long time, without also causing the
-      ;; buffer not to pop up.  If a real abort is desired, the user can ^G
-      ;; again.
-      ;;
-      ;; Possibly this should happen down in font-lock-fontify-region instead
-      ;; of here, but since that happens from the after-change-hook (meaning
-      ;; much more frequently) I'm afraid of the bad consequences of stealing
-      ;; the interrupt character at inopportune times.
-      ;;
-      (condition-case nil
-	  (save-excursion
-	    (font-lock-fontify-region (point-min) (point-max)))
-	(t
-	 (setq aborted t)))
-
-      (or was-on			; turn it off if it was off.
-	  (let ((font-lock-fontified nil)) ; kludge to prevent defontification
-	    (font-lock-mode 0)))
-      (set (make-local-variable 'font-lock-fontified) t)
-      (when (and aborted font-lock-verbose)
-	(progress-feedback-with-label 'font-lock "Fontifying %s... aborted."
-				      'abort (buffer-name))))
-    (run-hooks 'font-lock-after-fontify-buffer-hook)))
+  (let* (
+	 ;; XEmacs addition: Various stuff relating to messages.  Sync
+	 ;; carefully!
+	 (font-lock-verbose (or font-lock-verbose (interactive-p)))
+	 (verbose (if (numberp font-lock-verbose)
+		      (> (buffer-size) font-lock-verbose)
+		    font-lock-verbose))
+	 aborted)
+    (unwind-protect
+	(progn
+	  (when verbose
+	    (progress-feedback-with-label 'font-lock "Fontifying %s..." 0
+					  (buffer-name)))
+	  ;; Make sure we have the right `font-lock-keywords' etc.
+	  (unless font-lock-mode
+	    (font-lock-set-defaults))
+	  ;; Make sure we fontify etc. in the whole buffer.
+	  (save-restriction
+	    (widen)
+	    ;;    (buffer-syntactic-context-flush-cache)
+	    ;; If a ^G is typed during fontification, abort the
+	    ;; fontification, but return normally (do not signal.)  This is
+	    ;; to make it easy to abort fontification if it's taking a long
+	    ;; time, without also causing the buffer not to pop up.  If a
+	    ;; real abort is desired, the user can ^G
+	    ;; again.
+	    ;;
+	    ;; Possibly this should happen down in font-lock-fontify-region
+	    ;; instead of here, but since that happens from the
+	    ;; after-change-hook (meaning much more frequently) I'm afraid
+	    ;; of the bad consequences of stealing the interrupt character
+	    ;; at inopportune times.
+	    ;;
+	    (condition-case nil
+		(save-excursion
+		  (save-match-data
+		    (font-lock-fontify-region (point-min) (point-max) verbose)
+		    (font-lock-after-fontify-buffer)
+		    (setq font-lock-fontified t)))
+	      ;; We don't restore the old fontification, so it's best to
+	      ;; unfontify.
+	      (quit (setq aborted t) (font-lock-unfontify-buffer))))
+	  ;; Make sure we undo `font-lock-keywords' etc.
+	  (unless font-lock-mode
+	    (font-lock-unset-defaults)))
+      (when verbose
+	(if aborted
+	    (progress-feedback-with-label 'font-lock
+					  "Fontifying %s... aborted."
+					  'abort (buffer-name))
+	  (clear-progress-feedback 'font-lock))))))
 
 (defun font-lock-default-unfontify-buffer ()
-  (font-lock-unfontify-region (point-min) (point-max))
-  (set (make-local-variable 'font-lock-fontified) nil))
+  ;; Make sure we unfontify etc. in the whole buffer.
+  (save-restriction
+    (widen)
+    (font-lock-unfontify-region (point-min) (point-max))
+    (font-lock-after-unfontify-buffer)
+    (setq font-lock-fontified nil)))
 
 ;; This used to be `font-lock-fontify-region', and before that,
 ;; `font-lock-fontify-region' used to be the name used for what is now
 ;; `font-lock-fontify-syntactically-region'.
 (defun font-lock-default-fontify-region (beg end &optional loudly)
-  (let ((modified (buffer-modified-p))
-	(buffer-undo-list t) (inhibit-read-only t)
-	(old-syntax-table (syntax-table))
-	buffer-file-name buffer-file-truename)
+  (save-buffer-state
+      ((parse-sexp-lookup-properties font-lock-syntactic-keywords)
+       (old-syntax-table (syntax-table)))
     (unwind-protect
-	(progn
+	(save-restriction
+	  (widen)
 	  ;; Use the fontification syntax table, if any.
-	  (if font-lock-syntax-table (set-syntax-table font-lock-syntax-table))
+	  (when font-lock-syntax-table
+	    (set-syntax-table font-lock-syntax-table))
+	  ;; check to see if we should expand the beg/end area for
+	  ;; proper multiline matches
+	  (when (and font-lock-multiline
+		     (> beg (point-min))
+		     (get-text-property (1- beg) 'font-lock-multiline))
+	    ;; We are just after or in a multiline match.
+	    (setq beg (or (previous-single-property-change
+			   beg 'font-lock-multiline)
+			  (point-min)))
+	    (goto-char beg)
+	    (setq beg (line-beginning-position)))
+	  (when font-lock-multiline
+	    (setq end (or (text-property-any end (point-max)
+					     'font-lock-multiline nil)
+			  (point-max))))
+	  (goto-char end)
+	  (setq end (line-beginning-position 2))
 	  ;; Now do the fontification.
 	  (font-lock-unfontify-region beg end)
 	  (when font-lock-syntactic-keywords
@@ -1180,8 +1748,7 @@
 	    (font-lock-fontify-syntactically-region beg end loudly))
 	  (font-lock-fontify-keywords-region beg end loudly))
       ;; Clean up.
-      (set-syntax-table old-syntax-table)
-      (and (not modified) (buffer-modified-p) (set-buffer-modified-p nil)))))
+      (set-syntax-table old-syntax-table))))
 
 ;; The following must be rethought, since keywords can override fontification.
 ;      ;; Now scan for keywords, but not if we are inside a comment now.
@@ -1191,16 +1758,17 @@
 ;		 (or (nth 4 state) (nth 7 state))))
 ;	  (font-lock-fontify-keywords-region beg end))
 
-(defun font-lock-default-unfontify-region (beg end &optional maybe-loudly)
-  (when (and maybe-loudly font-lock-verbose
+(defun font-lock-default-unfontify-region (beg end &optional loudly)
+  (when (and loudly
 	     (>= (- end beg) font-lock-message-threshold))
     (progress-feedback-with-label 'font-lock "Fontifying %s..." 0
 				  (buffer-name)))
-  (let ((modified (buffer-modified-p))
-	(buffer-undo-list t) (inhibit-read-only t)
-	buffer-file-name buffer-file-truename)
+  (save-buffer-state nil
     (font-lock-remove-face beg end)
-    (and (not modified) (buffer-modified-p) (set-buffer-modified-p nil))))
+    (remove-text-properties beg end
+			    (if font-lock-syntactic-keywords
+				'(syntax-table nil font-lock-multiline nil)
+			      '(font-lock-multiline nil)))))
 
 ;; Following is the original FSF version (similar to our original
 ;; version, before the deferred stuff was added).
@@ -1209,13 +1777,14 @@
 ;; Those efforts should be merged.
 
 ;; Called when any modification is made to buffer text.
-;(defun font-lock-after-change-function (beg end old-len)
-;  (save-excursion
-;    (save-match-data
-;      ;; Rescan between start of line from `beg' and start of line after `end'.
-;      (font-lock-fontify-region
-;	(progn (goto-char beg) (beginning-of-line) (point))
-;	(progn (goto-char end) (forward-line 1) (point))))))
+; (defun font-lock-after-change-function (beg end old-len)
+;   (let ((inhibit-point-motion-hooks t))
+;     (save-excursion
+;       (save-match-data
+; 	;; Rescan between start of lines enclosing the region.
+; 	(font-lock-fontify-region
+; 	 (progn (goto-char beg) (beginning-of-line) (point))
+; 	 (progn (goto-char end) (forward-line 1) (point)))))))
 
 (defvar font-lock-always-fontify-immediately nil
   "Set this to non-nil to disable font-lock deferral.
@@ -1310,93 +1879,42 @@
 		      (font-lock-fontify-region beg end))
 		  font-lock-range-table))))))
      font-lock-pending-buffer-table)))
-
-;; Syntactic fontification functions.
 
-(defun font-lock-lisp-like (mode)
-  ;; Note: (or (get mode 'font-lock-lisp-like) (string-match ...)) is
-  ;; not enough because the property needs to be able to specify a nil
-  ;; value.
-  (if (plist-member (symbol-plist mode) 'font-lock-lisp-like)
-      (get mode 'font-lock-lisp-like)
-    ;; If the property is not specified, guess.  Similar logic exists
-    ;; in add-log, but I think this encompasses more modes.
-    (string-match "lisp\\|scheme" (symbol-name mode))))
-
-;; fontify-syntactically-region used to use syntactically-sectionize, which
-;; was supposedly much faster than the FSF version because it was written in
-;; C. However, the FSF version uses parse-partial-sexp, which is also
-;; written in C, and the benchmarking I did showed the
-;; syntactically-sectionize code to be slower overall. So here's the FSF
-;; version, modified to support font-lock-doc-string-face.
-;; -- mct 2000-12-29
-(defun font-lock-fontify-syntactically-region (start end &optional loudly)
-  "Put proper face on each string and comment between START and END.
-START should be at the beginning of a line."
-  (if font-lock-keywords-only
-      nil
+(defun font-lock-fontify-block (&optional arg)
+  "Fontify some lines the way `font-lock-fontify-buffer' would.
+The lines could be a function or paragraph, or a specified number of lines.
+If ARG is given, fontify that many lines before and after point, or 16 lines if
+no ARG is given and `font-lock-mark-block-function' is nil.
+If `font-lock-mark-block-function' non-nil and no ARG is given, it is used to
+delimit the region to fontify."
+  (interactive "P")
+  (let (;FSF 21.2 (inhibit-point-motion-hooks t)
+	font-lock-beginning-of-syntax-function
+	;FSF 21.2 deactivate-mark
+	)
+    ;; Make sure we have the right `font-lock-keywords' etc.
+    (if (not font-lock-mode) (font-lock-set-defaults))
+    (save-excursion
+      (save-match-data
+	(condition-case error-data
+	    (if (or arg (not font-lock-mark-block-function))
+		(let ((lines (if arg (prefix-numeric-value arg) 16)))
+		  (font-lock-fontify-region
+		   (save-excursion (forward-line (- lines)) (point))
+		   (save-excursion (forward-line lines) (point))))
+	      (funcall font-lock-mark-block-function)
+	      (font-lock-fontify-region (point) (mark)))
+	  ((error quit) (message "Fontifying block...%s" error-data)))))))
 
-    ;; #### Shouldn't this just be using 'loudly??
-    (when (and font-lock-verbose
-	       (>= (- end start) font-lock-message-threshold))
-      (progress-feedback-with-label 'font-lock
-				    "Fontifying %s... (syntactically)" 5
-				    (buffer-name)))
-    (goto-char start)
+;; FSF 21.2.
+;;(define-key facemenu-keymap "\M-g" 'font-lock-fontify-block)
 
-    (let ((lisp-like (font-lock-lisp-like major-mode))
-	  (cache (marker-position font-lock-cache-position))
-	  state string beg depth)
-      ;;
-      ;; Find the state at the `beginning-of-line' before `start'.
-      (if (eq start cache)
-	  ;; Use the cache for the state of `start'.
-	  (setq state font-lock-cache-state)
-	;; Find the state of `start'.
-	(if (null font-lock-beginning-of-syntax-function)
-	    ;; Use the state at the previous cache position, if any, or
-	    ;; otherwise calculate from `point-min'.
-	    (if (or (null cache) (< start cache))
-		(setq state (parse-partial-sexp (point-min) start))
-	      (setq state (parse-partial-sexp cache start nil nil
-					      font-lock-cache-state)))
-	  ;; Call the function to move outside any syntactic block.
-	  (funcall font-lock-beginning-of-syntax-function)
-	  (setq state (parse-partial-sexp (point) start)))
-	;; Cache the state and position of `start'.
-	(setq font-lock-cache-state state)
-	(set-marker font-lock-cache-position start))
-      ;;
-      ;; If the region starts inside a string or comment, show the extent of it.
-      (when (or (nth 3 state) (nth 4 state))
-	(setq string (nth 3 state) beg (point))
-	(setq state (parse-partial-sexp (point) end nil nil state 'syntax-table))
-	(font-lock-set-face beg (point) (if string 
-					    font-lock-string-face
-					  font-lock-comment-face)))
-      ;;
-      ;; Find each interesting place between here and `end'.
-      (while (and (< (point) end)
-		  (progn
-		    (setq state (parse-partial-sexp (point) end nil nil state
-						    'syntax-table))
-		    (or (nth 3 state) (nth 4 state))))
-	(setq depth (nth 0 state) string (nth 3 state) beg (nth 8 state))
-	(setq state (parse-partial-sexp (point) end nil nil state 'syntax-table))
-	(if string
-	    ;; #### It would be nice if we handled Python and other
-	    ;; non-Lisp languages with docstrings correctly.
-	    (let ((face (if (and lisp-like (= depth 1))
-			    'font-lock-doc-string-face
-			  'font-lock-string-face)))
-	      (if font-lock-fontify-string-delimiters
-		  (font-lock-set-face beg (point) face)
-		(font-lock-set-face (+ beg 1) (- (point) 1) face)))
-	  (font-lock-set-face beg (point)
-			      font-lock-comment-face))))))
+;;; End of Fontification functions.
 
 ;;; Additional text property functions.
 
+;;;; We write:
+
 ;; The following three text property functions are not generally available (and
 ;; it's not certain that they should be) so they are inlined for speed.
 ;; The case for `fillin-text-property' is simple; it may or not be generally
@@ -1411,17 +1929,17 @@
 ;; the first one to take both SETPROP and MARKPROP, in accordance with the
 ;; changed definitions of `font-lock-any-faces-p' and `font-lock-set-face'.
 
-(defsubst font-lock-fillin-text-property (start end setprop markprop value &optional object)
-  "Fill in one property of the text from START to END.
-Arguments PROP and VALUE specify the property and value to put where none are
-already in place.  Therefore existing property values are not overwritten.
-Optional argument OBJECT is the string or buffer containing the text."
-  (let ((start (text-property-any start end markprop nil object)) next)
-    (while start
-      (setq next (next-single-property-change start markprop object end))
-      (put-nonduplicable-text-property start next setprop value object)
-      (put-nonduplicable-text-property start next markprop value object)
-      (setq start (text-property-any next end markprop nil object)))))
+;;;; FSF writes:
+
+;; The following text property functions should be builtins.  This means they
+;; should be written in C and put with all the other text property functions.
+;; In the meantime, those that are used by font-lock.el are defined in Lisp
+;; below and given a `font-lock-' prefix.  Those that are not used are defined
+;; in Lisp below and commented out.  sm.
+
+;;;; XEmacs: We also have some additions here: call font-lock-unique in
+;;;; certain places, allow for two different properties in
+;;;; font-lock-fillin-text-property.
 
 ;; This function (from simon's unique.el) is rewritten and inlined for speed.
 ;(defun unique (list function)
@@ -1476,6 +1994,52 @@
        (font-lock-unique (append (if (listp prev) prev (list prev)) val))
        object)
       (setq start next))))
+
+(defsubst font-lock-fillin-text-property (start end setprop markprop value &optional object)
+  "Fill in one property of the text from START to END.
+Arguments PROP and VALUE specify the property and value to put where none are
+already in place.  Therefore existing property values are not overwritten.
+Optional argument OBJECT is the string or buffer containing the text."
+  (let ((start (text-property-any start end markprop nil object)) next)
+    (while start
+      (setq next (next-single-property-change start markprop object end))
+      (put-nonduplicable-text-property start next setprop value object)
+      (put-nonduplicable-text-property start next markprop value object)
+      (setq start (text-property-any next end markprop nil object)))))
+
+;; For completeness: this is to `remove-text-properties' as `put-text-property'
+;; is to `add-text-properties', etc.
+;(defun remove-text-property (start end property &optional object)
+;  "Remove a property from text from START to END.
+;Argument PROPERTY is the property to remove.
+;Optional argument OBJECT is the string or buffer containing the text.
+;Return t if the property was actually removed, nil otherwise."
+;  (remove-text-properties start end (list property) object))
+
+;; For consistency: maybe this should be called `remove-single-property' like
+;; `next-single-property-change' (not `next-single-text-property-change'), etc.
+;(defun remove-single-text-property (start end prop value &optional object)
+;  "Remove a specific property value from text from START to END.
+;Arguments PROP and VALUE specify the property and value to remove.  The
+;resulting property values are not equal to VALUE nor lists containing VALUE.
+;Optional argument OBJECT is the string or buffer containing the text."
+;  (let ((start (text-property-not-all start end prop nil object)) next prev)
+;    (while start
+;      (setq next (next-single-property-change start prop object end)
+;	    prev (get-text-property start prop object))
+;      (cond ((and (symbolp prev) (eq value prev))
+;	     (remove-text-property start next prop object))
+;	    ((and (listp prev) (memq value prev))
+;	     (let ((new (delq value prev)))
+;	       (cond ((null new)
+;		      (remove-text-property start next prop object))
+;		     ((= (length new) 1)
+;		      (put-text-property start next prop (car new) object))
+;		     (t
+;		      (put-text-property start next prop new object))))))
+;      (setq start (text-property-not-all next end prop nil object)))))
+
+;;; End of Additional text property functions.
 
 ;;; Syntactic regexp fontification functions (taken from FSF Emacs 20.7.1)
 
@@ -1492,17 +2056,29 @@
 HIGHLIGHT should be of the form MATCH-HIGHLIGHT,
 see `font-lock-syntactic-keywords'."
   (let* ((match (nth 0 highlight))
- 	 (start (match-beginning match)) (end (match-end match))
- 	 (value (nth 1 highlight))
- 	 (override (nth 2 highlight)))
-    (unless (numberp (car-safe value))
+	 (start (match-beginning match)) (end (match-end match))
+	 (value (nth 1 highlight))
+	 (override (nth 2 highlight)))
+    (when (and (consp value) (not (numberp (car value))))
       (setq value (eval value)))
+    (when (stringp value) (setq value (string-to-syntax value)))
     (cond ((not start)
  	   ;; No match but we might not signal an error.
  	   (or (nth 3 highlight)
  	       (error "No match %d in highlight %S" match highlight)))
  	  ((not override)
+	   ;; FSF 21.2 version. #### Need to investigate here the use of
+	   ;; map-extents vs. text-property-not-all, which should be just
+	   ;; as fast, if not faster.
  	   ;; Cannot override existing fontification.
+; 	   (or (text-property-not-all start end 'syntax-table nil)
+; 	       (put-text-property start end 'syntax-table value)))
+; 	  ((eq override t)
+; 	   ;; Override existing fontification.
+; 	   (put-text-property start end 'syntax-table value))
+; 	  ((eq override 'keep)
+; 	   ;; Keep existing fontification.
+; 	   (font-lock-fillin-text-property start end 'syntax-table value)))))
  	   (or (map-extents 'extent-property (current-buffer)
 			    start end 'syntax-table)
 	       (font-lock-set-syntax start end value)))
@@ -1516,66 +2092,163 @@
 
 (defun font-lock-fontify-syntactic-anchored-keywords (keywords limit)
   "Fontify according to KEYWORDS until LIMIT.
- KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords',
- LIMIT can be modified by the value of its PRE-MATCH-FORM."
+KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords',
+LIMIT can be modified by the value of its PRE-MATCH-FORM."
   (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
- 	;; Evaluate PRE-MATCH-FORM.
- 	(pre-match-value (eval (nth 1 keywords))))
+	;; Evaluate PRE-MATCH-FORM.
+	(pre-match-value (eval (nth 1 keywords))))
     ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
     (if (and (numberp pre-match-value) (> pre-match-value (point)))
- 	(setq limit pre-match-value)
-      (save-excursion (end-of-line) (setq limit (point))))
+	(setq limit pre-match-value)
+      (setq limit (line-end-position)))
     (save-match-data
       ;; Find an occurrence of `matcher' before `limit'.
       (while (if (stringp matcher)
- 		 (re-search-forward matcher limit t)
- 	       (funcall matcher limit))
- 	;; Apply each highlight to this instance of `matcher'.
- 	(setq highlights lowdarks)
- 	(while highlights
- 	  (font-lock-apply-syntactic-highlight (car highlights))
- 	  (setq highlights (cdr highlights)))))
+		 (re-search-forward matcher limit t)
+	       (funcall matcher limit))
+	;; Apply each highlight to this instance of `matcher'.
+	(setq highlights lowdarks)
+	(while highlights
+	  (font-lock-apply-syntactic-highlight (car highlights))
+	  (setq highlights (cdr highlights)))))
     ;; Evaluate POST-MATCH-FORM.
     (eval (nth 2 keywords))))
 
 (defun font-lock-fontify-syntactic-keywords-region (start end)
   "Fontify according to `font-lock-syntactic-keywords' between START and END.
+START should be at the beginning of a line."
+  ;; Ensure the beginning of the file is properly syntactic-fontified.
+  (when (and font-lock-syntactically-fontified
+	     (< font-lock-syntactically-fontified start))
+    (setq start (max font-lock-syntactically-fontified (point-min)))
+    (setq font-lock-syntactically-fontified end))
+  ;; If `font-lock-syntactic-keywords' is a symbol, get the real keywords.
+  (when (symbolp font-lock-syntactic-keywords)
+    (setq font-lock-syntactic-keywords (font-lock-eval-keywords
+					font-lock-syntactic-keywords)))
+  ;; If `font-lock-syntactic-keywords' is not compiled, compile it.
+  (unless (eq (car font-lock-syntactic-keywords) t)
+    (setq font-lock-syntactic-keywords (font-lock-compile-keywords
+					font-lock-syntactic-keywords)))
+  ;; Get down to business.
+  (let ((case-fold-search font-lock-keywords-case-fold-search)
+	(keywords (cdr font-lock-syntactic-keywords))
+	keyword matcher highlights)
+    (while keywords
+      ;; Find an occurrence of `matcher' from `start' to `end'.
+      (setq keyword (car keywords) matcher (car keyword))
+      (goto-char start)
+      (while (if (stringp matcher)
+		 (re-search-forward matcher end t)
+	       (funcall matcher end))
+	;; Apply each highlight to this instance of `matcher', which may be
+	;; specific highlights or more keywords anchored to `matcher'.
+	(setq highlights (cdr keyword))
+	(while highlights
+	  (if (numberp (car (car highlights)))
+	      (font-lock-apply-syntactic-highlight (car highlights))
+	    (font-lock-fontify-syntactic-anchored-keywords (car highlights)
+							   end))
+	  (setq highlights (cdr highlights))))
+      (setq keywords (cdr keywords)))))
+
+;;; End of Syntactic regexp fontification functions.
+
+
+;; Syntactic fontification functions.
+
+;; These record the parse state at a particular position, always the start of a
+;; line.  Used to make `font-lock-fontify-syntactically-region' faster.
+;; Previously, `font-lock-cache-position' was just a buffer position.  However,
+;; under certain situations, this occasionally resulted in mis-fontification.
+;; I think the "situations" were deletion with Lazy Lock mode's deferral.  sm.
+(defvar font-lock-cache-state nil)
+(defvar font-lock-cache-position nil)
+(make-variable-buffer-local 'font-lock-cache-state)
+(make-variable-buffer-local 'font-lock-cache-position)
+
+(defun font-lock-lisp-like (mode)
+  ;; Note: (or (get mode 'font-lock-lisp-like) (string-match ...)) is
+  ;; not enough because the property needs to be able to specify a nil
+  ;; value.
+  (if (plist-member (symbol-plist mode) 'font-lock-lisp-like)
+      (get mode 'font-lock-lisp-like)
+    ;; If the property is not specified, guess.  Similar logic exists
+    ;; in add-log, but I think this encompasses more modes.
+    (string-match "lisp\\|scheme" (symbol-name mode))))
+
+;; fontify-syntactically-region used to use syntactically-sectionize, which
+;; was supposedly much faster than the FSF version because it was written in
+;; C. However, the FSF version uses parse-partial-sexp, which is also
+;; written in C, and the benchmarking I did showed the
+;; syntactically-sectionize code to be slower overall. So here's the FSF
+;; version, modified to support font-lock-doc-string-face.
+;; -- mct 2000-12-29
+;; Now synched with 21.2. --ben
+(defun font-lock-fontify-syntactically-region (start end &optional loudly)
+  "Put proper face on each string and comment between START and END.
 START should be at the beginning of a line."
-;;  ;; If `font-lock-syntactic-keywords' is a symbol, get the real keywords.
-  (when (symbolp font-lock-syntactic-keywords)
-    (setq font-lock-syntactic-keywords (font-lock-eval-keywords
-					font-lock-syntactic-keywords)))
-  ;; If `font-lock-syntactic-keywords' is not compiled, compile it.
-  (unless (eq (car font-lock-syntactic-keywords) t)
-    (setq font-lock-syntactic-keywords (font-lock-compile-keywords
-					font-lock-syntactic-keywords)))
-  ;; Get down to business.
-  (let ((case-fold-search font-lock-keywords-case-fold-search)
-	(keywords (cdr font-lock-syntactic-keywords))
-	keyword matcher highlights)
-    (while keywords
-      ;; Find an occurrence of `matcher' from `start' to `end'.
-      (setq keyword (car keywords) matcher (car keyword))
-      (goto-char start)
-      (while (if (stringp matcher)
-		 (re-search-forward matcher end t)
-	       (funcall matcher end))
-	;; Apply each highlight to this instance of `matcher', which may be
-	;; specific highlights or more keywords anchored to `matcher'.
-	(setq highlights (cdr keyword))
-	(while highlights
-	  (if (numberp (car (car highlights)))
-	      (font-lock-apply-syntactic-highlight (car highlights))
-	    (font-lock-fontify-syntactic-anchored-keywords (car highlights)
-							   end))
-	  (setq highlights (cdr highlights))))
-      (setq keywords (cdr keywords)))))
+  (let ((cache (marker-position font-lock-cache-position))
+	state face beg stringp) ;; STRINGP is XEmacs addition
+    ;; XEmacs: implement font-lock-message-threshold and progress bars.
+    (if (and loudly (>= (- end start) font-lock-message-threshold))
+	(progress-feedback-with-label
+	 'font-lock "Fontifying %s... (syntactically...)" 5
+	 (buffer-name)))
+    (goto-char start)
+    ;;
+    ;; Find the state at the `beginning-of-line' before `start'.
+    (if (eq start cache)
+	;; Use the cache for the state of `start'.
+	(setq state font-lock-cache-state)
+      ;; Find the state of `start'.
+      (if (null font-lock-beginning-of-syntax-function)
+	  ;; Use the state at the previous cache position, if any, or
+	  ;; otherwise calculate from `point-min'.
+	  (if (or (null cache) (< start cache))
+	      (setq state (parse-partial-sexp (point-min) start))
+	    (setq state (parse-partial-sexp cache start nil nil
+					    font-lock-cache-state)))
+	;; Call the function to move outside any syntactic block.
+	(funcall font-lock-beginning-of-syntax-function)
+	(setq state (parse-partial-sexp (point) start)))
+      ;; Cache the state and position of `start'.
+      (setq font-lock-cache-state state)
+      (set-marker font-lock-cache-position start))
+    ;;
+    ;; If the region starts inside a string or comment, show the extent of it.
+    (when (or (nth 3 state) (nth 4 state))
+      (setq face (funcall font-lock-syntactic-face-function state) beg (point))
+      (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table))
+      ;; XEmacs change: call font-lock-set-face
+      (font-lock-set-face beg (point) face))
+    ;;
+    ;; Find each interesting place between here and `end'.
+    (while (and (< (point) end)
+		(progn
+		  (setq state (parse-partial-sexp (point) end nil nil state
+						  'syntax-table))
+		  (or (nth 3 state) (nth 4 state))))
+      (setq face (funcall font-lock-syntactic-face-function state)
+	    stringp (nth 3 state)
+	    beg (nth 8 state))
+      (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table))
+      ;; XEmacs change: call font-lock-set-face, handle
+      ;; font-lock-fontify-string-delimiters.
+      (if (and stringp (not font-lock-fontify-string-delimiters))
+	  (font-lock-set-face (+ beg 1) (- (point) 1) face)
+	(font-lock-set-face beg (point) face)))))
+
+;;; End of Syntactic fontification functions.
+
 
 ;;; Regexp fontification functions.
 
 (defsubst font-lock-apply-highlight (highlight)
   "Apply HIGHLIGHT following a match.
 HIGHLIGHT should be of the form MATCH-HIGHLIGHT, see `font-lock-keywords'."
+  ;; XEmacs changes to this.  The FSF function is basically unchanged from
+  ;; 19.34 through 21.2 but we have some additions -- e.g. NEWFACE.
   (let* ((match (nth 0 highlight))
 	 (start (match-beginning match)) (end (match-end match))
 	 (override (nth 2 highlight)))
@@ -1610,17 +2283,27 @@
 KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords',
 LIMIT can be modified by the value of its PRE-MATCH-FORM."
   (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
+	(lead-start (match-beginning 0))
 	;; Evaluate PRE-MATCH-FORM.
 	(pre-match-value (eval (nth 1 keywords))))
     ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
-    (if (and (numberp pre-match-value) (> pre-match-value (point)))
-	(setq limit pre-match-value)
-      (save-excursion (end-of-line) (setq limit (point))))
+    (if (not (and (numberp pre-match-value) (> pre-match-value (point))))
+	(setq limit (line-end-position))
+      (setq limit pre-match-value)
+      (when (and font-lock-multiline (>= limit (line-beginning-position 2)))
+	;; this is a multiline anchored match
+	;; (setq font-lock-multiline t)
+	(put-text-property (if (= limit (line-beginning-position 2))
+			       (1- limit)
+			     (min lead-start (point)))
+			   limit
+			   'font-lock-multiline t)))
     (save-match-data
       ;; Find an occurrence of `matcher' before `limit'.
-      (while (if (stringp matcher)
-		 (re-search-forward matcher limit t)
-	       (funcall matcher limit))
+      (while (and (< (point) limit)
+		  (if (stringp matcher)
+		      (re-search-forward matcher limit t)
+		    (funcall matcher limit)))
 	;; Apply each highlight to this instance of `matcher'.
 	(setq highlights lowdarks)
 	(while highlights
@@ -1629,10 +2312,11 @@
     ;; Evaluate POST-MATCH-FORM.
     (eval (nth 2 keywords))))
 
-(defun font-lock-fontify-keywords-region (start end &optional loudvar)
+(defun font-lock-fontify-keywords-region (start end &optional loudly)
   "Fontify according to `font-lock-keywords' between START and END.
 START should be at the beginning of a line."
-  (let ((loudly (and font-lock-verbose
+  ;; XEmacs addition: font-lock-message-threshold
+  (let ((loudly (and loudly
 		     (>= (- end start) font-lock-message-threshold))))
     ;; If `font-lock-keywords' is not compiled, compile it.
     (unless (eq (car-safe font-lock-keywords) t)
@@ -1640,11 +2324,12 @@
 				font-lock-keywords)))
     (let* ((case-fold-search font-lock-keywords-case-fold-search)
 	   (keywords (cdr font-lock-keywords))
-	   (bufname (buffer-name)) 
+	   (bufname (buffer-name)) (count 0)
+	   keyword matcher highlights
+	   ;; XEmacs addition: for progress gauge
+	   regexp-dots
 	   (progress 5) (old-progress 5)
-	   (iter 0)
-	   (nkeywords (length keywords))
-	   keyword matcher highlights)
+	   (nkeywords (length keywords)))
       ;;
       ;; Fontify each item in `font-lock-keywords' from `start' to `end'.
       ;; In order to measure progress accurately we need to know how
@@ -1652,6 +2337,8 @@
       ;; is ((pos - start)/ (end - start) * nkeywords 
       ;; 	+ iteration / nkeywords) * 100
       (while keywords
+	;; XEmacs: message display is down below.
+	(setq regexp-dots (make-string (incf count) ?.))
 	;;
 	;; Find an occurrence of `matcher' from `start' to `end'.
 	(setq keyword (car keywords) matcher (car keyword))
@@ -1660,78 +2347,78 @@
 		    (if (stringp matcher)
 			(re-search-forward matcher end t)
 		      (funcall matcher end)))
-	  ;; calculate progress
+	  ;; XEmacs: calculate progress, display
 	  (setq progress
 		(+ (/ (* (- (point) start) 95) (* (- end start) nkeywords))
-		   (/ (* iter 95) nkeywords) 5))
+		   (/ (* (1- count) 95) nkeywords) 5))
 	  (when (and loudly (> progress old-progress))
 	    (progress-feedback-with-label 'font-lock
-					  "Fontifying %s... (regexps)"
-					  progress bufname))
+					  "Fontifying %s... (regexps..%s)"
+					  progress bufname regexp-dots))
 	  (setq old-progress progress)
+	  (when (and font-lock-multiline
+		     (>= (point)
+			 (save-excursion (goto-char (match-beginning 0))
+					 (forward-line 1) (point))))
+	    ;; this is a multiline regexp match
+	    ;; (setq font-lock-multiline t)
+	    (put-nonduplicable-text-property
+	     (if (= (point)
+		    (save-excursion
+		      (goto-char (match-beginning 0))
+		      (forward-line 1) (point)))
+		 (1- (point))
+	       (match-beginning 0))
+	     (point)
+	     'font-lock-multiline t))
 	  ;; Apply each highlight to this instance of `matcher', which may be
 	  ;; specific highlights or more keywords anchored to `matcher'.
 	  (setq highlights (cdr keyword))
 	  (while highlights
 	    (if (numberp (car (car highlights)))
+		;; XEmacs addition (next line)
 		(let ((end (match-end (car (car highlights)))))
 		  (font-lock-apply-highlight (car highlights))
-		  ;; restart search just after the end of the
-		  ;; keyword so keywords can share bracketing
-		  ;; expressions.
+		  ;; XEmacs addition (Kyle Jones, 1997): restart search
+		  ;; just after the end of the keyword so keywords can
+		  ;; share bracketing expressions.
 		  (and end (goto-char end)))
 	      (font-lock-fontify-anchored-keywords (car highlights) end))
 	    (setq highlights (cdr highlights))))
-	(setq iter (1+ iter))
 	(setq keywords (cdr keywords))))
     (if loudly
 	(progress-feedback-with-label 'font-lock "Fontifying %s... " 100
 				      (buffer-name)))))
-
-
-;; Various functions.
-
-;; Turn off other related packages if they're on.  I prefer a hook. --sm.
-;; These explicit calls are easier to understand
-;; because people know what they will do.
-;; A hook is a mystery because it might do anything whatever. --rms.
-(defun font-lock-thing-lock-cleanup ()
-  (cond ((and-boundp 'fast-lock-mode fast-lock-mode)
-	 (declare-fboundp (fast-lock-mode -1)))
-	((and-boundp 'lazy-lock-mode lazy-lock-mode)
-	 (declare-fboundp (lazy-lock-mode -1)))
-	((and-boundp 'lazy-shot-mode lazy-shot-mode)
-	 (declare-fboundp (lazy-shot-mode -1)))))
-
-; Do something special for these packages after fontifying.  I prefer a hook.
-(defun font-lock-after-fontify-buffer ()
-  (cond ((and-boundp 'fast-lock-mode fast-lock-mode)
-	 (declare-fboundp (fast-lock-after-fontify-buffer)))
-	((and-boundp 'lazy-lock-mode lazy-lock-mode)
-	 (declare-fboundp (lazy-lock-after-fontify-buffer)))))
 
+;;; End of Keyword regexp fontification functions.
 
 ;; Various functions.
 
 (defun font-lock-compile-keywords (keywords)
-  "Compile KEYWORDS (a list) and return the list of compiled keywords.
-Each keyword has the form (MATCHER HIGHLIGHT ...).  See `font-lock-keywords'."
+  "Compile KEYWORDS into the form (t KEYWORD ...).
+Here KEYWORD is of the form (MATCHER HIGHLIGHT ...) as shown in the
+`font-lock-keywords' doc string."
   (if (eq (car-safe keywords) t)
       keywords
     (cons t (mapcar 'font-lock-compile-keyword keywords))))
 
 (defun font-lock-compile-keyword (keyword)
-  (cond ((nlistp keyword)		; Just MATCHER
+  (cond ((nlistp keyword)			; MATCHER
 	 (list keyword '(0 font-lock-keyword-face)))
-	((eq (car keyword) 'eval)	; Specified (eval . FORM)
+	((eq (car keyword) 'eval)		; (eval . FORM)
 	 (font-lock-compile-keyword (eval (cdr keyword))))
-	((numberp (cdr keyword))	; Specified (MATCHER . MATCH)
+	((eq (car-safe (cdr keyword)) 'quote)	; (MATCHER . 'FORM)
+	 ;; If FORM is a FACENAME then quote it.  Otherwise ignore the quote.
+	 (if (symbolp (nth 2 keyword))
+	     (list (car keyword) (list 0 (cdr keyword)))
+	   (font-lock-compile-keyword (cons (car keyword) (nth 2 keyword)))))
+	((numberp (cdr keyword))		; (MATCHER . MATCH)
 	 (list (car keyword) (list (cdr keyword) 'font-lock-keyword-face)))
-	((symbolp (cdr keyword))	; Specified (MATCHER . FACENAME)
+	((symbolp (cdr keyword))		; (MATCHER . FACENAME)
 	 (list (car keyword) (list 0 (cdr keyword))))
-	((nlistp (nth 1 keyword))	; Specified (MATCHER . HIGHLIGHT)
+	((nlistp (nth 1 keyword))		; (MATCHER . HIGHLIGHT)
 	 (list (car keyword) (cdr keyword)))
-	(t				; Hopefully (MATCHER HIGHLIGHT ...)
+	(t					; (MATCHER HIGHLIGHT ...)
 	 keyword)))
 
 (defun font-lock-eval-keywords (keywords)
@@ -1742,9 +2429,19 @@
 				 (funcall keywords)
 			       (eval keywords)))))
 
+(defun font-lock-value-in-major-mode (alist)
+  "Return value in ALIST for `major-mode', or ALIST if it is not an alist.
+Structure is ((MAJOR-MODE . VALUE) ...) where MAJOR-MODE may be t."
+  (if (consp alist)
+      (cdr (or (assq major-mode alist) (assq t alist)))
+    alist))
+
 (defun font-lock-choose-keywords (keywords level)
-  ;; Return LEVELth element of KEYWORDS.  A LEVEL of nil is equal to a
-  ;; LEVEL of 0, a LEVEL of t is equal to (1- (length KEYWORDS)).
+  "Return LEVELth element of KEYWORDS.
+A LEVEL of nil is equal to a LEVEL of 0, a LEVEL of t is equal to
+\(1- (length KEYWORDS))."
+  ;; XEmacs: This function is rather different because it supports LEVEL
+  ;; being a cons of data, from which we have to extract the correct value.
   (let ((level (if (not (consp level))
 		   level
 		 (cdr (or (assq major-mode level) (assq t level))))))
@@ -1771,122 +2468,489 @@
       )
     raw-defaults))
 
-(defun font-lock-examine-syntax-table ()
-  ; Computes the value of font-lock-keywords-only for this buffer.
-  (if (eq (syntax-table) (standard-syntax-table))
-      ;; Assume that modes which haven't bothered to install their own
-      ;; syntax table don't do anything syntactically interesting.
-      ;; Really, the standard-syntax-table shouldn't have comments and
-      ;; strings in it, but changing that now might break things.
-      nil
-    ;; else map over the syntax table looking for strings or comments.
-    (let (got-one)
-      ;; XEmacs 20.0 ...
-      (if (fboundp 'map-syntax-table)
-	  (setq got-one
-		(map-syntax-table
-		 #'(lambda (key value)
-		     (memq (char-syntax-from-code value)
-			   '(?\" ?\< ?\> ?\$)))
-		 (syntax-table)))
-	;; older Emacsen.
-	(let ((i (1- (length (syntax-table)))))
-	  (while (>= i 0)
-	    (if (memq (char-syntax i) '(?\" ?\< ?\> ?\$))
-		(setq got-one t i 0))
-	    (setq i (1- i)))))
-      (set (make-local-variable 'font-lock-keywords-only) (not got-one)))))
+;;;###autoload
+(defun font-lock-set-defaults (&optional explicit-defaults)
+  "Set fontification defaults appropriately for this mode.
+
+If EXPLICIT-DEFAULTS is not nil and not t, it is used to compute the
+defaults; else, if `font-lock-defaults' is currently set, it is used;
+else, the symbol naming the major mode is examined for a `font-lock-defaults'
+property.
+
+The value of `font-lock-maximum-decoration' is used to determine which
+set of keywords applies, if more than one exists.
+
+Calling this function multiple times in the same buffer is safe -- this
+function keeps track of whether it has already been called in this buffer, and
+does nothing if so (unless EXPLICIT-DEFAULTS is non-nil).  This allows for
+multiple ways of getting Font Lock properly initialized in a buffer, to deal
+with existing major modes that do not call this function. (For example, Font
+Lock adds this function to `find-file-hooks'.)
+
+Major modes that have any font-lock defaults specified should call this
+function during their initialization process, after they have set
+the variable `major-mode'."
+  ;; Set fontification defaults iff not previously set (or if EXPLICIT-DEFAULTS
+  ;; is specified).
+  (unless (and font-lock-set-defaults (not explicit-defaults))
+    (set (make-local-variable 'font-lock-set-defaults)		t)
+    (set (make-local-variable 'font-lock-cache-state)		nil)
+    (set (make-local-variable 'font-lock-cache-position)	(make-marker))
+    (make-local-variable 'font-lock-fontified)
+    (make-local-variable 'font-lock-multiline)
+    (let* ((defaults (or ;; XEmacs
+		      ;; Explicit defaults given.
+		      (and (not (eq t explicit-defaults))
+			   explicit-defaults)
+		      ;; in case modes decide to set
+		      ;; `font-lock-defaults' themselves,
+		      ;; as in FSF Emacs.
+		      font-lock-defaults
+		      ;; FSF 21.2:
+		      ;; (cdr (assq major-mode font-lock-defaults-alist))
+		      (font-lock-find-font-lock-defaults major-mode)))
+	   (keywords
+	    (font-lock-choose-keywords (nth 0 defaults)
+	     (font-lock-value-in-major-mode font-lock-maximum-decoration)))
+	   (local (cdr (assq major-mode font-lock-keywords-alist)))
+	   (removed-keywords
+	    (cdr-safe (assq major-mode font-lock-removed-keywords-alist))))
+      ;; Previous XEmacs code here.  This dates back at least to 1994 and is
+      ;; undocumented, so there seems no reason to keep it.
+;       (or keywords
+; 	  ;; older way:
+; 	  ;; try to look for a variable `foo-mode-font-lock-keywords',
+; 	  ;; or similar.
+; 	  (let ((major (symbol-name major-mode))
+; 		(try #'(lambda (n)
+; 			 (if (stringp n) (setq n (intern-soft n)))
+; 			 (if (and n
+; 				  (boundp n))
+; 			     n
+; 			   nil))))
+; 	    (setq keywords
+; 		  (symbol-value
+; 		   (or (funcall try (get major-mode 'font-lock-keywords))
+; 		       (funcall try (concat major "-font-lock-keywords"))
+; 		       (funcall try (and (string-match "-mode\\'" major)
+; 					 (concat (substring 
+; 						  major 0 
+; 						  (match-beginning 0))
+; 						 "-font-lock-keywords")))
+; 		       'font-lock-keywords)))))
+      ;; Regexp fontification?
+      (set (make-local-variable 'font-lock-keywords)
+	   (font-lock-compile-keywords (font-lock-eval-keywords keywords)))
+      ;; Local fontification?
+      (while local
+	(font-lock-add-keywords nil (car (car local)) (cdr (car local)))
+	(setq local (cdr local)))
+      (when removed-keywords
+	(font-lock-remove-keywords nil removed-keywords))
+      ;; Syntactic fontification?
+      (when (nth 1 defaults)
+	(set (make-local-variable 'font-lock-keywords-only) t))
+      ;; Case fold during regexp fontification?
+      (when (nth 2 defaults)
+	(set (make-local-variable 'font-lock-keywords-case-fold-search) t))
+      ;; Syntax table for regexp and syntactic fontification?
+      (when (nth 3 defaults)
+	(let ((slist (nth 3 defaults)))
+	  (set (make-local-variable 'font-lock-syntax-table)
+	       (copy-syntax-table (syntax-table)))
+	  (while slist
+	    ;; The character to modify may be a single CHAR or a STRING.
+	    (let ((chars (if (numberp (car (car slist)))
+			     (list (car (car slist)))
+			   (mapcar 'identity (car (car slist)))))
+		  (syntax (cdr (car slist))))
+	      (while chars
+		(modify-syntax-entry (car chars) syntax font-lock-syntax-table)
+		(setq chars (cdr chars)))
+	      (setq slist (cdr slist))))))
+      ;; Syntax function for syntactic fontification?
+      (when (nth 4 defaults)
+	(set (make-local-variable 'font-lock-beginning-of-syntax-function)
+	     (nth 4 defaults)))
+      ;; Variable alist?
+      (dolist (x (nthcdr 5 defaults))
+	(let ((variable (car x)) (value (cdr x)))
+	  (unless (boundp variable)
+	    (set variable nil))		;why ?
+	  (set (make-local-variable variable) value))))))
+
+(defun font-lock-unset-defaults ()
+  "Unset fontification defaults.  See function `font-lock-set-defaults'."
+  (setq font-lock-set-defaults			nil
+	font-lock-keywords			nil
+	font-lock-keywords-only			nil
+	font-lock-keywords-case-fold-search	nil
+	font-lock-syntax-table			nil
+	font-lock-beginning-of-syntax-function	nil)
+  (let* ((defaults (or font-lock-defaults
+		      ;; FSF 21.2:
+		      ;; (cdr (assq major-mode font-lock-defaults-alist))
+		      (font-lock-find-font-lock-defaults major-mode)))
+	 (alist (nthcdr 5 defaults)))
+    (while alist
+      (set (car (car alist)) (default-value (car (car alist))))
+      (setq alist (cdr alist)))))
+
+;;; Colour etc. support.
 
-;; font-lock-set-defaults is in fontl-hooks.el.
+;; FSF has:
 
-;;;###autoload
-(defun font-lock-set-defaults-1 (&optional explicit-defaults)
-  ;; does everything that font-lock-set-defaults does except
-  ;; enable font-lock-mode.  This is called by `font-lock-mode'.
-  ;; Note that the return value is used!
-
-  (if (and font-lock-defaults-computed (not explicit-defaults))
-      ;; nothing to do.
-      nil
-
-    (or font-lock-keywords
-	(let* ((defaults (or (and (not (eq t explicit-defaults))
-				  explicit-defaults)
-			     ;; in case modes decide to set
-			     ;; `font-lock-defaults' themselves,
-			     ;; as in FSF Emacs.
-			     font-lock-defaults
-			     (font-lock-find-font-lock-defaults major-mode)))
-	       (keywords (font-lock-choose-keywords
-			  (nth 0 defaults) font-lock-maximum-decoration)))
-
-	  ;; Keywords?
-	  (setq font-lock-keywords (if (fboundp keywords)
-				       (funcall keywords)
-				     (eval keywords)))
-	  (or font-lock-keywords
-	      ;; older way:
-	      ;; try to look for a variable `foo-mode-font-lock-keywords',
-	      ;; or similar.
-	      (let ((major (symbol-name major-mode))
-		    (try #'(lambda (n)
-			     (if (stringp n) (setq n (intern-soft n)))
-			     (if (and n
-				      (boundp n))
-				 n
-			       nil))))
-		(setq font-lock-keywords 
-		      (symbol-value
-		       (or (funcall try (get major-mode 'font-lock-keywords))
-			   (funcall try (concat major "-font-lock-keywords"))
-			   (funcall try (and (string-match "-mode\\'" major)
-					     (concat (substring 
-						      major 0 
-						      (match-beginning 0))
-						     "-font-lock-keywords")))
-			   'font-lock-keywords)))))
-
-	  ;; Case fold?
-	  (if (>= (length defaults) 3)
-	      (setq font-lock-keywords-case-fold-search (nth 2 defaults))
-	    ;; older way:
-	    ;; look for a property 'font-lock-keywords-case-fold-search on
-	    ;; the major-mode symbol.
-	    (let* ((nonexist (make-symbol ""))
-		   (value (get major-mode 'font-lock-keywords-case-fold-search
-			       nonexist)))
-	      (if (not (eq nonexist value))
-		  (setq font-lock-keywords-case-fold-search value))))
-
-	  ;; Syntactic?
-	  (if (>= (length defaults) 2)
-	      (setq font-lock-keywords-only (nth 1 defaults))
-	    ;; older way:
-	    ;; cleverly examine the syntax table.
-	    (font-lock-examine-syntax-table))
-	   
-	  ;; Syntax table?
-	  (if (nth 3 defaults)
-	      (let ((slist (nth 3 defaults)))
-		(setq font-lock-syntax-table
-		      (copy-syntax-table (syntax-table)))
-		(while slist
-		  (modify-syntax-entry (car (car slist)) (cdr (car slist))
-				       font-lock-syntax-table)
-		  (setq slist (cdr slist)))))
-
-	  ;; Syntax function?
-	  (cond (defaults
-		  (setq font-lock-beginning-of-syntax-function
-			(nth 4 defaults)))
-		(t
-		 ;; older way:
-		 ;; defaults not specified at all, so use `beginning-of-defun'.
-		 (setq font-lock-beginning-of-syntax-function
-		       'beginning-of-defun)))))
+;; Originally face attributes were specified via `font-lock-face-attributes'.
+;; Users then changed the default face attributes by setting that variable.
+;; However, we try and be back-compatible and respect its value if set except
+;; for faces where M-x customize has been used to save changes for the face.
+
+;;(when (boundp 'font-lock-face-attributes)
+;; ...
+
+;; Since we never had it, we don't need to be backwards-compatible.
+
+
+(defconst font-lock-face-list
+  '(font-lock-comment-face
+    font-lock-string-face
+    font-lock-doc-string-face
+    font-lock-keyword-face
+    font-lock-builtin-face
+    font-lock-function-name-face
+    font-lock-variable-name-face
+    font-lock-type-face
+    font-lock-constant-face
+    font-lock-preprocessor-face
+    font-lock-warning-face))
+
+;; These are our old definitions, quite different from FSF.
+;; I've temporarily substituted the FSF definitions to see if I like them.
+
+; (defface font-lock-comment-face
+;   '((((class color) (background dark)) (:foreground "gray80"))
+;     ;; blue4 is hardly different from black on windows.
+;     (((class color) (background light) (type mswindows)) (:foreground "blue"))
+;     (((class color) (background light)) (:foreground "blue4"))
+;     (((class grayscale) (background light))
+;      (:foreground "DimGray" :bold t :italic t))
+;     (((class grayscale) (background dark))
+;      (:foreground "LightGray" :bold t :italic t))
+;     (t (:bold t)))
+;   "Font Lock mode face used to highlight comments."
+;:group 'font-lock-faces)
+
+; (defface font-lock-string-face
+;   '((((class color) (background dark)) (:foreground "tan"))
+;     (((class color) (background light)) (:foreground "green4"))
+;     (((class grayscale) (background light)) (:foreground "DimGray" :italic t))
+;     (((class grayscale) (background dark)) (:foreground "LightGray" :italic t))
+;     (t (:bold t)))
+;   "Font Lock mode face used to highlight strings."
+;:group 'font-lock-faces)
+
+; (defface font-lock-doc-string-face
+;   '((((class color) (background dark)) (:foreground "light coral"))
+;     (((class color) (background light)) (:foreground "green4"))
+;     (t (:bold t)))
+;   "Font Lock mode face used to highlight documentation strings.
+; This is currently supported only in Lisp-like modes, which are those
+; with \"lisp\" or \"scheme\" in their name.  You can explicitly make
+; a mode Lisp-like by putting a non-nil `font-lock-lisp-like' property
+; on the major mode's symbol."
+;:group 'font-lock-faces)
+
+; (defface font-lock-keyword-face
+;   '((((class color) (background dark)) (:foreground "cyan"))
+;     ;; red4 is hardly different from black on windows.
+;     (((class color) (background light) (type mswindows)) (:foreground "red"))
+;     (((class color) (background light)) (:foreground "red4"))
+;     (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
+;     (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
+;     (t (:bold t)))
+;   "Font Lock mode face used to highlight keywords."
+;:group 'font-lock-faces)
+
+; (defface font-lock-builtin-face
+;   '((((class color) (background light)) (:foreground "Purple"))
+;     (((class color) (background dark)) (:foreground "Cyan"))
+;     (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
+;     (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
+;     (t (:bold t)))
+;   "Font Lock mode face used to highlight builtins."
+;:group 'font-lock-faces)
+
+; (defface font-lock-function-name-face
+;   '((((class color) (background dark)) (:foreground "aquamarine"))
+;     ;; brown4 is hardly different from black on windows.
+;     ;; I changed it to red because IMO it's pointless and ugly to
+;     ;; use a million slightly different colors for niggly syntactic
+;     ;; differences. --ben
+;     (((class color) (background light) (type mswindows)) (:foreground "red"))
+;     (((class color) (background light)) (:foreground "brown4"))
+;     (t (:bold t :underline t)))
+;   "Font Lock mode face used to highlight function names."
+;:group 'font-lock-faces)
+
+; (defface font-lock-variable-name-face
+;   '((((class color) (background dark)) (:foreground "cyan3"))
+;     (((class color) (background light)) (:foreground "magenta4"))
+;     (((class grayscale) (background light))
+;      (:foreground "Gray90" :bold t :italic t))
+;     (((class grayscale) (background dark))
+;      (:foreground "DimGray" :bold t :italic t))
+;     (t (:underline t)))
+;   "Font Lock mode face used to highlight variable names."
+;:group 'font-lock-faces)
+
+; (defface font-lock-type-face
+;   '((((class color) (background dark)) (:foreground "wheat"))
+;     (((class color) (background light)) (:foreground "steelblue"))
+;     (((class grayscale) (background light)) (:foreground "Gray90" :bold t))
+;     (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
+;     (t (:bold t)))
+;   "Font Lock mode face used to highlight types."
+;:group 'font-lock-faces)
+
+; (defface font-lock-constant-face
+;   '((((class color) (background light)) (:foreground "CadetBlue"))
+;     (((class color) (background dark)) (:foreground "Aquamarine"))
+;     (((class grayscale) (background light))
+;      (:foreground "LightGray" :bold t :underline t))
+;     (((class grayscale) (background dark))
+;      (:foreground "Gray50" :bold t :underline t))
+;     (t (:bold t :underline t)))
+;   "Font Lock mode face used to highlight constants and labels."
+;:group 'font-lock-faces)
+
+; (defface font-lock-reference-face
+;   '((((class color) (background dark)) (:foreground "cadetblue2"))
+;     (((class color) (background light)) (:foreground "red3"))
+;     (((class grayscale) (background light))
+;      (:foreground "LightGray" :bold t :underline t))
+;     (((class grayscale) (background dark))
+;      (:foreground "Gray50" :bold t :underline t)))
+;   "Font Lock mode face used to highlight references."
+;:group 'font-lock-faces)
+
+; (defface font-lock-preprocessor-face
+;   '((((class color) (background dark)) (:foreground "steelblue1"))
+;     (((class color) (background light)) (:foreground "blue3"))
+;     (t (:underline t)))
+;   "Font Lock Mode face used to highlight preprocessor conditionals."
+;:group 'font-lock-faces)
+
+; (defface font-lock-warning-face
+;   '((((class color) (background light)) (:foreground "Red" :bold t))
+;     (((class color) (background dark)) (:foreground "Pink" :bold t))
+;     (t (:inverse-video t :bold t)))
+;   "Font Lock mode face used to highlight warnings."
+;:group 'font-lock-faces)
+
+(defface font-lock-comment-face
+  '((((type tty pc) (class color) (background light)) (:foreground "red"))
+    (((type tty pc) (class color) (background dark)) (:foreground "red1"))
+    (((class grayscale) (background light))
+     (:foreground "DimGray" :bold t :italic t))
+    (((class grayscale) (background dark))
+     (:foreground "LightGray" :bold t :italic t))
+    (((class color) (background light)) (:foreground "Firebrick"))
+    (((class color) (background dark)) (:foreground "chocolate1"))
+    (t (:bold t :italic t)))
+  "Font Lock mode face used to highlight comments."
+:group 'font-lock-faces)
+
+(defface font-lock-string-face
+  '((((type tty) (class color)) (:foreground "green"))
+    (((class grayscale) (background light)) (:foreground "DimGray" :italic t))
+    (((class grayscale) (background dark)) (:foreground "LightGray" :italic t))
+    (((class color) (background light)) (:foreground "RosyBrown"))
+    (((class color) (background dark)) (:foreground "LightSalmon"))
+    (t (:italic t)))
+  "Font Lock mode face used to highlight strings."
+:group 'font-lock-faces)
+
+(defface font-lock-doc-string-face
+  '((t :inherit font-lock-string-face))
+  "Font Lock mode face used to highlight documentation strings.
+This is currently supported only in Lisp-like modes, which are those
+with \"lisp\" or \"scheme\" in their name.  You can explicitly make
+a mode Lisp-like by putting a non-nil `font-lock-lisp-like' property
+on the major mode's symbol."
+:group 'font-lock-faces)
+
+(defface font-lock-keyword-face
+  '((((type tty) (class color)) (:foreground "cyan" :weight bold))
+    (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
+    (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
+    (((class color) (background light)) (:foreground "Purple"))
+    (((class color) (background dark)) (:foreground "Cyan"))
+    (t (:bold t)))
+  "Font Lock mode face used to highlight keywords."
+:group 'font-lock-faces)
+
+(defface font-lock-builtin-face
+  '((((type tty) (class color)) (:foreground "blue" :weight light))
+    (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
+    (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
+    (((class color) (background light)) (:foreground "Orchid"))
+    (((class color) (background dark)) (:foreground "LightSteelBlue"))
+    (t (:bold t)))
+  "Font Lock mode face used to highlight builtins."
+:group 'font-lock-faces)
+
+(defface font-lock-function-name-face
+  '((((type tty) (class color)) (:foreground "blue" :weight bold))
+    (((class color) (background light)) (:foreground "Blue"))
+    (((class color) (background dark)) (:foreground "LightSkyBlue"))
+    (t (:inverse-video t :bold t)))
+  "Font Lock mode face used to highlight function names."
+:group 'font-lock-faces)
+
+(defface font-lock-variable-name-face
+  '((((type tty) (class color)) (:foreground "yellow" :weight light))
+    (((class grayscale) (background light))
+     (:foreground "Gray90" :bold t :italic t))
+    (((class grayscale) (background dark))
+     (:foreground "DimGray" :bold t :italic t))
+    (((class color) (background light)) (:foreground "DarkGoldenrod"))
+    (((class color) (background dark)) (:foreground "LightGoldenrod"))
+    (t (:bold t :italic t)))
+  "Font Lock mode face used to highlight variable names."
+:group 'font-lock-faces)
 
-    (setq font-lock-cache-position (make-marker))
-    (setq font-lock-defaults-computed t)))
+(defface font-lock-type-face
+  '((((type tty) (class color)) (:foreground "green"))
+    (((class grayscale) (background light)) (:foreground "Gray90" :bold t))
+    (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
+    (((class color) (background light)) (:foreground "ForestGreen"))
+    (((class color) (background dark)) (:foreground "PaleGreen"))
+    (t (:bold t :underline t)))
+  "Font Lock mode face used to highlight type and classes."
+:group 'font-lock-faces)
+
+(defface font-lock-constant-face
+  '((((type tty) (class color)) (:foreground "magenta"))
+    (((class grayscale) (background light))
+     (:foreground "LightGray" :bold t :underline t))
+    (((class grayscale) (background dark))
+     (:foreground "Gray50" :bold t :underline t))
+    (((class color) (background light)) (:foreground "CadetBlue"))
+    (((class color) (background dark)) (:foreground "Aquamarine"))
+    (t (:bold t :underline t)))
+  "Font Lock mode face used to highlight constants and labels."
+:group 'font-lock-faces)
+
+(defface font-lock-preprocessor-face
+  '((((class color) (background dark)) (:foreground "steelblue1"))
+    (((class color) (background light)) (:foreground "blue3"))
+    (t (:underline t)))
+  "Font Lock Mode face used to highlight preprocessor conditionals."
+:group 'font-lock-faces)
+
+(defface font-lock-warning-face
+  '((((type tty) (class color)) (:foreground "red"))
+    (((class color) (background light)) (:foreground "Red" :bold t))
+    (((class color) (background dark)) (:foreground "Pink" :bold t))
+    (t (:inverse-video t :bold t)))
+  "Font Lock mode face used to highlight warnings."
+:group 'font-lock-faces)
+
+;; Backwards-compatible crud.  XEmacs only.
+
+(defun font-lock-recompute-variables ()
+  ;; Is this a Draconian thing to do?
+  (mapc #'(lambda (buffer)
+	    (with-current-buffer buffer
+	      (font-lock-mode 0)
+	      (font-lock-set-defaults t)))
+	(buffer-list)))
+
+(defun font-lock-reset-all-faces ()
+  (dolist (face font-lock-face-list)
+    (face-spec-set face (get face 'face-defface-spec))))
+
+(defun font-lock-use-default-fonts ()
+  "Reset the font-lock faces to a default set of fonts."
+  (interactive)
+  ;; #### !!!!
+  (font-lock-reset-all-faces))
+
+(defun font-lock-use-default-colors ()
+  "Reset the font-lock faces to a default set of colors."
+  (interactive)
+  ;; #### !!!!
+  (font-lock-reset-all-faces))
+
+(defun font-lock-use-default-minimal-decoration ()
+  "Reset the font-lock patterns to a fast, minimal set of decorations."
+  (and font-lock-maximum-decoration
+       (setq font-lock-maximum-decoration nil)
+       (font-lock-recompute-variables)))
+
+(defun font-lock-use-default-maximal-decoration ()
+  "Reset the font-lock patterns to a larger set of decorations."
+  (and (not (eq t font-lock-maximum-decoration))
+       (setq font-lock-maximum-decoration t)
+       (font-lock-recompute-variables)))
+
+;;; End of Colour etc. support.
+
+;;; Menu support.
+
+;;; FSF writes:
+
+;; This section of code is commented out because Emacs does not have real menu
+;; buttons.  (We can mimic them by putting "( ) " or "(X) " at the beginning of
+;; the menu entry text, but with Xt it looks both ugly and embarrassingly
+;; amateur.)  If/When Emacs gets real menus buttons, put in menu-bar.el after
+;; the entry for "Text Properties" something like:
+
+;; We DO have real menu buttons, and all the code in this section seems to
+;; mimic the option menu.
+
+;; ...
+
+;;; End of Menu support.
+
+;;; Various regexp information shared by several modes.
+;;; Information specific to a single mode should go in its load library.
+
+;; Font Lock support for C, C++, Objective-C and Java modes will one day be in
+;; some cc-font.el (and required by cc-mode.el).  However, the below function
+;; should stay in font-lock.el, since it is used by other libraries.  sm.
+
+(defun font-lock-match-c-style-declaration-item-and-skip-to-next (limit)
+  "Match, and move over, any declaration/definition item after point.
+Matches after point, but ignores leading whitespace and `*' characters.
+Does not move further than LIMIT.
+
+The expected syntax of a declaration/definition item is `word' (preceded by
+optional whitespace and `*' characters and proceeded by optional whitespace)
+optionally followed by a `('.  Everything following the item (but belonging to
+it) is expected to by skip-able by `scan-sexps', and items are expected to be
+separated with a `,' and to be terminated with a `;'.
+
+Thus the regexp matches after point:	word (
+					^^^^ ^
+Where the match subexpressions are:	  1  2
+
+The item is delimited by (match-beginning 1) and (match-end 1).
+If (match-beginning 2) is non-nil, the item is followed by a `('.
+
+This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item."
+  (when (looking-at "[ \t*]*\\(\\sw+\\)[ \t]*\\((\\)?")
+    (save-match-data
+      (condition-case nil
+	  (save-restriction
+	    ;; Restrict to the end of line, currently guaranteed to be LIMIT.
+	    (narrow-to-region (point-min) limit)
+	    (goto-char (match-end 1))
+	    ;; Move over any item value, etc., to the next item.
+	    (while (not (looking-at "[ \t]*\\(\\(,\\)\\|;\\|$\\)"))
+	      (goto-char (or (scan-sexps (point) 1) (point-max))))
+	    (goto-char (match-end 2)))
+	(error t)))))
 
 
 ;;;;;;;;;;;;;;;;;;;;;;         keywords         ;;;;;;;;;;;;;;;;;;;;;;
@@ -1901,73 +2965,17 @@
 ;; for SYNTAX-BEGIN.  Thus the calculation of the cache is usually
 ;; faster but not infallible, so we risk mis-fontification.  --sm.
 
-(put 'c-mode 'font-lock-defaults 
-     '((c-font-lock-keywords
-	c-font-lock-keywords-1 c-font-lock-keywords-2 c-font-lock-keywords-3)
-       nil nil ((?_ . "w")) beginning-of-defun))
-(put 'c++-c-mode 'font-lock-defaults 'c-mode)
-(put 'elec-c-mode 'font-lock-defaults 'c-mode)
-
-(put 'c++-mode 'font-lock-defaults
-     '((c++-font-lock-keywords
-	c++-font-lock-keywords-1 c++-font-lock-keywords-2
-	c++-font-lock-keywords-3)
-       nil nil ((?_ . "w") (?~ . "w")) beginning-of-defun))
-
-(put 'java-mode 'font-lock-defaults 
-     '((java-font-lock-keywords
-	java-font-lock-keywords-1 java-font-lock-keywords-2
-	java-font-lock-keywords-3)
-       nil nil ((?_ . "w")) beginning-of-defun
-       (font-lock-mark-block-function . mark-defun)))
-
-(put 'lisp-mode 'font-lock-defaults
-     '((lisp-font-lock-keywords
-	lisp-font-lock-keywords-1 lisp-font-lock-keywords-2)
-       nil nil
-       ((?: . "w") (?- . "w") (?* . "w") (?+ . "w") (?. . "w") (?< . "w")
-	(?> . "w") (?= . "w") (?! . "w") (?? . "w") (?$ . "w") (?% . "w")
-	(?_ . "w") (?& . "w") (?~ . "w") (?^ . "w") (?/ . "w"))
-       beginning-of-defun))
-(put 'emacs-lisp-mode 'font-lock-defaults 'lisp-mode)
-(put 'lisp-interaction-mode 'font-lock-defaults 'lisp-mode)
-
-(put 'scheme-mode 'font-lock-defaults
-     '(scheme-font-lock-keywords
-       nil t
-       ((?: . "w") (?- . "w") (?* . "w") (?+ . "w") (?. . "w") (?< . "w")
-	(?> . "w") (?= . "w") (?! . "w") (?? . "w") (?$ . "w") (?% . "w")
-	(?_ . "w") (?& . "w") (?~ . "w") (?^ . "w") (?/ . "w"))
-       beginning-of-defun))
-(put 'inferior-scheme-mode 'font-lock-defaults 'scheme-mode)
-(put 'scheme-interaction-mode 'font-lock-defaults 'scheme-mode)
-
-(put 'tex-mode 'font-lock-defaults
-     ;; For TeX modes we could use `backward-paragraph' for the same reason.
-     '(tex-font-lock-keywords nil nil ((?$ . "\""))))
-;; the nine billion names of TeX mode...
-(put 'bibtex-mode	'font-lock-defaults 'tex-mode)
-(put 'plain-tex-mode	'font-lock-defaults 'tex-mode)
-(put 'slitex-tex-mode	'font-lock-defaults 'tex-mode)
-(put 'SliTeX-mode	'font-lock-defaults 'tex-mode)
-(put 'slitex-mode	'font-lock-defaults 'tex-mode)
-(put 'latex-tex-mode	'font-lock-defaults 'tex-mode)
-(put 'LaTex-tex-mode	'font-lock-defaults 'tex-mode)
-(put 'latex-mode        'font-lock-defaults 'tex-mode)
-(put 'LaTeX-mode        'font-lock-defaults 'tex-mode)
-(put 'japanese-LaTeX-mode 'font-lock-defaults 'tex-mode)
-(put 'japanese-SliTeX-mode 'font-lock-defaults 'tex-mode)
-(put 'FoilTeX-mode	'font-lock-defaults 'tex-mode)
-(put 'LATeX-MoDe	'font-lock-defaults 'tex-mode)
-(put 'lATEx-mODe	'font-lock-defaults 'tex-mode)
-;; ok, this is getting a bit silly ...
-(put 'eDOm-xETAl	'font-lock-defaults 'tex-mode)
-
 ;;; Various regexp information shared by several modes.
 ;;; Information specific to a single mode should go in its load library.
 
+
+;; Lisp.
+
 (defconst lisp-font-lock-keywords-1
   (list
+   ;;
+   ;; Definitions.
+   ;;
    ;; Anything not a function or type declaration is fontified as a
    ;; variable.  It would be cleaner to allow preceding whitespace, but it
    ;; would also be about five times slower.  We used to fontify unknown
@@ -1977,16 +2985,15 @@
    ;; different, which looks better.
    (list (concat
 	  "^(\\(" lisp-function-and-type-regexp
-	  ;; Former variable declarations, but woefully inadequate.
-	  ;; "\\|def\\(const\\(\\|ant\\)\\|ine-key\\(\\|-after\\)\\|"
-	  ;; "var\\|custom\\)"
-	  ;; Everything else is a variable declaration.
-	  ;; anything else is a variable
+	  ;; Former variable declarations (FSF 21.2), but woefully inadequate.
+	  ;; "\\(const\\(ant\\)?\\|custom\\|face\\|parameter\\|var\\)\\|"
+	  ;; Anything else is a variable.
 	  "\\|def\\([^ \t\n\(\)]+\\)"
-	  ;; make sure we are at end of word.
+	  ;; Make sure we are at end of word.
 	  "\\)\\>"
 	  ;; Any whitespace following and declared object.
 	  "[ \t'\(]*"
+	  ;; FSF 21.2: "\\(setf[ \t]+\\sw+)\\|\\sw+\\)?")
 	  "\\([^ \t\n\(\)]+\\)?")
 	 ;; Note about numbering:  #1 is the grouping around the whole
 	 ;; keyword.  #2 - #4 are in lisp-function-and-type-regexp.
@@ -1997,66 +3004,90 @@
 		   ((match-beginning 4) 'font-lock-type-face)
 		   (t 'font-lock-variable-name-face))
 	   nil t))
+     ;;
+     ;; Emacs Lisp autoload cookies.
+     '("^;;;###\\(autoload\\)" 1 font-lock-warning-face prepend)
    )
  "Subdued level highlighting Lisp modes.")
 
+;; Macro to break up generated regexp-opt strings for easier reading and
+;; substitution into code, if we go back to expanding the regexp-opt call
+;; manually.
+;;
+;;(setq last-kbd-macro
+;;      (read-kbd-macro "\" C-7 C-1 <right> C-r \\\\| 3*<right> \" RET"))
+
 (defconst lisp-font-lock-keywords-2
   (append lisp-font-lock-keywords-1
-   (list
-    ;;
-    ;; Control structures.  ELisp and CLisp combined.
-    ;;
-    (cons
-     (concat
-      "(\\("
-      ;; beginning of generated stuff
-      ;; to regenerate, use the regexp-opt below, then delete the outermost
-      ;; grouping, then use the macro below to break up the string.
-      ;; (regexp-opt
-      ;;   '("cond" "if" "while" "let" "let*" "prog" "progn" "prog1"
-      ;;     "prog2" "progv" "catch" "throw" "save-restriction"
-      ;;     "save-excursion" "save-window-excursion"
-      ;;     "save-current-buffer" "with-current-buffer"
-      ;;     "save-selected-window" "with-selected-window"
-      ;;     "save-selected-frame" "with-selected-frame"
-      ;;     "with-temp-file" "with-temp-buffer" "with-output-to-string"
-      ;;     "with-string-as-buffer-contents"
-      ;;     "save-match-data" "unwind-protect" "call-with-condition-handler"
-      ;;     "condition-case" "track-mouse" "autoload"
-      ;;     "eval-after-load" "eval-and-compile" "eval-when-compile"
-      ;;     "when" "unless" "do" "dolist" "dotimes" "flet" "labels"
-      ;;     "lambda" "block" "return" "return-from" "loop") t)
-      ;; (setq last-kbd-macro
-      ;;   (read-kbd-macro "\" C-6 C-9 <right> C-r \\\\| 3*<right> \" RET"))
-      "autoload\\|block\\|c\\(?:a\\(?:ll-with-condition-handler\\|tch\\)\\|"
-      "ond\\(?:ition-case\\)?\\)\\|do\\(?:list\\|times\\)?\\|"
-      "eval-\\(?:a\\(?:fter-load\\|nd-compile\\)\\|when-compile\\)\\|flet\\|"
-      "if\\|l\\(?:a\\(?:bels\\|mbda\\)\\|et\\*?\\|oop\\)\\|prog[12nv]?\\|"
-      "return\\(?:-from\\)?\\|save-\\(?:current-buffer\\|excursion\\|"
-      "match-data\\|restriction\\|selected-\\(?:frame\\|window\\)\\|"
-      "window-excursion\\)\\|t\\(?:hrow\\|rack-mouse\\)\\|un\\(?:less\\|"
-      "wind-protect\\)\\|w\\(?:h\\(?:en\\|ile\\)\\|ith-\\(?:current-buffer\\|"
-      "output-to-string\\|s\\(?:elected-\\(?:frame\\|window\\)\\|"
-      "tring-as-buffer-contents\\)\\|temp-\\(?:buffer\\|file\\)\\)\\)"
-      ;; end of generated stuff
-      "\\)\\>") 1)
-    ;;
-    ;; Feature symbols as references.
-    '("(\\(featurep\\|provide\\|require\\)\\>[ \t']*\\(\\sw+\\)?"
-      (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
-    ;;
-    ;; Words inside \\[] tend to be for `substitute-command-keys'.
-    '("\\\\\\\\\\[\\(\\sw+\\)]" 1 font-lock-reference-face prepend)
-    ;;
-    ;; Words inside `' tend to be symbol names.
-    '("`\\(\\sw\\sw+\\)'" 1 font-lock-reference-face prepend)
-    ;;
-    ;; CLisp `:' keywords as references.
-    '("\\<:\\sw+\\>" 0 font-lock-reference-face prepend)
-    ;;
-    ;; ELisp and CLisp `&' keywords as types.
-    '("\\<\\&\\(optional\\|rest\\|whole\\)\\>" . font-lock-type-face)
-    ))
+   (eval-when-compile
+     (list
+      ;;
+      ;; Control structures.  Emacs Lisp forms.
+      (cons (concat
+	     "(" (regexp-opt
+		  '("cond" "if" "while" "let" "let*"
+		    "prog" "progn" "progv" "prog1" "prog2" "prog*"
+		    "inline" "lambda" "save-restriction" "save-excursion"
+		    "save-window-excursion" "save-selected-window"
+		    "save-match-data" "save-current-buffer" "unwind-protect"
+		    "condition-case" "track-mouse"
+		    "eval-after-load" "eval-and-compile" "eval-when-compile"
+		    "eval-when"
+		    "with-current-buffer" "with-electric-help"
+		    "with-output-to-string" "with-output-to-temp-buffer"
+		    "with-temp-buffer" "with-temp-file" "with-temp-message"
+		    "with-timeout"
+		    ;; XEmacs additions:
+		    "catch" "throw" "with-selected-window"
+		    "save-selected-frame" "with-selected-frame"
+		    "with-string-as-buffer-contents"
+		    "call-with-condition-handler"
+		    "autoload"
+		    ) t)
+	     "\\>")
+	    1)
+      ;;
+      ;; Control structures.  Common Lisp forms.
+      (cons (concat
+	     "(" (regexp-opt
+		  '("when" "unless" "case" "ecase" "typecase" "etypecase"
+		    "ccase" "ctypecase" "handler-case" "handler-bind"
+		    "restart-bind" "restart-case" "in-package"
+		    "cerror" "break" "ignore-errors"
+		    "loop" "do" "do*" "dotimes" "dolist" "the" "locally"
+		    "proclaim" "declaim" "declare" "symbol-macrolet"
+		    "lexical-let" "lexical-let*" "flet" "labels" "compiler-let"
+		    "destructuring-bind" "macrolet" "tagbody" "block"
+		    "return" "return-from") t)
+	     "\\>")
+	    1)
+      ;;
+      ;; Exit/Feature symbols as constants.
+      (list (concat "(\\(catch\\|throw\\|featurep\\|provide\\|require\\)\\>"
+		    "[ \t']*\\(\\sw+\\)?")
+	    '(1 font-lock-keyword-face)
+	    '(2 font-lock-constant-face nil t))
+      ;;
+      ;; Erroneous structures.
+      '("(\\(abort\\|assert\\|error\\|signal\\)\\>" 1 font-lock-warning-face)
+      ;;
+      ;; Words inside \\[] tend to be for `substitute-command-keys'.
+      '("\\\\\\\\\\[\\(\\sw+\\)]" 1 font-lock-constant-face prepend)
+      ;;
+      ;; Words inside `' tend to be symbol names.
+      '("`\\(\\sw\\sw+\\)'" 1 font-lock-constant-face prepend)
+      ;;
+      ;; Constant values.
+      '("\\<:\\sw\\sw+\\>" 0 font-lock-builtin-face)
+      ;;
+      ;; ELisp and CLisp `&' keywords as types.
+      ;; Former XEmacs version:
+      ;; '("\\<\\&\\(optional\\|rest\\|whole\\)\\>" . font-lock-type-face)
+      '("\\&\\sw+\\>" . font-lock-type-face)
+      ;;
+      ;; CL `with-' and `do-' constructs
+      '("(\\(\\(do-\\|with-\\)\\(\\s_\\|\\w\\)*\\)" 1 font-lock-keyword-face)
+      )))
   "Gaudy level highlighting for Lisp modes.")
 
 (defvar lisp-font-lock-keywords lisp-font-lock-keywords-1
@@ -2106,56 +3137,64 @@
 ;
 ;This does a lot more highlighting.")
 
-(defvar scheme-font-lock-keywords
+(defconst scheme-font-lock-keywords-1
   (eval-when-compile
     (list
      ;;
      ;; Declarations.  Hannes Haug <hannes.haug@student.uni-tuebingen.de> says
      ;; this works for SOS, STklos, SCOOPS, Meroon and Tiny CLOS.
-     (list (concat "(\\(define\\("
+     (list (concat "(\\(define\\*?\\("
 		   ;; Function names.
-		   "\\(\\|-\\(generic\\(\\|-procedure\\)\\|method\\)\\)\\|"
+		   "\\(\\|-public\\|-method\\|-generic\\(-procedure\\)?\\)\\|"
 		   ;; Macro names, as variable names.  A bit dubious, this.
-		   "\\(-syntax\\)\\|"
+		   "\\(-syntax\\|-macro\\)\\|"
 		   ;; Class names.
-		   "\\(-class\\)"
+		   "-class"
+                   ;; Guile modules.
+                   "\\|-module"
 		   "\\)\\)\\>"
 		   ;; Any whitespace and declared object.
 		   "[ \t]*(?"
 		   "\\(\\sw+\\)?")
 	   '(1 font-lock-keyword-face)
-	   '(8 (cond ((match-beginning 3) 'font-lock-function-name-face)
-		     ((match-beginning 6) 'font-lock-variable-name-face)
-		     (t 'font-lock-type-face))
+	   '(6 (cond ((match-beginning 3) font-lock-function-name-face)
+		     ((match-beginning 5) font-lock-variable-name-face)
+		     (t font-lock-type-face))
 	       nil t))
-     ;;
-     ;; Control structures.
-;(regexp-opt '("begin" "call-with-current-continuation" "call/cc"
-;	       "call-with-input-file" "call-with-output-file" "case" "cond"
-;	       "do" "else" "for-each" "if" "lambda"
-;	       "let\\*?" "let-syntax" "letrec" "letrec-syntax"
-;	       ;; Hannes Haug <hannes.haug@student.uni-tuebingen.de> wants:
-;	       "and" "or" "delay"
-;	       ;; Stefan Monnier <stefan.monnier@epfl.ch> says don't bother:
-;	       ;;"quasiquote" "quote" "unquote" "unquote-splicing"
-;	       "map" "syntax" "syntax-rules"))
-     (cons
-      (concat "(\\("
-	      "and\\|begin\\|c\\(a\\(ll\\(-with-\\(current-continuation\\|"
-	      "input-file\\|output-file\\)\\|/cc\\)\\|se\\)\\|ond\\)\\|"
-	      "d\\(elay\\|o\\)\\|else\\|for-each\\|if\\|"
-	      "l\\(ambda\\|et\\(-syntax\\|\\*?\\|rec\\(\\|-syntax\\)\\)\\)\\|"
-	      "map\\|or\\|syntax\\(\\|-rules\\)"
-	      "\\)\\>") 1)
-     ;;
-     ;; David Fox <fox@graphics.cs.nyu.edu> for SOS/STklos class specifiers.
-     '("\\<<\\sw+>\\>" . font-lock-type-face)
-     ;;
-     ;; Scheme `:' keywords as references.
-     '("\\<:\\sw+\\>" . font-lock-reference-face)
      ))
-"Default expressions to highlight in Scheme modes.")
+  "Subdued expressions to highlight in Scheme modes.")
 
+(defconst scheme-font-lock-keywords-2
+  (append scheme-font-lock-keywords-1
+   (eval-when-compile
+     (list
+      ;;
+      ;; Control structures.
+      (cons
+       (concat
+	"(" (regexp-opt
+	     '("begin" "call-with-current-continuation" "call/cc"
+	       "call-with-input-file" "call-with-output-file" "case" "cond"
+	       "do" "else" "for-each" "if" "lambda"
+	       "let" "let*" "let-syntax" "letrec" "letrec-syntax"
+	       ;; Hannes Haug <hannes.haug@student.uni-tuebingen.de> wants:
+	       "and" "or" "delay"
+	       ;; Stefan Monnier <stefan.monnier@epfl.ch> says don't bother:
+	       ;;"quasiquote" "quote" "unquote" "unquote-splicing"
+	       "map" "syntax" "syntax-rules") t)
+	"\\>") 1)
+      ;;
+      ;; David Fox <fox@graphics.cs.nyu.edu> for SOS/STklos class specifiers.
+      '("\\<<\\sw+>\\>" . font-lock-type-face)
+      ;;
+      ;; Scheme `:' keywords as builtins.
+      '("\\<:\\sw+\\>" . font-lock-builtin-face)
+      )))
+  "Gaudy expressions to highlight in Scheme modes.")
+
+(defvar scheme-font-lock-keywords scheme-font-lock-keywords-1
+  "Default expressions to highlight in Scheme modes.")
+
 ;; The previous version, before replacing it with the FSF version.
 ;(defconst scheme-font-lock-keywords (purecopy
 ; '(("(define[ \t]+(?\\([^ \t\n\)]+\\)" 1 font-lock-function-name-face)
@@ -2164,126 +3203,173 @@
 ;   ("(\\(quote\\|unquote\\|quasiquote\\|unquote-splicing\\)[ \t\n]" . 1)
 ;   ("(\\(syntax\\|syntax-rules\\|define-syntax\\|let-syntax\\|letrec-syntax\\)[ \t\n]" . 1)))
 ;  "Expressions to highlight in Scheme buffers.")
-
-(defconst c-font-lock-keywords-1 nil
-  "Subdued level highlighting for C modes.")
 
-(defconst c-font-lock-keywords-2 nil
-  "Medium level highlighting for C modes.")
+(put 'lisp-mode 'font-lock-defaults
+     '((lisp-font-lock-keywords
+        lisp-font-lock-keywords-1 lisp-font-lock-keywords-2)
+       nil nil (("+-*/.<>=!?$%_&~^:" . "w")) beginning-of-defun
+       (font-lock-mark-block-function . mark-defun)))
+(put 'emacs-lisp-mode 'font-lock-defaults 'lisp-mode)
+(put 'lisp-interaction-mode 'font-lock-defaults 'lisp-mode)
 
-(defconst c-font-lock-keywords-3 nil
-  "Gaudy level highlighting for C modes.")
+(put 'scheme-mode 'font-lock-defaults
+     '((scheme-font-lock-keywords
+	scheme-font-lock-keywords-1 scheme-font-lock-keywords-2)
+       nil t (("+-*/.<>=!?$%_&~^:" . "w")) beginning-of-defun
+       (font-lock-mark-block-function . mark-defun)))
+(put 'inferior-scheme-mode 'font-lock-defaults 'scheme-mode)
+(put 'scheme-interaction-mode 'font-lock-defaults 'scheme-mode)
 
-(defconst xemacs-c-font-lock-keywords-2 nil
-  "Medium level highlighting for XEmacs C source code.")
+
+;;; User choices.
 
-(defconst xemacs-c-font-lock-keywords-3 nil
-  "Gaudy level highlighting for XEmacs C source code.")
+;; These provide a means to fontify types not defined by the language.  Those
+;; types might be the user's own or they might be generally accepted and used.
+;; Generally accepted types are used to provide default variable values.
+
+(define-widget 'font-lock-extra-types-widget 'radio
+  "Widget `:type' for members of the custom group `font-lock-extra-types'.
+Members should `:load' the package `font-lock' to use this widget."
+:args '((const :tag "none" nil)
+	  (repeat :tag "types" regexp)))
+
+(defcustom c-font-lock-extra-types '("FILE" "\\sw+_t" "Lisp_Object")
+  "*List of extra types to fontify in C mode.
+Each list item should be a regexp not containing word-delimiters.
+For example, a value of (\"FILE\" \"\\\\sw+_t\") means the word FILE and words
+ending in _t are treated as type names.
+
+The value of this variable is used when Font Lock mode is turned on."
+:type 'font-lock-extra-types-widget
+:group 'font-lock-extra-types)
+
+(defconst xemacs-c-font-lock-extra-types
+  '("FILE" "\\sw+_t"
+    "Ibyte" "CIbyte" "Extbyte" "UExtbyte" "WExtbyte"
+    "Ascbyte" "UAscbyte" "Rawbyte" "CRawbyte" "Binbyte" "CBinbyte"
+    "SBinbyte" "Boolbyte" "Ichar" "Raw_Ichar" "Itext" "Textcount"
+    "Bytecount" "Charcount" "Charbpos" "Bytebpos" "Membpos" "Charxpos"
+    "Bytexpos" "Memxpos" "Elemcount" "Hashcode" "EMACS_INT" "USID"
+    "face_index" "glyph_index" "Lisp_Object")
+  "Value of `c-font-lock-extra-types' appropriate for XEmacs source code.")
+
+(defcustom c++-font-lock-extra-types
+  '("\\sw+_t"
+    "\\([iof]\\|str\\)+stream\\(buf\\)?" "ios"
+    "string" "rope"
+    "list" "slist"
+    "deque" "vector" "bit_vector"
+    "set" "multiset"
+    "map" "multimap"
+    "hash\\(_\\(m\\(ap\\|ulti\\(map\\|set\\)\\)\\|set\\)\\)?"
+    "stack" "queue" "priority_queue"
+    "type_info"
+    "iterator" "const_iterator" "reverse_iterator" "const_reverse_iterator"
+    "reference" "const_reference")
+  "*List of extra types to fontify in C++ mode.
+Each list item should be a regexp not containing word-delimiters.
+For example, a value of (\"string\") means the word string is treated as a type
+name.
+
+The value of this variable is used when Font Lock mode is turned on."
+:type 'font-lock-extra-types-widget
+:group 'font-lock-extra-types)
+
+(defcustom objc-font-lock-extra-types '("Class" "BOOL" "IMP" "SEL")
+  "*List of extra types to fontify in Objective-C mode.
+Each list item should be a regexp not containing word-delimiters.
+For example, a value of (\"Class\" \"BOOL\" \"IMP\" \"SEL\") means the words
+Class, BOOL, IMP and SEL are treated as type names.
+
+The value of this variable is used when Font Lock mode is turned on."
+:type 'font-lock-extra-types-widget
+:group 'font-lock-extra-types)
+
+(defcustom java-font-lock-extra-types
+  '("[A-Z\300-\326\330-\337]\\sw*[a-z]\\sw*")
+  "*List of extra types to fontify in Java mode.
+Each list item should be a regexp not containing word-delimiters.
+For example, a value of (\"[A-Z\300-\326\330-\337]\\\\sw*[a-z]\\\\sw*\") means capitalised
+words (and words conforming to the Java id spec) are treated as type names.
+
+The value of this variable is used when Font Lock mode is turned on."
+:type 'font-lock-extra-types-widget
+:group 'font-lock-extra-types)
+
+;;; C.
 
-(defconst c++-font-lock-keywords-1 nil
-  "Subdued level highlighting for C++ modes.")
+;; [Murmur murmur murmur] Maestro, drum-roll please...  [Murmur murmur murmur.]
+;; Ahem.  [Murmur murmur murmur] Lay-dees an Gennel-men.  [Murmur murmur shhh!]
+;; I am most proud and humbly honoured today [murmur murmur cough] to present
+;; to you good people, the winner of the Second Millennium Award for The Most
+;; Hairy Language Syntax.  [Ahhh!]  All rise please.  [Shuffle shuffle
+;; shuffle.]  And a round of applause please.  For...  The C Language!  [Roar.]
+;;
+;; Thank you...  You are too kind...  It is with a feeling of great privilege
+;; and indeed emotion [sob] that I accept this award.  It has been a long hard
+;; road.  But we know our destiny.  And our future.  For we must not rest.
+;; There are more tokens to overload, more shoehorn, more methodologies.  But
+;; more is a plus!  [Ha ha ha.]  And more means plus!  [Ho ho ho.]  The future
+;; is C++!  [Ohhh!]  The Third Millennium Award...  Will be ours!  [Roar.]
 
-(defconst c++-font-lock-keywords-2 nil
-  "Medium level highlighting for C++ modes.")
+(defconst c-font-lock-keywords-1 nil
+  "Subdued level highlighting for C mode.")
 
-(defconst c++-font-lock-keywords-3 nil
-  "Gaudy level highlighting for C++ modes.")
+(defconst c-font-lock-keywords-2 nil
+  "Medium level highlighting for C mode.
+See also `c-font-lock-extra-types'.")
 
-(defun font-lock-match-c++-style-declaration-item-and-skip-to-next (limit)
-  ;; Match, and move over, any declaration/definition item after point.
-  ;; The expect syntax of an item is "word" or "word::word", possibly ending
-  ;; with optional whitespace and a "(".  Everything following the item (but
-  ;; belonging to it) is expected to by skip-able by `forward-sexp', and items
-  ;; are expected to be separated with a "," or ";".
-  (if (looking-at "[ \t*&]*\\(\\(?:\\sw\\|\\s_\\)+\\)\\(::\\(\\(?:\\sw\\|\\s_\\)+\\)\\)?[ \t]*\\((\\)?")
-      (save-match-data
-	(condition-case nil
-	    (save-restriction
-	      ;; Restrict to the end of line, currently guaranteed to be LIMIT.
-	      (narrow-to-region (point-min) limit)
-	      (goto-char (match-end 1))
-	      ;; Move over any item value, etc., to the next item.
-	      (while (not (looking-at "[ \t]*\\([,;]\\|$\\)"))
-		(goto-char (or (scan-sexps (point) 1) (point-max))))
-	      (goto-char (match-end 0)))
-	  (error t)))))
+(defconst c-font-lock-keywords-3 nil
+  "Gaudy level highlighting for C mode.
+See also `c-font-lock-extra-types'.")
 
-(let ((c-keywords
-;      ("break" "continue" "do" "else" "for" "if" "return" "switch" "while")
-       "break\\|continue\\|do\\|else\\|for\\|if\\|return\\|switch\\|while")
-      (xemacs-c-type-types
-      ;(regexp-opt '("Ibyte" "CIbyte" "Extbyte" "UExtbyte" "WExtbyte"
-      ; "Ascbyte" "UAscbyte" "Rawbyte" "CRawbyte" "Binbyte" "CBinbyte"
-      ; "SBinbyte" "Boolbyte" "Ichar" "Raw_Ichar" "Itext" "Textcount"
-      ; "Bytecount" "Charcount" "Charbpos" "Bytebpos" "Membpos" "Charxpos"
-      ; "Bytexpos" "Memxpos" "Elemcount" "Hashcode" "EMACS_INT" "USID"
-      ; "face_index" "glyph_index" "Lisp_Object"))
-       ;; see below (search for last-kbd-macro) for how to auto-generate
-       ;; what's below from what's above.
-       (concat
-	"Ascbyte\\|B\\(?:inbyte\\|oolbyte\\|yte\\(?:bpos\\|count\\|"
-	"xpos\\)\\)\\|C\\(?:Binbyte\\|Ibyte\\|Rawbyte\\|har\\(?:bpos\\|"
-	"count\\|xpos\\)\\)\\|E\\(?:MACS_INT\\|lemcount\\|xtbyte\\)\\|"
-	"Hashcode\\|I\\(?:byte\\|char\\|text\\)\\|Lisp_Object\\|"
-	"Mem\\(?:bpos\\|xpos\\)\\|Raw\\(?:_Ichar\\|byte\\)\\|SBinbyte\\|"
-	"Textcount\\|U\\(?:Ascbyte\\|Extbyte\\|SID\\)\\|WExtbyte\\|"
-	"face_index\\|glyph_index"))
-      (c-type-types
-;      ("auto" "extern" "register" "static" "typedef" "struct" "union" "enum"
-;	"signed" "unsigned" "short" "long" "int" "char" "wchar_t" "float"
-;       "double" "void" "volatile" "const")
-       ;; This regexp is (just) 6 parens deep ...
-       ;; This regexp is (just) 6 parens deep ...
-       ;; This regexp is (just) 6 parens deep ...
-       ;; repeat ad nauseum
-       (concat "auto\\|c\\(har\\|onst\\)\\|double\\|e\\(num\\|xtern\\)\\|"
-	       "float\\|int\\|long\\|register\\|"
-	       "s\\(hort\\|igned\\|t\\(atic\\|ruct\\)\\)\\|typedef\\|"
-	       "un\\(ion\\|signed\\)\\|vo\\(id\\|latile\\)\\|wchar_t"))
-      (c++-keywords
-;      ("break" "continue" "do" "else" "for" "if" "return" "switch" "while"
-;	"asm" "catch" "delete" "new" "operator" "sizeof" "this" "throw" "try"
-;       "protected" "private" "public" "const_cast" "dynamic_cast" "reinterpret_cast"
-;       "static_cast" "and" "bitor" "or" "xor" "compl" "bitand" "and_eq"
-;	"or_eq" "xor_eq" "not" "not_eq" "typeid" "false" "true")
-       (concat "a\\(nd\\(\\|_eq\\)\\|sm\\)\\|"
-	       "b\\(it\\(or\\|and\\)\\|reak\\)\\|"
-	       "c\\(atch\\|o\\(mpl\\|n\\(tinue\\|st_cast\\)\\)\\)\\|"
-	       "d\\(elete\\|o\\|ynamic_cast\\)\\|"
-	       "else\\|"
-	       "f\\(alse\\|or\\)\\|if\\|"
-	       "n\\(ew\\|ot\\(\\|_eq\\)\\)\\|"
-	       "p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|"
-	       "or\\(\\|_eq\\)\\|"
-	       "re\\(interpret_cast\\|turn\\)\\|"
-	       "s\\(izeof\\|tatic_cast\\|witch\\)\\|"
-	       "t\\(h\\(is\\|row\\)\\|r\\(ue\\|y\\)\\|ypeid\\)\\|"
-	       "xor\\(\\|_eq\\)\\|while"))
-      (c++-type-types
-;      ("auto" "extern" "register" "static" "typedef" "struct" "union" "enum"
-;	"signed" "unsigned" "short" "long" "int" "char" "float" "double"
-;	"void" "volatile" "const" "class" "inline" "friend" "bool"
-;	"virtual" "complex" "template" "explicit" "mutable" "export" "namespace"
-;       "using" "typename" "wchar_t")
-       (concat "auto\\|bool\\|c\\(har\\|lass\\|o\\(mplex\\|nst\\)\\)\\|"
-	       "double\\|"
-	       "e\\(num\\|x\\(p\\(licit\\|ort\\)\\|tern\\)\\)\\|"
-	       "f\\(loat\\|riend\\)\\|"
-	       "in\\(line\\|t\\)\\|long\\|mutable\\|namespace\\|register\\|"
-	       "s\\(hort\\|igned\\|t\\(atic\\|ruct\\)\\)\\|"
-	       "t\\(emplate\\|ype\\(def\\|name\\)\\)\\|"
-	       "u\\(\\(n\\(ion\\|signed\\)\\|sing\\)\\)\\|"
-	       "v\\(irtual\\|o\\(id\\|latile\\)\\)\\|"
-	       "wchar_t"))		; 11 ()s deep.
-      (ctoken "\\(\\sw\\|\\s_\\|[:~*&]\\)+")
-      )
+(let* ((c-keywords
+	(eval-when-compile
+	  (regexp-opt '("break" "continue" "do" "else" "for" "if" "return"
+			"switch" "while" "sizeof"
+			;; Type related, but we don't do anything special.
+			"typedef" "extern" "auto" "register" "static"
+			"volatile" "const"
+			;; Dan Nicolaescu <done@gnu.org> says this is new.
+			"restrict"))))
+       (c-type-specs
+	(eval-when-compile
+	  (regexp-opt '("enum" "struct" "union"))))
+       (c-type-specs-depth
+	(regexp-opt-depth c-type-specs))
+       (c-type-names
+	`(mapconcat 'identity
+	  (cons
+	   ,(eval-when-compile
+	      (regexp-opt
+	       '("char" "short" "int" "long" "signed" "unsigned"
+		 "float" "double" "void" "complex")))
+	   c-font-lock-extra-types)
+	  "\\|"))
+       (c-type-names-depth
+	`(regexp-opt-depth ,c-type-names))
+       (c-preprocessor-directives
+	(eval-when-compile
+	  (regexp-opt
+	   '("define"  "elif" "else" "endif" "error" "file" "if" "ifdef"
+	     "ifndef" "include" "line" "pragma" "undef"))))
+       (c-preprocessor-directives-depth
+	(regexp-opt-depth c-preprocessor-directives))
+       ;; XEmacs:
+       (ctoken "\\(\\sw\\|\\s_\\|[:~*&]\\)+"))
  (setq c-font-lock-keywords-1
   (list
    ;;
    ;; These are all anchored at the beginning of line for speed.
+   ;; Note that `c++-font-lock-keywords-1' depends on `c-font-lock-keywords-1'.
    ;;
    ;; Fontify function name definitions (GNU style; without type on line).
-   
+   ;;
+   ;; FSF 21.2 has:
+   ;'("^\\(\\sw+\\)[ \t]*(" 1 font-lock-function-name-face)
+   ;;
+   ;; We have all the following down to just before the error directives.
+
    ;; In FSF this has the simpler definition of "\\sw+" for ctoken.
    ;; I'm not sure if ours is more correct.
    ;; This is a subset of the next rule, and is slower when present. --dmoore
@@ -2311,159 +3397,275 @@
    ;; This is faster but not by much.  I don't see why not.
    ;(list (concat "^\\(" ctoken "\\)[ \t]*(") 1 'font-lock-function-name-face)
    ;;
-   ;; Added next two; they're both jolly-good fastmatch candidates so
-   ;; should be fast. --ben
+   ;; [[ Added next two; they're both jolly-good fastmatch candidates so
+   ;; should be fast. --ben ]]
    ;;
-   ;; Fontify structure names (in structure definition form).
-   (list (concat "^\\(typedef[ \t]+struct\\|struct\\|static[ \t]+struct\\)"
-      	   "[ \t]+\\(" ctoken "\\)[ \t]*\\(\{\\|$\\)")
-         2 'font-lock-function-name-face)
+   ;; Matchers for these are down below in ...-keywords-2.  Move them up
+   ;; if we want them here. --ben
    ;;
-   ;; Fontify case clauses.  This is fast because its anchored on the left.
-   '("case[ \t]+\\(\\(\\sw\\|\\s_\\)+\\)[ \t]+:". 1)
+;    ;; Fontify structure names (in structure definition form).
+;    (list (concat "^\\(typedef[ \t]+struct\\|struct\\|static[ \t]+struct\\)"
+;       	   "[ \t]+\\(" ctoken "\\)[ \t]*\\(\{\\|$\\)")
+;          2 'font-lock-function-name-face)
+;    ;;
+;    ;; Fontify case clauses.  This is fast because it's anchored on the left.
+;    '("case[ \t]+\\(\\(\\sw\\|\\s_\\)+\\)[ \t]+:". 1)
+;    ;;
+;    '("\\<\\(default\\):". 1)
+;    ;;
+   ;; Fontify error directives.
+   '("^#[ \t]*error[ \t]+\\(.+\\)" 1 font-lock-warning-face prepend)
    ;;
-   '("\\<\\(default\\):". 1)
    ;; Fontify filenames in #include <...> preprocessor directives as strings.
-   '("^#[ \t]*include[ \t]+\\(<[^>\"\n]+>\\)" 1 font-lock-string-face)
+   '("^#[ \t]*\\(import\\|include\\)[ \t]*\\(<[^>\"\n]*>?\\)"
+     2 font-lock-string-face)
    ;;
    ;; Fontify function macro names.
+;FSF'("^#[ \t]*define[ \t]+\\(\\sw+\\)(" 1 font-lock-function-name-face)
+   ;; #### Is this really any different?
    '("^#[ \t]*define[ \t]+\\(\\(\\sw+\\)(\\)" 2 font-lock-function-name-face)
-   ;;
-   ;; Fontify symbol names in #if ... defined preprocessor directives.
-   '("^#[ \t]*if\\>"
-     ("\\<\\(defined\\)\\>[ \t]*(?\\(\\sw+\\)?" nil nil
-      (1 font-lock-preprocessor-face) (2 font-lock-variable-name-face nil t)))
    ;;
-   ;; Fontify symbol names in #elif ... defined preprocessor directives.
-   '("^#[ \t]*elif\\>"
+   ;; Fontify symbol names in #elif or #if ... defined preprocessor directives.
+   '("^#[ \t]*\\(elif\\|if\\)\\>"
      ("\\<\\(defined\\)\\>[ \t]*(?\\(\\sw+\\)?" nil nil
+;FSF  (1 font-lock-builtin-face) (2 font-lock-variable-name-face nil t)))
       (1 font-lock-preprocessor-face) (2 font-lock-variable-name-face nil t)))
    ;;
    ;; Fontify otherwise as symbol names, and the preprocessor directive names.
-   '("^\\(#[ \t]*[a-z]+\\)\\>[ \t]*\\(\\sw+\\)?"
-     (1 font-lock-preprocessor-face) (2 font-lock-variable-name-face nil t))
-   ))
+   (list
+;FSF(concat "^#[ \t]*\\(" c-preprocessor-directives
+    (concat "^\\(#[ \t]*" c-preprocessor-directives
+	    "\\)\\>[ \t!]*\\(\\sw+\\)?")
+;FSF'(1 font-lock-builtin-face)
+    '(1 font-lock-preprocessor-face)
+    (list (+ 2 c-preprocessor-directives-depth)
+	  'font-lock-variable-name-face nil t))))
 
- (let ((cflk2-part-1
-	(list
-	 ;;
-	 ;; Simple regexps for speed.
-	 ;;
-	 ;; Fontify all type specifiers.
-	 (cons (concat "\\<\\(" c-type-types "\\)\\>") 'font-lock-type-face)))
-       (cflk2-part-2
-	(list
-	 ;; Fontify all builtin keywords (except case, default and goto;
-	 ;; see below).
-	 (cons (concat "\\<\\(" c-keywords "\\)\\>") 'font-lock-keyword-face)
-	 ;;
-	 ;; Fontify case/goto keywords and targets, and case default/goto tags.
-	 '("\\<\\(case\\|goto\\)\\>[ \t]*\\([^ \t\n:;]+\\)?"
-	   (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
-	 '("^[ \t]*\\(\\sw+\\)[ \t]*:" 1 font-lock-reference-face)))
-       (cflk3-part-1
-	;;
-	;; More complicated regexps for more complete highlighting for
-	;; types.  We still have to fontify type specifiers individually,
-	;; as C is so hairy.
-	(list
-	 ;;
-	 ;; Fontify all storage classes and type specifiers, plus their items.
-	 (list (concat "\\<\\(" c-type-types "\\)\\>"
-		       "\\([ \t*&]+\\sw+\\>\\)*")
-	       ;; Fontify each declaration item.
-	       '(font-lock-match-c++-style-declaration-item-and-skip-to-next
-		 ;; Start with point after all type specifiers.
-		 (goto-char (or (match-beginning 8) (match-end 1)))
-		 ;; Finish with point after first type specifier.
-		 (goto-char (match-end 1))
-		 ;; Fontify as a variable or function name.
-		 (1 (if (match-beginning 4)
-			font-lock-function-name-face
-		      font-lock-variable-name-face))))))
-       (cflk3-part-2
-	(list
-	 ;;
-	 ;; Fontify structures, or typedef names, plus their items.
-	 '("\\(}\\)[ \t*]*\\sw"
-	   (font-lock-match-c++-style-declaration-item-and-skip-to-next
-	    (goto-char (match-end 1)) nil
-	    (1 (if (match-beginning 4)
-		   font-lock-function-name-face
-		 font-lock-variable-name-face))))
-	 ;;
-	 ;; Fontify anything at beginning of line as a declaration or
-	 ;; definition.
-	 '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*"
-	   (1 font-lock-type-face)
-	   (font-lock-match-c++-style-declaration-item-and-skip-to-next
-	    (goto-char (or (match-beginning 2) (match-end 1))) nil
-	    (1 (if (match-beginning 4)
-		   font-lock-function-name-face
-		 font-lock-variable-name-face))))))
-       (xcflk2-part-1
-	(list
-	 ;; Fontify all simple type specifiers used in XEmacs code.
-	 (cons (concat "\\<\\(" xemacs-c-type-types "\\)\\>")
-	       'font-lock-type-face)))
-       (xcflk3-part-1
-	;;
-	;; More complicated regexps for more complete highlighting for
-	;; types.  We still have to fontify type specifiers individually,
-	;; as C is so hairy.
-	(list
-	 ;;
-	 ;; Fontify all storage classes and type specifiers, plus their items.
-	 (list (concat "\\<\\(" xemacs-c-type-types "\\)\\>"
-		       "\\([ \t*&]+\\sw+\\>\\)*")
-	       ;; Fontify each declaration item.
-	       '(font-lock-match-c++-style-declaration-item-and-skip-to-next
-		 ;; Start with point after all type specifiers.
-		 (goto-char (or (match-beginning 8) (match-end 1)))
-		 ;; Finish with point after first type specifier.
-		 (goto-char (match-end 1))
-		 ;; Fontify as a variable or function name.
-		 (1 (if (match-beginning 4)
-			font-lock-function-name-face
-		      font-lock-variable-name-face)))))))
-
-   (setq c-font-lock-keywords-2
-	 (append c-font-lock-keywords-1
-		 cflk2-part-1
-		 cflk2-part-2))
-
-   (setq c-font-lock-keywords-3
-	 (append c-font-lock-keywords-2
-		 cflk3-part-1
-		 cflk3-part-2))
-
-   (setq xemacs-c-font-lock-keywords-2
-	 (append c-font-lock-keywords-1
-		 cflk2-part-1
-		 xcflk2-part-1
-		 cflk2-part-2))
-
-   (setq xemacs-c-font-lock-keywords-3
-	 (append xemacs-c-font-lock-keywords-2
-		 cflk3-part-1
-		 xcflk3-part-1
-		 cflk3-part-2)))
+ (setq c-font-lock-keywords-2
+  (append c-font-lock-keywords-1
+   (list
+    ;;
+    ;; Simple regexps for speed.
+    ;;
+    ;; Fontify all type names.
+    `(eval .
+      (cons (concat "\\<\\(" ,c-type-names "\\)\\>") 'font-lock-type-face))
+    ;;
+    ;; Fontify all builtin keywords (except case, default and goto; see below).
+    (concat "\\<\\(" c-keywords "\\|" c-type-specs "\\)\\>")
+    ;;
+    ;; Fontify case/goto keywords and targets, and case default/goto tags.
+    '("\\<\\(case\\|goto\\)\\>"
+      (1 font-lock-keyword-face)
+      ("\\(-[0-9]+\\|\\sw+\\)"
+       ;; Return limit of search.
+       (save-excursion (skip-chars-forward "^:\n") (point))
+       nil
+       (1 font-lock-constant-face nil t)))
+    ;; Anders Lindgren <andersl@andersl.com> points out that it is quicker to
+    ;; use MATCH-ANCHORED to effectively anchor the regexp on the left.
+    ;; This must come after the one for keywords and targets.
+    '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$"
+	   (beginning-of-line) (end-of-line)
+	   (1 font-lock-constant-face)))
+    )))
+
+ (setq c-font-lock-keywords-3
+  (append c-font-lock-keywords-2
+   ;;
+   ;; More complicated regexps for more complete highlighting for types.
+   ;; We still have to fontify type specifiers individually, as C is so hairy.
+   (list
+    ;;
+    ;; Fontify all storage types, plus their items.
+    `(eval .
+      (list (concat "\\<\\(" ,c-type-names "\\)\\>"
+		    "\\([ \t*&]+\\sw+\\>\\)*")
+	    ;; Fontify each declaration item.
+	    (list 'font-lock-match-c-style-declaration-item-and-skip-to-next
+		  ;; Start with point after all type specifiers.
+		  (list 'goto-char (list 'or
+					 (list 'match-beginning
+					       (+ ,c-type-names-depth 2))
+					 '(match-end 1)))
+		  ;; Finish with point after first type specifier.
+		  '(goto-char (match-end 1))
+		  ;; Fontify as a variable or function name.
+		  '(1 (if (match-beginning 2)
+			  font-lock-function-name-face
+			font-lock-variable-name-face)))))
+    ;;
+    ;; Fontify all storage specs and types, plus their items.
+    `(eval .
+      (list (concat "\\<\\(" ,c-type-specs "\\)\\>"
+		    "[ \t]*\\(\\sw+\\)?")
+	  (list 1 'font-lock-keyword-face)
+	  (list ,(+ c-type-specs-depth 2) 'font-lock-type-face nil t)
+	  (list 'font-lock-match-c-style-declaration-item-and-skip-to-next
+		  nil 
+		  ;; Finish with point after the variable name if
+		  ;; there is one.
+		  `(if (match-end 2) 
+		       (goto-char (match-end 2)))
+		  ;; Fontify as a variable or function name.
+		  '(1 (if (match-beginning 2)
+			  font-lock-function-name-face
+			font-lock-variable-name-face) nil t))))
+    ;;
+    ;; Fontify structures, or typedef names, plus their items.
+    '("\\(}\\)[ \t*]*\\sw"
+      (font-lock-match-c-style-declaration-item-and-skip-to-next
+       (goto-char (match-end 1)) nil
+       (1 font-lock-type-face)))
+    ;;
+    ;; Fontify anything at beginning of line as a declaration or definition.
+    '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*"
+      (1 font-lock-type-face)
+      (font-lock-match-c-style-declaration-item-and-skip-to-next
+       (goto-char (or (match-beginning 2) (match-end 1))) nil
+       (1 (if (match-beginning 2)
+	      font-lock-function-name-face
+	    font-lock-variable-name-face))))
+    )))
+ )
+
+(defvar c-font-lock-keywords c-font-lock-keywords-1
+  "Default expressions to highlight in C mode.
+See also `c-font-lock-extra-types'.")
+
+;;; C++.
+
+(defconst c++-font-lock-keywords-1 nil
+  "Subdued level highlighting for C++ modes.")
+
+(defconst c++-font-lock-keywords-2 nil
+  "Medium level highlighting for C++ modes.")
+
+(defconst c++-font-lock-keywords-3 nil
+  "Gaudy level highlighting for C++ modes.")
+
+(defun font-lock-match-c++-style-declaration-item-and-skip-to-next (limit)
+  ;; Match, and move over, any declaration/definition item after point.
+  ;; The expect syntax of an item is "word" or "word::word", possibly ending
+  ;; with optional whitespace and a "(".  Everything following the item (but
+  ;; belonging to it) is expected to by skip-able by `forward-sexp', and items
+  ;; are expected to be separated with a "," or ";".
+  (if (looking-at "[ \t*&]*\\(\\(?:\\sw\\|\\s_\\)+\\)\\(::\\(\\(?:\\sw\\|\\s_\\)+\\)\\)?[ \t]*\\((\\)?")
+      (save-match-data
+	(condition-case nil
+	    (save-restriction
+	      ;; Restrict to the end of line, currently guaranteed to be LIMIT.
+	      (narrow-to-region (point-min) limit)
+	      (goto-char (match-end 1))
+	      ;; Move over any item value, etc., to the next item.
+	      (while (not (looking-at "[ \t]*\\([,;]\\|$\\)"))
+		(goto-char (or (scan-sexps (point) 1) (point-max))))
+	      (goto-char (match-end 0)))
+	  (error t)))))
+
+(defun font-lock-match-c++-structor-declaration (limit)
+  ;; Match C++ constructors and destructors inside class declarations.
+  (let ((res nil)
+	(regexp (concat "^\\s-+\\(\\(virtual\\|explicit\\)\\s-+\\)*~?\\(\\<"
+			(mapconcat 'identity
+				   c++-font-lock-extra-types "\\|")
+			"\\>\\)\\s-*("
+			;; Don't match function pointer declarations, e.g.:
+			;;    Foo (*fptr)();
+			"\\s-*[^*( \t]")))
+    (while (progn (setq res (re-search-forward regexp limit t))
+		  (and res
+		       (save-excursion
+			 (beginning-of-line)
+			 (save-match-data
+			   (not (vectorp (c-at-toplevel-p))))))))
+    res))
+
+(let* ((c++-keywords
+	(eval-when-compile
+	  (regexp-opt
+	   '("break" "continue" "do" "else" "for" "if" "return" "switch"
+	     "while" "asm" "catch" "delete" "new" "sizeof" "this" "throw" "try"
+	     "typeid"
+	     ;; XEmacs:
+	     "false" "true"
+	     ;; Branko Cibej <branko.cibej@hermes.si> says this is new.
+	     "export"
+	     ;; Mark Mitchell <mmitchell@usa.net> says these are new.
+	     "mutable" "explicit"
+	     ;; Alain Picard <ap@abelard.apana.org.au> suggests treating these
+	     ;; as keywords not types.
+	     "typedef" "template"
+	     "extern" "auto" "register" "const" "volatile" "static"
+	     "inline" "friend" "virtual"
+	     ;; Standard C++ operator names.
+	     "and" "and_eq" "bitand" "bitor" "compl" "not" "not_eq"
+	     "or" "or_eq" "xor" "xor_eq"))))
+       (c++-operators
+	(eval-when-compile
+	  (regexp-opt
+	   ;; Taken from Stroustrup, minus keywords otherwise fontified.
+	   '("+" "-" "*" "/" "%" "^" "&" "|" "~" "!" "=" "<" ">" "+=" "-="
+	     "*=" "/=" "%=" "^=" "&=" "|=" "<<" ">>" ">>=" "<<=" "==" "!="
+	     "<=" ">=" "&&" "||" "++" "--" "->*" "," "->" "[]" "()"))))
+       (c++-type-specs
+	(eval-when-compile
+	  (regexp-opt
+	   '("class" "public" "private" "protected" "typename"
+	     "struct" "union" "enum" "namespace" "using"
+	     ;; Eric Hopper <hopper@omnifarious.mn.org> says these are new.
+	     "static_cast" "dynamic_cast" "const_cast" "reinterpret_cast"
+	     ;; XEmacs:
+	     "wchar_t"
+	     ) t)))
+       (c++-type-specs-depth
+	(regexp-opt-depth c++-type-specs))
+       (c++-type-names
+	`(mapconcat 'identity
+	  (cons
+	   ,(eval-when-compile
+	      (regexp-opt
+	       '("signed" "unsigned" "short" "long"
+		 "int" "char" "float" "double" "void"
+		 "bool" "complex")))
+	   c++-font-lock-extra-types)
+	  "\\|"))
+       (c++-type-names-depth `(regexp-opt-depth ,c++-type-names))
+       ;;
+       ;; A brave attempt to match templates following a type and/or match
+       ;; class membership.  See and sync the above function
+       ;; `font-lock-match-c++-style-declaration-item-and-skip-to-next'.
+       (c++-type-suffix (concat "\\([ \t]*<\\([^>\n]+\\)[ \t*&]*>\\)?"
+				"\\([ \t]*::[ \t*~]*\\(\\sw+\\)\\)*"))
+       (c++-type-suffix-depth (regexp-opt-depth c++-type-suffix))
+       ;; If the string is a type, it may be followed by the cruft above.
+       (c++-type-spec (concat "\\(\\sw+\\)\\>" c++-type-suffix))
+       ;FSF 21.2 (unused) (c++-type-spec-depth (regexp-opt-depth c++-type-spec))
+       ;;
+       ;; Parenthesis depth of user-defined types not forgetting their cruft.
+       (c++-type-depth `(regexp-opt-depth
+			 (concat ,c++-type-names ,c++-type-suffix)))
+       )
 
  (setq c++-font-lock-keywords-1
   (append
    ;;
    ;; The list `c-font-lock-keywords-1' less that for function names.
-   ;; the simple function form regexp has been removed. --dmoore
-   ;;(cdr c-font-lock-keywords-1)
+;FSF(cdr c-font-lock-keywords-1)
+   ;; XEmacs: the simple function form regexp has been removed. --dmoore
    c-font-lock-keywords-1
    ;;
-   ;; Fontify function name definitions, possibly incorporating class name.
    (list
-    '("^\\(\\sw+\\)\\(::\\(\\sw+\\)\\)?[ \t]*("
-      (1 (if (match-beginning 2)
-	     font-lock-type-face
-	   font-lock-function-name-face))
-      (3 (if (match-beginning 2) font-lock-function-name-face) nil t))
+    ;;
+    ;; Fontify function name definitions, possibly incorporating class names.
+    (list (concat "^" c++-type-spec "[ \t]*(")
+	  '(1 (if (or (match-beginning 2) (match-beginning 4))
+		  font-lock-type-face
+		font-lock-function-name-face))
+	  '(3 font-lock-type-face nil t)
+;FSF	  '(5 font-lock-function-name-face nil t))
+	  '(5 (if (or (match-beginning 2) (match-beginning 4))
+		  font-lock-function-name-face) nil t))
     )))
 
  (setq c++-font-lock-keywords-2
@@ -2471,19 +3673,40 @@
    (list
     ;;
     ;; The list `c-font-lock-keywords-2' for C++ plus operator overloading.
-    (cons (concat "\\<\\(" c++-type-types "\\)\\>") 'font-lock-type-face)
+    `(eval .
+      (cons (concat "\\<\\(" ,c++-type-names "\\)\\>")
+	    'font-lock-type-face))
     ;;
-    ;; Fontify operator function name overloading.
-    '("\\<\\(operator\\)\\>[ \t]*\\([][)(><!=+-][][)(><!=+-]?\\)?"
-      (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
+    ;; Fontify operator overloading.
+    (list (concat "\\<\\(operator\\)\\>[ \t]*\\(" c++-operators "\\)?")
+	  '(1 font-lock-keyword-face)
+	  '(2 font-lock-builtin-face nil t))
     ;;
     ;; Fontify case/goto keywords and targets, and case default/goto tags.
-    '("\\<\\(case\\|goto\\)\\>[ \t]*\\([^ \t\n:;]+\\)?"
-      (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
-    '("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-reference-face)
+    '("\\<\\(case\\|goto\\)\\>"
+      (1 font-lock-keyword-face)
+      ("\\(-[0-9]+\\|\\sw+\\)[ \t]*\\(::\\)?"
+       ;; Return limit of search.
+       (save-excursion
+	 (while (progn
+		  (skip-chars-forward "^:\n")
+		  (looking-at "::"))
+	   (forward-char 2))
+	 (point))
+       nil
+       (1 (if (match-beginning 2)
+	      font-lock-type-face
+	    font-lock-constant-face) nil t)))
+    ;; This must come after the one for keywords and targets.
+    '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:\\($\\|[^:]\\)"
+	   (beginning-of-line) (end-of-line)
+	   (1 font-lock-constant-face)))
     ;;
     ;; Fontify other builtin keywords.
-    (cons (concat "\\<\\(" c++-keywords "\\)\\>") 'font-lock-keyword-face)
+    (concat "\\<\\(" c++-keywords "\\|" c++-type-specs "\\)\\>")
+    ;;
+    ;; Eric Hopper <hopper@omnifarious.mn.org> says `true' and `false' are new.
+    '("\\<\\(false\\|true\\)\\>" . font-lock-constant-face)
     )))
 
  (setq c++-font-lock-keywords-3
@@ -2493,49 +3716,248 @@
    (list
     ;;
     ;; Fontify all storage classes and type specifiers, plus their items.
-    (list (concat "\\<\\(" c++-type-types "\\)\\>"
-		  "\\([ \t*&]+\\sw+\\>\\)*")
-	  ;; Fontify each declaration item.
+    `(eval .
+      (list (concat "\\<\\(" ,c++-type-names "\\)\\>" ,c++-type-suffix
+		    "\\([ \t*&]+" ,c++-type-spec "\\)*")
+	    ;; The name of any template type.
+	    (list (+ ,c++-type-names-depth 3) 'font-lock-type-face nil t)
+	    ;; Fontify each declaration item.
+	    (list 'font-lock-match-c++-style-declaration-item-and-skip-to-next
+		  ;; Start with point after all type specifiers.
+		  (list 'goto-char (list 'or (list 'match-beginning
+						   (+ ,c++-type-depth 2))
+					 '(match-end 1)))
+		  ;; Finish with point after first type specifier.
+		  '(goto-char (match-end 1))
+		  ;; Fontify as a variable or function name.
+		  '(1 (cond ((or (match-beginning 2) (match-beginning 4))
+			     font-lock-type-face)
+			    ((and (match-beginning 6) (c-at-toplevel-p))
+			     font-lock-function-name-face)
+			    (t
+			     font-lock-variable-name-face)))
+		  '(3 font-lock-type-face nil t)
+		  '(5 (if (match-beginning 6)
+			  font-lock-function-name-face
+			font-lock-variable-name-face) nil t))))
+    ;;
+    ;; Fontify all storage specs and types, plus their items.
+    `(eval .
+      (list (concat "\\<" ,c++-type-specs "\\>" ,c++-type-suffix
+		    "[ \t]*\\(" ,c++-type-spec "\\)?")
+	    ;; The name of any template type.
+	    (list ,(+ c++-type-specs-depth 2) 'font-lock-type-face nil t)
+	    ;; The name of any type.
+	    (list (+ ,c++-type-specs-depth ,c++-type-suffix-depth 2)
+		  'font-lock-type-face nil t)
+	    ;; Fontify each declaration item.
+	    (list 'font-lock-match-c++-style-declaration-item-and-skip-to-next
+		  ;; Start with point after all type specifiers.
+		  nil
+		  ;; Finish with point after first type specifier.
+		  nil
+		  ;; Fontify as a variable or function name.
+		  '(1 (cond ((or (match-beginning 2) (match-beginning 4))
+			     font-lock-type-face)
+			    ((and (match-beginning 6) (c-at-toplevel-p))
+			     font-lock-function-name-face)
+			    (t
+			     font-lock-variable-name-face)))
+		  '(3 font-lock-type-face nil t)
+		  '(5 (if (match-beginning 6)
+			  font-lock-function-name-face
+			font-lock-variable-name-face) nil t))
+	    ))
+    ;;
+    ;; Fontify structures, or typedef names, plus their items.
+    '("\\(}\\)[ \t*]*\\sw"
+      (font-lock-match-c++-style-declaration-item-and-skip-to-next
+       (goto-char (match-end 1)) nil
+       (1 font-lock-type-face)))
+    ;;
+    ;; Fontify anything at beginning of line as a declaration or definition.
+    (list (concat "^\\(" c++-type-spec "[ \t*&]*\\)+")
 	  '(font-lock-match-c++-style-declaration-item-and-skip-to-next
-	    ;; Start with point after all type specifiers.
-	    (goto-char (or (match-beginning 13) (match-end 1)))
-	    ;; Finish with point after first type specifier.
+	    (goto-char (match-beginning 1))
 	    (goto-char (match-end 1))
-	    ;; Fontify as a variable or function name.
-	    (1 (cond ((match-beginning 2) 'font-lock-type-face)
-		     ((match-beginning 4) 'font-lock-function-name-face)
-		     (t 'font-lock-variable-name-face)))
-	    (3 (if (match-beginning 4)
-		   'font-lock-function-name-face
-		 'font-lock-variable-name-face) nil t)))
+	    (1 (cond ((or (match-beginning 2) (match-beginning 4))
+		      font-lock-type-face)
+		     ((match-beginning 6) font-lock-function-name-face)
+		     (t font-lock-variable-name-face)))
+	    (3 font-lock-type-face nil t)
+	    (5 (if (match-beginning 6)
+		   font-lock-function-name-face
+		 font-lock-variable-name-face) nil t)))
+    ;;
+    ;; Fontify constructors and destructors inside class declarations.
+    '(font-lock-match-c++-structor-declaration
+      (3 font-lock-function-name-face t))
+    )))
+ )
+
+(defvar c++-font-lock-keywords c++-font-lock-keywords-1
+  "Default expressions to highlight in C++ mode.
+See also `c++-font-lock-extra-types'.")
+
+;;; Objective-C.
+
+(defconst objc-font-lock-keywords-1 nil
+  "Subdued level highlighting for Objective-C mode.")
+
+(defconst objc-font-lock-keywords-2 nil
+  "Medium level highlighting for Objective-C mode.
+See also `objc-font-lock-extra-types'.")
+
+(defconst objc-font-lock-keywords-3 nil
+  "Gaudy level highlighting for Objective-C mode.
+See also `objc-font-lock-extra-types'.")
+
+;; Regexps written with help from Stephen Peters <speters@us.oracle.com> and
+;; Jacques Duthen Prestataire <duthen@cegelec-red.fr>.
+(let* ((objc-keywords
+	(eval-when-compile
+	  (regexp-opt '("break" "continue" "do" "else" "for" "if" "return"
+			"switch" "while" "sizeof" "self" "super"
+			"typedef" "auto" "extern" "static"
+			"volatile" "const"))))
+       (objc-type-specs
+	(eval-when-compile
+	  (regexp-opt
+	   '("register" "struct" "union" "enum"
+	     "oneway" "in" "out" "inout" "bycopy" "byref") t)))
+       (objc-type-specs-depth
+	(regexp-opt-depth objc-type-specs))
+       (objc-type-names
+	`(mapconcat 'identity
+	  (cons
+	   ,(eval-when-compile
+	      (regexp-opt
+	       '("signed" "unsigned" "short" "long"
+		 "int" "char" "float" "double" "void"
+		 "id")))
+	   objc-font-lock-extra-types)
+	  "\\|"))
+       (objc-type-names-depth
+	`(regexp-opt-depth ,objc-type-names))
+       )
+ (setq objc-font-lock-keywords-1
+  (append
+   ;;
+   ;; The list `c-font-lock-keywords-1' less that for function names.
+   (cdr c-font-lock-keywords-1)
+   (list
+    ;;
+    ;; Fontify compiler directives.
+    '("@\\(\\sw+\\)\\>"
+      (1 font-lock-keyword-face)
+      ("\\=[ \t:<,]*\\(\\sw+\\)" nil nil
+       (1 font-lock-type-face)))
+    ;;
+    ;; Fontify method names and arguments.  Oh Lordy!
+    ;; First, on the same line as the function declaration.
+    '("^[+-][ \t]*\\(PRIVATE\\>\\)?[ \t]*\\(([^)\n]+)\\)?[ \t]*\\(\\sw+\\)"
+      (1 font-lock-keyword-face nil t)
+      (3 font-lock-function-name-face)
+      ("\\=[ \t]*\\(\\sw+\\)?:[ \t]*\\(([^)\n]+)\\)?[ \t]*\\(\\sw+\\)"
+       nil nil
+       (1 font-lock-function-name-face nil t)
+       (3 font-lock-variable-name-face)))
+    ;; Second, on lines following the function declaration.
+    '(":" ("^[ \t]*\\(\\sw+\\)?:[ \t]*\\(([^)\n]+)\\)?[ \t]*\\(\\sw+\\)"
+	   (beginning-of-line) (end-of-line)
+	   (1 font-lock-function-name-face nil t)
+	   (3 font-lock-variable-name-face)))
+    )))
+
+ (setq objc-font-lock-keywords-2
+  (append objc-font-lock-keywords-1
+   (list
+    ;;
+    ;; Simple regexps for speed.
+    ;;
+    ;; Fontify all type specifiers.
+    `(eval .
+      (cons (concat "\\<\\(" ,objc-type-names "\\)\\>")
+	    'font-lock-type-face))
+    ;;
+    ;; Fontify all builtin keywords (except case, default and goto; see below).
+    (concat "\\<\\(" objc-keywords "\\|" objc-type-specs "\\)\\>")
+    ;;
+    ;; Fontify case/goto keywords and targets, and case default/goto tags.
+    '("\\<\\(case\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?"
+      (1 font-lock-keyword-face) (2 font-lock-constant-face nil t))
+    ;; Fontify tags iff sole statement on line, otherwise we detect selectors.
+    ;; This must come after the one for keywords and targets.
+    '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$"
+	   (beginning-of-line) (end-of-line)
+	   (1 font-lock-constant-face)))
+    ;;
+    ;; Fontify null object pointers.
+    '("\\<[Nn]il\\>" . font-lock-constant-face)
+    )))
+
+ (setq objc-font-lock-keywords-3
+  (append objc-font-lock-keywords-2
+   ;;
+   ;; More complicated regexps for more complete highlighting for types.
+   ;; We still have to fontify type specifiers individually, as C is so hairy.
+   (list
+    ;;
+    ;; Fontify all storage classes and type specifiers, plus their items.
+    `(eval .
+      (list (concat "\\<\\(" ,objc-type-names "\\)\\>"
+		    "\\([ \t*&]+\\sw+\\>\\)*")
+	    ;; Fontify each declaration item.
+	    (list 'font-lock-match-c-style-declaration-item-and-skip-to-next
+		  ;; Start with point after all type specifiers.
+		  (list 'goto-char
+			(list 'or (list 'match-beginning
+					(+ ,objc-type-names-depth 2))
+			      '(match-end 1)))
+		  ;; Finish with point after first type specifier.
+		  '(goto-char (match-end 1))
+		  ;; Fontify as a variable or function name.
+		  '(1 (if (match-beginning 2)
+			  font-lock-function-name-face
+			font-lock-variable-name-face)))))
+    ;;
+    ;; Fontify all storage specs and types, plus their items.
+    `(eval .
+      (list (concat "\\<\\(" ,objc-type-specs "[ \t]*\\)+\\>"
+		    "[ \t]*\\(\\sw+\\)?")
+	    ;; The name of any type.
+	    (list ,(+ objc-type-specs-depth 2) 'font-lock-type-face nil t)
+	    ;; Fontify each declaration item.
+	    (list 'font-lock-match-c++-style-declaration-item-and-skip-to-next
+		  nil nil
+		  ;; Fontify as a variable or function name.
+		  '(1 (if (match-beginning 2)
+			  font-lock-function-name-face
+			font-lock-variable-name-face)))
+	    ))
     ;;
     ;; Fontify structures, or typedef names, plus their items.
     '("\\(}\\)[ \t*]*\\sw"
-      (font-lock-match-c++-style-declaration-item-and-skip-to-next
+      (font-lock-match-c-style-declaration-item-and-skip-to-next
        (goto-char (match-end 1)) nil
-       (1 (if (match-beginning 4)
-	      font-lock-function-name-face
-	    font-lock-variable-name-face))))
+       (1 font-lock-type-face)))
     ;;
     ;; Fontify anything at beginning of line as a declaration or definition.
     '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*"
       (1 font-lock-type-face)
-      (font-lock-match-c++-style-declaration-item-and-skip-to-next
+      (font-lock-match-c-style-declaration-item-and-skip-to-next
        (goto-char (or (match-beginning 2) (match-end 1))) nil
-       (1 (cond ((match-beginning 2) 'font-lock-type-face)
-		((match-beginning 4) 'font-lock-function-name-face)
-		(t 'font-lock-variable-name-face)))
-       (3 (if (match-beginning 4)
-	      'font-lock-function-name-face
-	    'font-lock-variable-name-face) nil t)))
+       (1 (if (match-beginning 2)
+	      font-lock-function-name-face
+	    font-lock-variable-name-face))))
     )))
  )
 
-(defvar c-font-lock-keywords c-font-lock-keywords-1
-  "Default expressions to highlight in C mode.")
+(defvar objc-font-lock-keywords objc-font-lock-keywords-1
+  "Default expressions to highlight in Objective-C mode.
+See also `objc-font-lock-extra-types'.")
 
-(defvar c++-font-lock-keywords c++-font-lock-keywords-1
-  "Default expressions to highlight in C++ mode.")
+;; END SYNCHED WITH FSF 21.2.
 
 ;;; Java.
 
@@ -2823,6 +4245,212 @@
 	     (goto-char (match-end 2)))   ; non-nil
 	 (error t))))))
 
+
+;;; FSF version of Java (21.2):
+
+; ;;; Java.
+
+; (defconst java-font-lock-keywords-1 nil
+;   "Subdued level highlighting for Java mode.")
+
+; (defconst java-font-lock-keywords-2 nil
+;   "Medium level highlighting for Java mode.
+; See also `java-font-lock-extra-types'.")
+
+; (defconst java-font-lock-keywords-3 nil
+;   "Gaudy level highlighting for Java mode.
+; See also `java-font-lock-extra-types'.")
+
+; ;; Regexps written with help from Fred White <fwhite@bbn.com>,
+; ;; Anders Lindgren <andersl@andersl.com> and Carl Manning <caroma@ai.mit.edu>.
+; (let* ((java-keywords
+; 	(eval-when-compile
+; 	  (regexp-opt
+; 	   '("catch" "do" "else" "super" "this" "finally" "for" "if"
+; 	     ;; Anders Lindgren <andersl@andersl.com> says these have gone.
+; 	     ;; "cast" "byvalue" "future" "generic" "operator" "var"
+; 	     ;; "inner" "outer" "rest"
+; 	     "implements" "extends" "throws" "instanceof" "new"
+; 	     "interface" "return" "switch" "throw" "try" "while"))))
+;        ;;
+;        ;; Classes immediately followed by an object name.
+;        (java-type-names
+; 	`(mapconcat 'identity
+; 	  (cons
+; 	   ,(eval-when-compile
+; 	      (regexp-opt '("boolean" "char" "byte" "short" "int" "long"
+; 			    "float" "double" "void")))
+; 	   java-font-lock-extra-types)
+; 	  "\\|"))
+;        (java-type-names-depth `(regexp-opt-depth ,java-type-names))
+;        ;;
+;        ;; These are eventually followed by an object name.
+;        (java-type-specs
+; 	(eval-when-compile
+; 	  (regexp-opt
+; 	   '("abstract" "const" "final" "synchronized" "transient" "static"
+; 	     ;; Anders Lindgren <andersl@andersl.com> says this has gone.
+; 	     ;; "threadsafe"
+; 	     "volatile" "public" "private" "protected" "native"
+; 	     ;; Carl Manning <caroma@ai.mit.edu> says this is new.
+; 	     "strictfp"))))
+;        )
+;  (setq java-font-lock-keywords-1
+;   (list
+;    ;;
+;    ;; Fontify class names.
+;    '("\\<\\(class\\)\\>[ \t]*\\(\\sw+\\)?"
+;      (1 font-lock-keyword-face) (2 font-lock-type-face nil t))
+;    ;;
+;    ;; Fontify package names in import directives.
+;    '("\\<\\(import\\|package\\)\\>[ \t]*\\(\\sw+\\)?"
+;      (1 font-lock-keyword-face)
+;      (2 font-lock-constant-face nil t)
+;      ("\\=\\.\\(\\*\\|\\sw+\\)" nil nil
+;       (1 font-lock-constant-face nil t)))
+;    ))
+
+;  (setq java-font-lock-keywords-2
+;   (append java-font-lock-keywords-1
+;    (list
+;     ;;
+;     ;; Fontify class names.
+;     `(eval .
+;       (cons (concat "\\<\\(" ,java-type-names "\\)\\>[^.]")
+; 	    '(1 font-lock-type-face)))
+;     ;;
+;     ;; Fontify all builtin keywords (except below).
+;     (concat "\\<\\(" java-keywords "\\|" java-type-specs "\\)\\>")
+;     ;;
+;     ;; Fontify keywords and targets, and case default/goto tags.
+;     (list "\\<\\(break\\|case\\|continue\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?"
+; 	  '(1 font-lock-keyword-face) '(2 font-lock-constant-face nil t))
+;     ;; This must come after the one for keywords and targets.
+;     '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$"
+; 	   (beginning-of-line) (end-of-line)
+; 	   (1 font-lock-constant-face)))
+;     ;;
+;     ;; Fontify all constants.
+;     '("\\<\\(false\\|null\\|true\\)\\>" . font-lock-constant-face)
+;     ;;
+;     ;; Javadoc tags within comments.
+;     (list
+;      (concat "@\\("
+; 	     "author\\|deprecated\\|exception"
+; 	     "\\|link\\|return\\|see\\|serial\\|serialData\\|serialField"
+; 	     "\\|since\\|throws"
+; 	     "\\|version"
+; 	     "\\)\\>")
+;      '(1 font-lock-constant-face prepend))
+;     '("@\\(param\\)\\>[ \t]*\\(\\sw+\\)?"
+;       (1 font-lock-constant-face prepend)
+;       (2 font-lock-variable-name-face prepend t))
+;     '("@\\(exception\\|throws\\)\\>[ \t]*\\(\\S-+\\)?"
+;       (1 font-lock-constant-face prepend)
+;       (2 font-lock-type-face prepend t))
+;     )))
+
+;  (setq java-font-lock-keywords-3
+;   (append java-font-lock-keywords-2
+;    ;;
+;    ;; More complicated regexps for more complete highlighting for types.
+;    ;; We still have to fontify type specifiers individually, as Java is hairy.
+;    (list
+;     ;;
+;     ;; Fontify random types immediately followed by an item or items.
+;     `(eval .
+;       (list (concat "\\<\\(" ,java-type-names "\\)\\>"
+; 		    "\\([ \t]*\\[[ \t]*\\]\\)*"
+; 		    "\\([ \t]*\\sw\\)")
+; 	    ;; Fontify each declaration item.
+; 	    (list 'font-lock-match-c-style-declaration-item-and-skip-to-next
+; 		  ;; Start and finish with point after the type specifier.
+; 		  (list 'goto-char (list 'match-beginning
+; 					 (+ ,java-type-names-depth 3)))
+; 		  (list 'goto-char (list 'match-beginning
+; 					 (+ ,java-type-names-depth 3)))
+; 		  ;; Fontify as a variable or function name.
+; 		  '(1 (if (match-beginning 2)
+; 			  font-lock-function-name-face
+; 			font-lock-variable-name-face)))))
+;     ;;
+;     ;; Fontify those that are eventually followed by an item or items.
+;     (list (concat "\\<\\(" java-type-specs "\\)\\>"
+; 		  "\\([ \t]+\\sw+\\>"
+; 		  "\\([ \t]*\\[[ \t]*\\]\\)*"
+; 		  "\\)*")
+; 	  ;; Fontify each declaration item.
+; 	  '(font-lock-match-c-style-declaration-item-and-skip-to-next
+; 	    ;; Start with point after all type specifiers.
+; 	    (goto-char (or (match-beginning 5) (match-end 1)))
+; 	    ;; Finish with point after first type specifier.
+; 	    (goto-char (match-end 1))
+; 	    ;; Fontify as a variable or function name.
+; 	    (1 (if (match-beginning 2)
+; 		   font-lock-function-name-face
+; 		 font-lock-variable-name-face))))
+;     )))
+;  )
+
+; (defvar java-font-lock-keywords java-font-lock-keywords-1
+;   "Default expressions to highlight in Java mode.
+; See also `java-font-lock-extra-types'.")
+
+
+;; BEGIN SYNCHED WITH FSF 21.2.
+
+(put 'c-mode 'font-lock-defaults 
+     '((c-font-lock-keywords c-font-lock-keywords-1
+        c-font-lock-keywords-2 c-font-lock-keywords-3)
+       nil nil ((?_ . "w")) beginning-of-defun
+       (font-lock-mark-block-function . mark-defun)))
+(put 'c++-c-mode 'font-lock-defaults 'c-mode)
+(put 'elec-c-mode 'font-lock-defaults 'c-mode)
+
+(put 'c++-mode 'font-lock-defaults
+     '((c++-font-lock-keywords c++-font-lock-keywords-1
+        c++-font-lock-keywords-2 c++-font-lock-keywords-3)
+;FSF   nil nil ((?_ . "w")) beginning-of-defun
+       nil nil (("_~" . "w")) beginning-of-defun
+       (font-lock-mark-block-function . mark-defun)))
+
+(put 'obj-c-mode 'font-lock-defaults
+     '((objc-font-lock-keywords objc-font-lock-keywords-1
+        objc-font-lock-keywords-2 objc-font-lock-keywords-3)
+       nil nil ((?_ . "w") (?$ . "w")) nil
+       (font-lock-mark-block-function . mark-defun)))
+
+(put 'java-mode 'font-lock-defaults 
+     '((java-font-lock-keywords java-font-lock-keywords-1
+        java-font-lock-keywords-2 java-font-lock-keywords-3)
+       nil nil ((?_ . "w") (?$ . "w")) nil
+       (font-lock-mark-block-function . mark-defun)))
+
+;; END SYNCHED WITH FSF 21.2.
+
+
+;; TeX
+
+(put 'tex-mode 'font-lock-defaults
+     ;; For TeX modes we could use `backward-paragraph' for the same reason.
+     '(tex-font-lock-keywords nil nil ((?$ . "\""))))
+;; the nine billion names of TeX mode...
+(put 'bibtex-mode	'font-lock-defaults 'tex-mode)
+(put 'plain-tex-mode	'font-lock-defaults 'tex-mode)
+(put 'slitex-tex-mode	'font-lock-defaults 'tex-mode)
+(put 'SliTeX-mode	'font-lock-defaults 'tex-mode)
+(put 'slitex-mode	'font-lock-defaults 'tex-mode)
+(put 'latex-tex-mode	'font-lock-defaults 'tex-mode)
+(put 'LaTex-tex-mode	'font-lock-defaults 'tex-mode)
+(put 'latex-mode        'font-lock-defaults 'tex-mode)
+(put 'LaTeX-mode        'font-lock-defaults 'tex-mode)
+(put 'japanese-LaTeX-mode 'font-lock-defaults 'tex-mode)
+(put 'japanese-SliTeX-mode 'font-lock-defaults 'tex-mode)
+(put 'FoilTeX-mode	'font-lock-defaults 'tex-mode)
+(put 'LATeX-MoDe	'font-lock-defaults 'tex-mode)
+(put 'lATEx-mODe	'font-lock-defaults 'tex-mode)
+;; ok, this is getting a bit silly ...
+(put 'eDOm-xETAl	'font-lock-defaults 'tex-mode)
 
 (defvar tex-font-lock-keywords
 ;  ;; Regexps updated with help from Ulrik Dickow <dickow@nbi.dk>.
@@ -2855,6 +4483,9 @@
      3 (if (match-beginning 2) 'bold 'italic) keep))
   "Default expressions to highlight in TeX modes.")
 
+
+;; Shell modes.
+
 (defconst ksh-font-lock-keywords 
   (list
    '("\\(^\\|[^\$\\\]\\)#.*" . font-lock-comment-face)
@@ -2874,15 +4505,12 @@
   "Additional expressions to highlight in sh-mode.")
 
 
-;; Install ourselves:
-
-(add-hook 'find-file-hooks 'font-lock-set-defaults t)
-
-;;;###autoload
-(add-minor-mode 'font-lock-mode 'font-lock-mode-line-string)
-
 ;; Provide ourselves:
 
 (provide 'font-lock)
+
+;; FSF 21.2:
+;(when (eq font-lock-support-mode 'jit-lock-mode)
+;  (require 'jit-lock))
 
 ;;; font-lock.el ends here
