(U+9B32): Use `->denotational' and `->subsumptive'.
[chise/xemacs-chise.git.1] / lisp / font-lock.el
1 ;;; font-lock.el --- decorating source files with fonts/colors based on syntax
2
3 ;; Copyright (C) 1992-1995, 1997 Free Software Foundation, Inc.
4 ;; Copyright (C) 1995 Amdahl Corporation.
5 ;; Copyright (C) 1996, 2000, 2001 Ben Wing.
6
7 ;; Author: Jamie Zawinski <jwz@jwz.org>, for the LISPM Preservation Society.
8 ;; Minimally merged with FSF 19.34 by Barry Warsaw <bwarsaw@python.org>
9 ;; Then (partially) synched with FSF 19.30, leading to:
10 ;; Next Author: RMS
11 ;; Next Author: Simon Marshall <simon@gnu.ai.mit.edu>
12 ;; Latest XEmacs Author: Ben Wing
13 ;; Maintainer: XEmacs Development Team
14 ;; Keywords: languages, faces
15
16 ;; This file is part of XEmacs.
17
18 ;; XEmacs is free software; you can redistribute it and/or modify it
19 ;; under the terms of the GNU General Public License as published by
20 ;; the Free Software Foundation; either version 2, or (at your option)
21 ;; any later version.
22
23 ;; XEmacs is distributed in the hope that it will be useful, but
24 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
25 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
26 ;; General Public License for more details.
27
28 ;; You should have received a copy of the GNU General Public License
29 ;; along with XEmacs; see the file COPYING.  If not, write to the 
30 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
31 ;; Boston, MA 02111-1307, USA.
32
33 ;;; Synched up with: FSF 19.30 except for the code to initialize the faces.
34
35 ;;; Commentary:
36
37 ;; Font-lock-mode is a minor mode that causes your comments to be
38 ;; displayed in one face, strings in another, reserved words in another,
39 ;; documentation strings in another, and so on.
40 ;;
41 ;; Comments will be displayed in `font-lock-comment-face'.
42 ;; Strings will be displayed in `font-lock-string-face'.
43 ;; Doc strings will be displayed in `font-lock-doc-string-face'.
44 ;; Function and variable names (in their defining forms) will be
45 ;;  displayed in `font-lock-function-name-face'.
46 ;; Reserved words will be displayed in `font-lock-keyword-face'.
47 ;;
48 ;; Don't let the name fool you: you can highlight things using different
49 ;; colors or background stipples instead of fonts, though that is not the
50 ;; default.  See the variables `font-lock-use-colors' and
51 ;; `font-lock-use-fonts' for broad control over this, or see the
52 ;; documentation on faces and how to change their attributes for
53 ;; fine-grained control.
54 ;;
55 ;; To make the text you type be fontified, use M-x font-lock-mode.  When
56 ;; this minor mode is on, the fonts of the current line will be updated
57 ;; with every insertion or deletion.
58 ;;
59 ;; By default, font-lock will automatically put newly loaded files
60 ;; into font-lock-mode if it knows about the file's mode.  See the
61 ;; variables `font-lock-auto-fontify', `font-lock-mode-enable-list',
62 ;; and `font-lock-mode-disable-list' for control over this.
63 ;;
64 ;; The `font-lock-keywords' variable defines other patterns to highlight.
65 ;; The default font-lock-mode-hook sets it to the value of the variables
66 ;; lisp-font-lock-keywords, c-font-lock-keywords, etc, as appropriate.
67 ;; The easiest way to change the highlighting patterns is to change the
68 ;; values of c-font-lock-keywords and related variables.  See the doc
69 ;; string of the variable `font-lock-keywords' for the appropriate syntax.
70 ;;
71 ;; The default value for `lisp-font-lock-keywords' is the value of the variable
72 ;; `lisp-font-lock-keywords-1'.  You may like `lisp-font-lock-keywords-2' 
73 ;; better; it highlights many more words, but is slower and makes your buffers
74 ;; be very visually noisy.
75 ;;
76 ;; The same is true of `c-font-lock-keywords-1' and `c-font-lock-keywords-2';
77 ;; the former is subdued, the latter is loud.
78 ;;
79 ;; You can make font-lock default to the gaudier variety of keyword
80 ;; highlighting by setting the variable `font-lock-maximum-decoration'
81 ;; before loading font-lock, or by calling the functions
82 ;; `font-lock-use-default-maximal-decoration' or
83 ;; `font-lock-use-default-minimal-decoration'.
84 ;;
85 ;; On a Sparc10, the initial fontification takes about 6 seconds for a typical
86 ;; 140k file of C code, using the default configuration.  The actual speed
87 ;; depends heavily on the type of code in the file, and how many non-syntactic
88 ;; patterns match; for example, Xlib.h takes 23 seconds for 101k, because many
89 ;; patterns match in it.  You can speed this up substantially by removing some
90 ;; of the patterns that are highlighted by default.  Fontifying lisp code is
91 ;; significantly faster, because lisp has a more regular syntax than C, so the
92 ;; regular expressions don't have to be as complicated.
93 ;;
94 ;; It's called font-lock-mode here because on the Lispms it was called
95 ;; "Electric Font Lock Mode."  It was called that because there was an older
96 ;; mode called "Electric Caps Lock Mode" which had the function of causing all
97 ;; of your source code to be in upper case except for strings and comments,
98 ;; without you having to blip the caps lock key by hand all the time (thus the
99 ;; "electric", as in `electric-c-brace'.)
100
101 ;; See also the related packages `fast-lock' and `lazy-lock'.  Both
102 ;; attempt to speed up the initial fontification.  `fast-lock' saves
103 ;; the fontification info when you exit Emacs and reloads it next time
104 ;; you load the file, so that the file doesn't have to be fontified
105 ;; again.  `lazy-lock' does "lazy" fontification -- i.e. it only
106 ;; fontifies the text as it becomes visible rather than fontifying
107 ;; the whole file when it's first loaded in.
108
109 ;; Further comments from the FSF:
110
111 ;; Nasty regexps of the form "bar\\(\\|lo\\)\\|f\\(oo\\|u\\(\\|bar\\)\\)\\|lo"
112 ;; are made thusly: (regexp-opt '("foo" "fu" "fubar" "bar" "barlo" "lo")) for
113 ;; efficiency.
114
115 ;; What is fontification for?  You might say, "It's to make my code look nice."
116 ;; I think it should be for adding information in the form of cues.  These cues
117 ;; should provide you with enough information to both (a) distinguish between
118 ;; different items, and (b) identify the item meanings, without having to read
119 ;; the items and think about it.  Therefore, fontification allows you to think
120 ;; less about, say, the structure of code, and more about, say, why the code
121 ;; doesn't work.  Or maybe it allows you to think less and drift off to sleep.
122 ;;
123 ;; So, here are my opinions/advice/guidelines:
124 ;; 
125 ;; - Use the same face for the same conceptual object, across all modes.
126 ;;   i.e., (b) above, all modes that have items that can be thought of as, say,
127 ;;   keywords, should be highlighted with the same face, etc.
128 ;; - Keep the faces distinct from each other as far as possible.
129 ;;   i.e., (a) above.
130 ;; - Make the face attributes fit the concept as far as possible.
131 ;;   i.e., function names might be a bold color such as blue, comments might
132 ;;   be a bright color such as red, character strings might be brown, because,
133 ;;   err, strings are brown (that was not the reason, please believe me).
134 ;; - Don't use a non-nil OVERRIDE unless you have a good reason.
135 ;;   Only use OVERRIDE for special things that are easy to define, such as the
136 ;;   way `...' quotes are treated in strings and comments in Emacs Lisp mode.
137 ;;   Don't use it to, say, highlight keywords in commented out code or strings.
138 ;; - Err, that's it.
139
140 \f
141 ;;; Code:
142
143 (require 'fontl-hooks)
144
145 ;;;;;;;;;;;;;;;;;;;;;;      user variables       ;;;;;;;;;;;;;;;;;;;;;;
146
147 (defgroup font-lock nil
148   "Decorate source files with fonts/colors based on syntax.
149 Font-lock-mode is a minor mode that causes your comments to be
150 displayed in one face, strings in another, reserved words in another,
151 documentation strings in another, and so on.
152
153 Comments will be displayed in `font-lock-comment-face'.
154 Strings will be displayed in `font-lock-string-face'.
155 Doc strings will be displayed in `font-lock-doc-string-face'.
156 Function and variable names (in their defining forms) will be displayed
157  in `font-lock-function-name-face'.
158 Reserved words will be displayed in `font-lock-keyword-face'.
159 Preprocessor conditionals will be displayed in `font-lock-preprocessor-face'."
160   :group 'languages)
161
162 (defgroup font-lock-faces nil
163   "Faces used by the font-lock package."
164   :group 'font-lock
165   :group 'faces)
166
167
168 (defcustom font-lock-verbose t
169   "*If non-nil, means show status messages when fontifying.
170 See also `font-lock-message-threshold'."
171   :type 'boolean
172   :group 'font-lock)
173
174 (defcustom font-lock-message-threshold 6000
175   "*Minimum size of region being fontified for status messages to appear.
176
177 The size is measured in characters.  This affects `font-lock-fontify-region'
178 but not `font-lock-fontify-buffer'. (In other words, when you first visit
179 a file and it gets fontified, you will see status messages no matter what
180 size the file is.  However, if you do something else like paste a
181 chunk of text, you will see status messages only if the changed region is
182 large enough.)
183
184 Note that setting `font-lock-verbose' to nil disables the status
185 messages entirely."
186   :type 'integer
187   :group 'font-lock)
188
189 ;;;###autoload
190 (defcustom font-lock-auto-fontify t
191   "*Whether font-lock should automatically fontify files as they're loaded.
192 This will only happen if font-lock has fontifying keywords for the major
193 mode of the file.  You can get finer-grained control over auto-fontification
194 by using this variable in combination with `font-lock-mode-enable-list' or
195 `font-lock-mode-disable-list'."
196   :type 'boolean
197   :group 'font-lock)
198
199 ;;;###autoload
200 (defcustom font-lock-mode-enable-list nil
201   "*List of modes to auto-fontify, if `font-lock-auto-fontify' is nil."
202   :type '(repeat (symbol :tag "Mode"))
203   :group 'font-lock)
204
205 ;;;###autoload
206 (defcustom font-lock-mode-disable-list nil
207   "*List of modes not to auto-fontify, if `font-lock-auto-fontify' is t."
208   :type '(repeat (symbol :tag "Mode"))
209   :group 'font-lock)
210
211 ;;;###autoload
212 (defcustom font-lock-use-colors '(color)
213   "*Specification for when Font Lock will set up color defaults.
214 Normally this should be '(color), meaning that Font Lock will set up
215 color defaults that are only used on color displays.  Set this to nil
216 if you don't want Font Lock to set up color defaults at all.  This
217 should be one of
218
219 -- a list of valid tags, meaning that the color defaults will be used
220    when all of the tags apply. (e.g. '(color x))
221 -- a list whose first element is 'or and whose remaining elements are
222    lists of valid tags, meaning that the defaults will be used when
223    any of the tag lists apply.
224 -- nil, meaning that the defaults should not be set up at all.
225
226 \(If you specify face values in your init file, they will override any
227 that Font Lock specifies, regardless of whether you specify the face
228 values before or after loading Font Lock.)
229
230 See also `font-lock-use-fonts'.  If you want more control over the faces
231 used for fontification, see the documentation of `font-lock-mode' for
232 how to do it."
233   ;; Hard to do right.
234   :type 'sexp
235   :group 'font-lock)
236
237 ;;;###autoload
238 (defcustom font-lock-use-fonts '(or (mono) (grayscale))
239   "*Specification for when Font Lock will set up non-color defaults.
240
241 Normally this should be '(or (mono) (grayscale)), meaning that Font
242 Lock will set up non-color defaults that are only used on either mono
243 or grayscale displays.  Set this to nil if you don't want Font Lock to
244 set up non-color defaults at all.  This should be one of
245
246 -- a list of valid tags, meaning that the non-color defaults will be used
247    when all of the tags apply. (e.g. '(grayscale x))
248 -- a list whose first element is 'or and whose remaining elements are
249    lists of valid tags, meaning that the defaults will be used when
250    any of the tag lists apply.
251 -- nil, meaning that the defaults should not be set up at all.
252
253 \(If you specify face values in your init file, they will override any
254 that Font Lock specifies, regardless of whether you specify the face
255 values before or after loading Font Lock.)
256
257 See also `font-lock-use-colors'.  If you want more control over the faces
258 used for fontification, see the documentation of `font-lock-mode' for
259 how to do it."
260   :type 'sexp
261   :group 'font-lock)
262
263 ;;;###autoload
264 (defcustom font-lock-maximum-decoration t
265   "*If non-nil, the maximum decoration level for fontifying.
266 If nil, use the minimum decoration (equivalent to level 0).
267 If t, use the maximum decoration available.
268 If a number, use that level of decoration (or if not available the maximum).
269 If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL),
270 where MAJOR-MODE is a symbol or t (meaning the default).  For example:
271  ((c++-mode . 2) (c-mode . t) (t . 1))
272 means use level 2 decoration for buffers in `c++-mode', the maximum decoration
273 available for buffers in `c-mode', and level 1 decoration otherwise."
274   :type '(choice (const :tag "default" nil)
275                  (const :tag "maximum" t)
276                  (integer :tag "level" 1)
277                  (repeat :menu-tag "mode specific" :tag "mode specific"
278                          :value ((t . t))
279                          (cons :tag "Instance"
280                                (radio :tag "Mode"
281                                       (const :tag "all" t)
282                                       (symbol :tag "name"))
283                                (radio :tag "Decoration"
284                                       (const :tag "default" nil)
285                                       (const :tag "maximum" t)
286                                       (integer :tag "level" 1)))))
287   :group 'font-lock)
288
289 ;;;###autoload
290 (define-obsolete-variable-alias 'font-lock-use-maximal-decoration
291   'font-lock-maximum-decoration)
292
293 ;;;###autoload
294 (defcustom font-lock-maximum-size (* 250 1024)
295   "*If non-nil, the maximum size for buffers for fontifying.
296 Only buffers less than this can be fontified when Font Lock mode is turned on.
297 If nil, means size is irrelevant.
298 If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE),
299 where MAJOR-MODE is a symbol or t (meaning the default).  For example:
300  ((c++-mode . 256000) (c-mode . 256000) (rmail-mode . 1048576))
301 means that the maximum size is 250K for buffers in `c++-mode' or `c-mode', one
302 megabyte for buffers in `rmail-mode', and size is irrelevant otherwise."
303   :type '(choice (const :tag "none" nil)
304                  (integer :tag "size")
305                  (repeat :menu-tag "mode specific" :tag "mode specific"
306                          :value ((t . nil))
307                          (cons :tag "Instance"
308                                (radio :tag "Mode"
309                                       (const :tag "all" t)
310                                       (symbol :tag "name"))
311                                (radio :tag "Size"
312                                       (const :tag "none" nil)
313                                       (integer :tag "size")))))
314   :group 'font-lock)
315
316 ;;;###autoload
317 (defcustom font-lock-fontify-string-delimiters nil
318   "*If non-nil, apply font-lock-string-face to string delimiters as well as
319 string text when fontifying."
320   :type 'boolean
321   :group 'font-lock)
322 \f
323 ;; Fontification variables:
324
325 ;;;###autoload
326 (defvar font-lock-keywords nil
327   "A list defining the keywords for `font-lock-mode' to highlight.
328
329  FONT-LOCK-KEYWORDS := List of FONT-LOCK-FORM's.
330
331  FONT-LOCK-FORM     :== MATCHER
332                       | (MATCHER . MATCH)
333                       | (MATCHER . FACE-FORM)
334                       | (MATCHER . HIGHLIGHT)
335                       | (MATCHER HIGHLIGHT ...)
336                       | (eval . FORM)
337
338  MATCHER            :== A string containing a regexp.
339                       | A variable containing a regexp to search for.
340                       | A function to call to make the search.
341                         It is called with one arg, the limit of the search,
342                         and should leave MATCH results in the XEmacs global
343                         match data.
344
345  MATCH              :== An integer match subexpression number from MATCHER.
346
347  FACE-FORM           :== The symbol naming a defined face.
348                       | Expression whos value is the face name to use.  If you
349                         want FACE-FORM to be a symbol that evaluates to a face,
350                         use a form like \"(progn sym)\".
351
352  HIGHLIGHT          :== MATCH-HIGHLIGHT
353                       | MATCH-ANCHORED
354
355  FORM               :== Expression returning a FONT-LOCK-FORM, evaluated when
356                         the FONT-LOCK-FORM is first used in a buffer.  This
357                         feature can be used to provide a FONT-LOCK-FORM that
358                         can only be generated when Font Lock mode is actually
359                         turned on.
360
361  MATCH-HIGHLIGHT    :== (MATCH FACE-FORM OVERRIDE LAXMATCH)
362
363  OVERRIDE           :== t        - overwrite existing fontification
364                       | 'keep    - only parts not already fontified are
365                                    highlighted.
366                       | 'prepend - merge faces, this fontification has
367                                    precedence over existing
368                       | 'append  - merge faces, existing fontification has
369                                    precedence over
370                                    this face.
371
372  LAXMATCH           :== If non-nil, no error is signalled if there is no MATCH
373                         in MATCHER.
374
375  MATCH-ANCHORED     :== (ANCHOR-MATCHER PRE-MATCH-FORM \\
376                                           POST-MATCH-FORM MATCH-HIGHLIGHT ...)
377
378  ANCHOR-MATCHER     :== Like a MATCHER, except that the limit of the search
379                         defaults to the end of the line after PRE-MATCH-FORM
380                         is evaluated.  However, if PRE-MATCH-FORM returns a
381                         position greater than the end of the line, that
382                         position is used as the limit of the search.  It is
383                         generally a bad idea to return a position greater than
384                         the end of the line, i.e., cause the ANCHOR-MATCHER
385                         search to span lines.
386
387  PRE-MATCH-FORM     :== Evaluated before the ANCHOR-MATCHER is used, therefore
388                         can be used to initialize before, ANCHOR-MATCHER is
389                         used.  Typically, PRE-MATCH-FORM is used to move to
390                         some position relative to the original MATCHER, before
391                         starting with the ANCHOR-MATCHER.
392
393  POST-MATCH-FORM    :== Like PRE-MATCH-FORM, but used to clean up after the
394                         ANCHOR-MATCHER.  It might be used to move, before
395                         resuming with MATCH-ANCHORED's parent's MATCHER.
396
397 For example, an element of the first form highlights (if not already highlighted):
398
399   \"\\\\\\=<foo\\\\\\=>\"                    Discrete occurrences of \"foo\" in the value
400                                  of the variable `font-lock-keyword-face'.
401
402   (\"fu\\\\(bar\\\\)\" . 1)            Substring \"bar\" within all occurrences of
403                                  \"fubar\" in the value of
404                                  `font-lock-keyword-face'.
405
406   (\"fubar\" . fubar-face)         Occurrences of \"fubar\" in the value of
407                                  `fubar-face'.
408
409   (\"foo\\\\|bar\" 0 foo-bar-face t) Occurrences of either \"foo\" or \"bar\" in the
410                                  value of `foo-bar-face', even if already
411                                  highlighted.
412
413   (fubar-match 1 fubar-face)     The first subexpression within all
414                                  occurrences of whatever the function
415                                  `fubar-match' finds and matches in the value
416                                  of `fubar-face'.
417
418   (\"\\\\\\=<anchor\\\\\\=>\" (0 anchor-face) (\"\\\\\\=<item\\\\\\=>\" nil nil (0 item-face)))
419    -------------- ---------------  ------------ --- --- -------------
420        |            |               |            |   |          |
421    MATCHER          |         ANCHOR-MATCHER     |   +------+ MATCH-HIGHLIGHT
422              MATCH-HIGHLIGHT                 PRE-MATCH-FORM |
423                                                            POST-MATCH-FORM
424
425   Discrete occurrences of \"anchor\" in the value of `anchor-face', and
426   subsequent discrete occurrences of \"item\" (on the same line) in the value
427   of `item-face'.  (Here PRE-MATCH-FORM and POST-MATCH-FORM are nil.
428   Therefore \"item\" is initially searched for starting from the end of the
429   match of \"anchor\", and searching for subsequent instance of \"anchor\"
430   resumes from where searching for \"item\" concluded.)
431
432 For highlighting single items, typically only MATCH-HIGHLIGHT is required.
433 However, if an item or (typically) several items are to be highlighted
434 following the instance of another item (the anchor) then MATCH-ANCHORED may be
435 required.
436
437 These regular expressions should not match text which spans lines.  While
438 \\[font-lock-fontify-buffer] handles multi-line patterns correctly, updating when you
439 edit the buffer does not, since it considers text one line at a time.
440
441 Be very careful composing regexps for this list; the wrong pattern can
442 dramatically slow things down!
443 ")
444 ;;;###autoload
445 (make-variable-buffer-local 'font-lock-keywords)
446
447 ;;;###autoload
448 (defvar font-lock-syntactic-keywords nil
449   "A list of the syntactic keywords to highlight.
450 Can be the list or the name of a function or variable whose value is the list.
451 See `font-lock-keywords' for a description of the form of this list;
452 the differences are listed below.  MATCH-HIGHLIGHT should be of the form:
453
454  (MATCH SYNTAX OVERRIDE LAXMATCH)
455
456 where SYNTAX can be of the form (SYNTAX-CODE . MATCHING-CHAR), the name of a
457 syntax table, or an expression whose value is such a form or a syntax table.
458 OVERRIDE cannot be `prepend' or `append'.
459
460 For example, an element of the form highlights syntactically:
461
462  (\"\\\\$\\\\(#\\\\)\" 1 (1 . nil))
463
464  a hash character when following a dollar character, with a SYNTAX-CODE of
465  1 (meaning punctuation syntax).  Assuming that the buffer syntax table does
466  specify hash characters to have comment start syntax, the element will only
467  highlight hash characters that do not follow dollar characters as comments
468  syntactically.
469
470  (\"\\\\('\\\\).\\\\('\\\\)\"
471   (1 (7 . ?'))
472   (2 (7 . ?')))
473
474  both single quotes which surround a single character, with a SYNTAX-CODE of
475  7 (meaning string quote syntax) and a MATCHING-CHAR of a single quote (meaning
476  a single quote matches a single quote).  Assuming that the buffer syntax table
477  does not specify single quotes to have quote syntax, the element will only
478  highlight single quotes of the form 'c' as strings syntactically.
479  Other forms, such as foo'bar or 'fubar', will not be highlighted as strings.
480
481 This is normally set via `font-lock-defaults'."
482 )
483 ;;;###autoload
484 (make-variable-buffer-local 'font-lock-syntactic-keywords)
485
486 (defvar font-lock-defaults nil
487   "The defaults font Font Lock mode for the current buffer.
488 Normally, do not set this directly.  If you are writing a major mode,
489 put a property of `font-lock-defaults' on the major-mode symbol with
490 the desired value.
491
492 It should be a list
493
494 \(KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN)
495
496 KEYWORDS may be a symbol (a variable or function whose value is the keywords
497 to use for fontification) or a list of symbols.  If KEYWORDS-ONLY is non-nil,
498 syntactic fontification (strings and comments) is not performed.  If CASE-FOLD
499 is non-nil, the case of the keywords is ignored when fontifying.  If
500 SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form (CHAR
501 . STRING) used to set the local Font Lock syntax table, for keyword and
502 syntactic fontification (see `modify-syntax-entry').
503
504 If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
505 backwards outside any enclosing syntactic block, for syntactic fontification.
506 Typical values are `beginning-of-line' (i.e., the start of the line is known to
507 be outside a syntactic block), or `beginning-of-defun' for programming modes or
508 `backward-paragraph' for textual modes (i.e., the mode-dependent function is
509 known to move outside a syntactic block).  If nil, the beginning of the buffer
510 is used as a position outside of a syntactic block, in the worst case.
511
512 These item elements are used by Font Lock mode to set the variables
513 `font-lock-keywords', `font-lock-keywords-only',
514 `font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
515 `font-lock-beginning-of-syntax-function', respectively.
516
517 Alternatively, if the value is a symbol, it should name a major mode,
518 and the defaults for that mode will apply.")
519 (make-variable-buffer-local 'font-lock-defaults)
520
521 ;; FSF uses `font-lock-defaults-alist' and expects the major mode to
522 ;; set a value for `font-lock-defaults', but I don't like either of
523 ;; these -- requiring the mode to set `font-lock-defaults' makes it
524 ;; impossible to have defaults for a minor mode, and using an alist is
525 ;; generally a bad idea for information that really should be
526 ;; decentralized. (Who knows what strange modes might want
527 ;; font-locking?)
528
529 (defvar font-lock-keywords-only nil
530   "Non-nil means Font Lock should not do syntactic fontification.
531 This is normally set via `font-lock-defaults'.
532
533 This should be nil for all ``language'' modes, but other modes, like
534 dired, do not have anything useful in the syntax tables (no comment
535 or string delimiters, etc) and so there is no need to use them and
536 this variable should have a value of t.
537
538 You should not set this variable directly; its value is computed
539 from `font-lock-defaults', or (if that does not specify anything)
540 by examining the syntax table to see whether it appears to contain
541 anything useful.")
542 (make-variable-buffer-local 'font-lock-keywords-only)
543
544 (defvar font-lock-keywords-case-fold-search nil
545   "Whether the strings in `font-lock-keywords' should be case-folded.
546 This variable is automatically buffer-local, as the correct value depends
547 on the language in use.")
548 (make-variable-buffer-local 'font-lock-keywords-case-fold-search)
549
550 (defvar font-lock-after-fontify-buffer-hook nil
551   "Function or functions to run after completion of font-lock-fontify-buffer.")
552
553 (defvar font-lock-syntax-table nil
554   "Non-nil means use this syntax table for fontifying.
555 If this is nil, the major mode's syntax table is used.
556 This is normally set via `font-lock-defaults'.")
557 (make-variable-buffer-local 'font-lock-syntax-table)
558
559 ;; These record the parse state at a particular position, always the start of a
560 ;; line.  Used to make `font-lock-fontify-syntactically-region' faster.
561 ;; Previously, `font-lock-cache-position' was just a buffer position.  However,
562 ;; under certain situations, this occasionally resulted in mis-fontification.
563 ;; I think the "situations" were deletion with Lazy Lock mode's deferral.  sm.
564 (defvar font-lock-cache-state nil)
565 (defvar font-lock-cache-position nil)
566 (make-variable-buffer-local 'font-lock-cache-state)
567 (make-variable-buffer-local 'font-lock-cache-position)
568
569 ;; If this is nil, we only use the beginning of the buffer if we can't use
570 ;; `font-lock-cache-position' and `font-lock-cache-state'.
571 (defvar font-lock-beginning-of-syntax-function nil
572   "Non-nil means use this function to move back outside of a syntactic block.
573 If this is nil, the beginning of the buffer is used (in the worst case).
574 This is normally set via `font-lock-defaults'.")
575 (make-variable-buffer-local 'font-lock-beginning-of-syntax-function)
576
577 (defvar font-lock-fontify-buffer-function 'font-lock-default-fontify-buffer
578   "Function to use for fontifying the buffer.
579 This is normally set via `font-lock-defaults'.")
580
581 (defvar font-lock-unfontify-buffer-function 'font-lock-default-unfontify-buffer
582   "Function to use for unfontifying the buffer.
583 This is used when turning off Font Lock mode.
584 This is normally set via `font-lock-defaults'.")
585
586 (defvar font-lock-fontify-region-function 'font-lock-default-fontify-region
587   "Function to use for fontifying a region.
588 It should take two args, the beginning and end of the region, and an optional
589 third arg VERBOSE.  If non-nil, the function should print status messages.
590 This is normally set via `font-lock-defaults'.")
591
592 (defvar font-lock-unfontify-region-function 'font-lock-default-unfontify-region
593   "Function to use for unfontifying a region.
594 It should take two args, the beginning and end of the region.
595 This is normally set via `font-lock-defaults'.")
596
597 (defvar font-lock-inhibit-thing-lock nil
598   "List of Font Lock mode related modes that should not be turned on.
599 Currently, valid mode names as `fast-lock-mode' and `lazy-lock-mode'.
600 This is normally set via `font-lock-defaults'.")
601
602 ;;;###autoload
603 (defcustom font-lock-mode nil ;; customized for the option menu. dverna
604   "Non nil means `font-lock-mode' is on"
605   :group 'font-lock
606   :type 'boolean
607   :initialize 'custom-initialize-default
608   :require 'font-lock
609   :set #'(lambda (var val) (font-lock-mode (or val 0)))
610   )
611
612 (defvar font-lock-fontified nil) ; whether we have hacked this buffer
613 (put 'font-lock-fontified 'permanent-local t)
614
615 ;;;###autoload
616 (defvar font-lock-mode-hook nil
617   "Function or functions to run on entry to font-lock-mode.")
618
619 ; whether font-lock-set-defaults has already been run.
620 (defvar font-lock-defaults-computed nil)
621 (make-variable-buffer-local 'font-lock-defaults-computed)
622
623 \f
624 ;;; Initialization of faces.
625
626 ;; #### barf gag retch.  Horrid FSF lossage that we need to
627 ;; keep around for compatibility with font-lock-keywords that
628 ;; forget to properly quote their faces.  I tried just let-binding
629 ;; them when we eval the face expression, but that fails because
630 ;; some files actually use the variables directly in their init code
631 ;; without quoting them. --ben
632 (defvar font-lock-comment-face 'font-lock-comment-face
633   "This variable should not be set.
634 It is present only for horrid FSF compatibility reasons.
635 The corresponding face should be set using `edit-faces' or the
636 `set-face-*' functions.")
637 (defvar font-lock-doc-string-face 'font-lock-doc-string-face
638   "This variable should not be set.
639 It is present only for horrid FSF compatibility reasons.
640 The corresponding face should be set using `edit-faces' or the
641 `set-face-*' functions.")
642 ;; GNU compatibility
643 (define-compatible-variable-alias
644   'font-lock-doc-face 'font-lock-doc-string-face)
645 (defvar font-lock-string-face 'font-lock-string-face
646   "This variable should not be set.
647 It is present only for horrid FSF compatibility reasons.
648 The corresponding face should be set using `edit-faces' or the
649 `set-face-*' functions.")
650 (defvar font-lock-keyword-face 'font-lock-keyword-face
651   "This variable should not be set.
652 It is present only for horrid FSF compatibility reasons.
653 The corresponding face should be set using `edit-faces' or the
654 `set-face-*' functions.")
655 (defvar font-lock-builtin-face 'font-lock-builtin-face
656   "This variable should not be set.
657 It is present only for horrid FSF compatibility reasons.
658 The corresponding face should be set using `edit-faces' or the
659 `set-face-*' functions.")
660 (defvar font-lock-function-name-face 'font-lock-function-name-face
661   "This variable should not be set.
662 It is present only for horrid FSF compatibility reasons.
663 The corresponding face should be set using `edit-faces' or the
664 `set-face-*' functions.")
665 (defvar font-lock-variable-name-face 'font-lock-variable-name-face
666   "This variable should not be set.
667 It is present only for horrid FSF compatibility reasons.
668 The corresponding face should be set using `edit-faces' or the
669 `set-face-*' functions.")
670 (defvar font-lock-type-face 'font-lock-type-face
671   "This variable should not be set.
672 It is present only for horrid FSF compatibility reasons.
673 The corresponding face should be set using `edit-faces' or the
674 `set-face-*' functions.")
675 (defvar font-lock-constant-face 'font-lock-constant-face
676   "This variable should not be set.
677 It is present only for horrid FSF compatibility reasons.
678 The corresponding face should be set using `edit-faces' or the
679 `set-face-*' functions.")
680 (defvar font-lock-reference-face 'font-lock-reference-face
681   "This variable should not be set.
682 It is present only for horrid FSF compatibility reasons.
683 The corresponding face should be set using `edit-faces' or the
684 `set-face-*' functions.")
685 (defvar font-lock-preprocessor-face 'font-lock-preprocessor-face
686   "This variable should not be set.
687 It is present only for horrid FSF compatibility reasons.
688 The corresponding face should be set using `edit-faces' or the
689 `set-face-*' functions.")
690
691 (defconst font-lock-face-list
692   '(font-lock-comment-face
693     font-lock-string-face
694     font-lock-doc-string-face
695     font-lock-keyword-face
696     font-lock-builtin-face
697     font-lock-function-name-face
698     font-lock-variable-name-face
699     font-lock-type-face
700     font-lock-constant-face
701     font-lock-reference-face
702     font-lock-preprocessor-face
703     font-lock-warning-face))
704
705 (defface font-lock-comment-face
706   '((((class color) (background dark)) (:foreground "gray80"))
707     ;; blue4 is hardly different from black on windows.
708     (((class color) (background light) (type mswindows)) (:foreground "blue"))
709     (((class color) (background light)) (:foreground "blue4"))
710     (((class grayscale) (background light))
711      (:foreground "DimGray" :bold t :italic t))
712     (((class grayscale) (background dark))
713      (:foreground "LightGray" :bold t :italic t))
714     (t (:bold t)))
715   "Font Lock mode face used to highlight comments."
716   :group 'font-lock-faces)
717
718 (defface font-lock-string-face
719   '((((class color) (background dark)) (:foreground "tan"))
720     (((class color) (background light)) (:foreground "green4"))
721     (((class grayscale) (background light)) (:foreground "DimGray" :italic t))
722     (((class grayscale) (background dark)) (:foreground "LightGray" :italic t))
723     (t (:bold t)))
724   "Font Lock mode face used to highlight strings."
725   :group 'font-lock-faces)
726
727 (defface font-lock-doc-string-face
728   '((((class color) (background dark)) (:foreground "light coral"))
729     (((class color) (background light)) (:foreground "green4"))
730     (t (:bold t)))
731   "Font Lock mode face used to highlight documentation strings.
732 This is currently supported only in Lisp-like modes, which are those
733 with \"lisp\" or \"scheme\" in their name.  You can explicitly make
734 a mode Lisp-like by putting a non-nil `font-lock-lisp-like' property
735 on the major mode's symbol."
736   :group 'font-lock-faces)
737
738 (defface font-lock-keyword-face
739   '((((class color) (background dark)) (:foreground "cyan"))
740     ;; red4 is hardly different from black on windows.
741     (((class color) (background light) (type mswindows)) (:foreground "red"))
742     (((class color) (background light)) (:foreground "red4"))
743     (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
744     (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
745     (t (:bold t)))
746   "Font Lock mode face used to highlight keywords."
747   :group 'font-lock-faces)
748
749 (defface font-lock-builtin-face
750   '((((class color) (background light)) (:foreground "Purple"))
751     (((class color) (background dark)) (:foreground "Cyan"))
752     (((class grayscale) (background light)) (:foreground "LightGray" :bold t))
753     (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
754     (t (:bold t)))
755   "Font Lock mode face used to highlight builtins."
756 :group 'font-lock-faces)
757
758 (defface font-lock-function-name-face
759   '((((class color) (background dark)) (:foreground "aquamarine"))
760     ;; brown4 is hardly different from black on windows.
761     ;; I changed it to red because IMO it's pointless and ugly to
762     ;; use a million slightly different colors for niggly syntactic
763     ;; differences. --ben
764     (((class color) (background light) (type mswindows)) (:foreground "red"))
765     (((class color) (background light)) (:foreground "brown4"))
766     (t (:bold t :underline t)))
767   "Font Lock mode face used to highlight function names."
768   :group 'font-lock-faces)
769
770 (defface font-lock-variable-name-face
771   '((((class color) (background dark)) (:foreground "cyan3"))
772     (((class color) (background light)) (:foreground "magenta4"))
773     (((class grayscale) (background light))
774      (:foreground "Gray90" :bold t :italic t))
775     (((class grayscale) (background dark))
776      (:foreground "DimGray" :bold t :italic t))
777     (t (:underline t)))
778   "Font Lock mode face used to highlight variable names."
779   :group 'font-lock-faces)
780
781 (defface font-lock-type-face
782   '((((class color) (background dark)) (:foreground "wheat"))
783     (((class color) (background light)) (:foreground "steelblue"))
784     (((class grayscale) (background light)) (:foreground "Gray90" :bold t))
785     (((class grayscale) (background dark)) (:foreground "DimGray" :bold t))
786     (t (:bold t)))
787   "Font Lock mode face used to highlight types."
788   :group 'font-lock-faces)
789
790 (defface font-lock-constant-face
791   '((((class color) (background light)) (:foreground "CadetBlue"))
792     (((class color) (background dark)) (:foreground "Aquamarine"))
793     (((class grayscale) (background light))
794      (:foreground "LightGray" :bold t :underline t))
795     (((class grayscale) (background dark))
796      (:foreground "Gray50" :bold t :underline t))
797     (t (:bold t :underline t)))
798   "Font Lock mode face used to highlight constants and labels."
799 :group 'font-lock-faces)
800
801 (defface font-lock-reference-face
802   '((((class color) (background dark)) (:foreground "cadetblue2"))
803     (((class color) (background light)) (:foreground "red3"))
804     (((class grayscale) (background light))
805      (:foreground "LightGray" :bold t :underline t))
806     (((class grayscale) (background dark))
807      (:foreground "Gray50" :bold t :underline t)))
808   "Font Lock mode face used to highlight references."
809   :group 'font-lock-faces)
810
811 (defface font-lock-preprocessor-face
812   '((((class color) (background dark)) (:foreground "steelblue1"))
813     (((class color) (background light)) (:foreground "blue3"))
814     (t (:underline t)))
815   "Font Lock Mode face used to highlight preprocessor conditionals."
816   :group 'font-lock-faces)
817
818 (defface font-lock-warning-face
819   '((((class color) (background light)) (:foreground "Red" :bold t))
820     (((class color) (background dark)) (:foreground "Pink" :bold t))
821     (t (:inverse-video t :bold t)))
822   "Font Lock mode face used to highlight warnings."
823   :group 'font-lock-faces)
824
825 (defun font-lock-recompute-variables ()
826   ;; Is this a Draconian thing to do?
827   (mapc #'(lambda (buffer)
828             (with-current-buffer buffer
829               (font-lock-mode 0)
830               (font-lock-set-defaults t)))
831         (buffer-list)))
832
833 ;; Backwards-compatible crud.
834
835 (defun font-lock-reset-all-faces ()
836   (dolist (face font-lock-face-list)
837     (face-spec-set face (get face 'face-defface-spec))))
838
839 (defun font-lock-use-default-fonts ()
840   "Reset the font-lock faces to a default set of fonts."
841   (interactive)
842   ;; #### !!!!
843   (font-lock-reset-all-faces))
844
845 (defun font-lock-use-default-colors ()
846   "Reset the font-lock faces to a default set of colors."
847   (interactive)
848   ;; #### !!!!
849   (font-lock-reset-all-faces))
850
851 (defun font-lock-use-default-minimal-decoration ()
852   "Reset the font-lock patterns to a fast, minimal set of decorations."
853   (and font-lock-maximum-decoration
854        (setq font-lock-maximum-decoration nil)
855        (font-lock-recompute-variables)))
856
857 (defun font-lock-use-default-maximal-decoration ()
858   "Reset the font-lock patterns to a larger set of decorations."
859   (and (not (eq t font-lock-maximum-decoration))
860        (setq font-lock-maximum-decoration t)
861        (font-lock-recompute-variables)))
862
863 \f
864 ;;;;;;;;;;;;;;;;;;;;;;        actual code        ;;;;;;;;;;;;;;;;;;;;;;
865
866 ;;; To fontify the whole buffer by language syntax, we go through it a
867 ;;; character at a time, creating extents on the boundary of each syntactic
868 ;;; unit (that is, one extent for each block comment, one for each line
869 ;;; comment, one for each string, etc.)  This is done with the C function
870 ;;; syntactically-sectionize.  It's in C for speed (the speed of lisp function
871 ;;; calls was a real bottleneck for this task since it involves examining each
872 ;;; character in turn.)
873 ;;;
874 ;;; Then we make a second pass, to fontify the buffer based on other patterns
875 ;;; specified by regexp.  When we find a match for a region of text, we need
876 ;;; to change the fonts on those characters.  This is done with the
877 ;;; put-text-property function, which knows how to efficiently share extents.
878 ;;; Conceptually, we are attaching some particular face to each of the
879 ;;; characters in a range, but the implementation of this involves creating
880 ;;; extents, or resizing existing ones.
881 ;;;
882 ;;; Each time a modification happens to a line, we re-fontify the entire line.
883 ;;; We do this by first removing the extents (text properties) on the line,
884 ;;; and then doing the syntactic and keyword passes again on that line.  (More
885 ;;; generally, each modified region is extended to include the preceding and
886 ;;; following BOL or EOL.)
887 ;;;
888 ;;; This means that, as the user types, we repeatedly go back to the beginning
889 ;;; of the line, doing more work the longer the line gets.  This doesn't cost
890 ;;; much in practice, and if we don't, then we incorrectly fontify things when,
891 ;;; for example, inserting spaces into `intfoo () {}'.
892 ;;;
893
894 \f
895 ;; The user level functions
896
897 ;;;###autoload
898 (defun font-lock-mode (&optional arg)
899   "Toggle Font Lock Mode.
900 With arg, turn font-lock mode on if and only if arg is positive.
901
902 When Font Lock mode is enabled, text is fontified as you type it:
903
904  - Comments are displayed in `font-lock-comment-face';
905  - Strings are displayed in `font-lock-string-face';
906  - Documentation strings (in Lisp-like languages) are displayed in
907    `font-lock-doc-string-face';
908  - Language keywords (\"reserved words\") are displayed in
909    `font-lock-keyword-face';
910  - Function names in their defining form are displayed in
911    `font-lock-function-name-face';
912  - Variable names in their defining form are displayed in
913    `font-lock-variable-name-face';
914  - Type names are displayed in `font-lock-type-face';
915  - References appearing in help files and the like are displayed
916    in `font-lock-reference-face';
917  - Preprocessor declarations are displayed in
918   `font-lock-preprocessor-face';
919
920    and
921
922  - Certain other expressions are displayed in other faces according
923    to the value of the variable `font-lock-keywords'.
924
925 Where modes support different levels of fontification, you can use the variable
926 `font-lock-maximum-decoration' to specify which level you generally prefer.
927 When you turn Font Lock mode on/off the buffer is fontified/defontified, though
928 fontification occurs only if the buffer is less than `font-lock-maximum-size'.
929 To fontify a buffer without turning on Font Lock mode, and regardless of buffer
930 size, you can use \\[font-lock-fontify-buffer].
931
932 See the variable `font-lock-keywords' for customization."
933   (interactive "P")
934   (let ((on-p (if arg (> (prefix-numeric-value arg) 0) (not font-lock-mode)))
935         (maximum-size (if (not (consp font-lock-maximum-size))
936                           font-lock-maximum-size
937                         (cdr (or (assq major-mode font-lock-maximum-size)
938                                  (assq t font-lock-maximum-size))))))
939     ;; Font-lock mode will refuse to turn itself on if in batch mode
940     ;; to avoid potential (probably not actual, though) slowdown.  We
941     ;; used to try to "be nice" by avoiding doing this in temporary
942     ;; buffers.  But with the deferral code we don't need this, and it
943     ;; definitely screws some things up.
944     (if (noninteractive)
945         (setq on-p nil))
946     (cond (on-p
947            (make-local-hook 'after-change-functions)
948            (add-hook 'after-change-functions
949                      'font-lock-after-change-function nil t)
950            (add-hook 'pre-idle-hook 'font-lock-pre-idle-hook))
951           (t
952            (remove-hook 'after-change-functions
953                         'font-lock-after-change-function t)
954            (setq font-lock-defaults-computed nil
955                  font-lock-keywords nil)
956            ;; We have no business doing this here, since 
957            ;; pre-idle-hook is global.  Other buffers may
958            ;; still be in font-lock mode.  -dkindred@cs.cmu.edu
959            ;; (remove-hook 'pre-idle-hook 'font-lock-pre-idle-hook)
960            ))
961     (set (make-local-variable 'font-lock-mode) on-p)
962     (cond (on-p
963            (font-lock-set-defaults-1)
964            (run-hooks 'font-lock-mode-hook)
965            (cond (font-lock-fontified
966                   nil)
967                  ((or (null maximum-size) (<= (buffer-size) maximum-size))
968                   (font-lock-fontify-buffer))
969                  (font-lock-verbose
970                   (progress-feedback-with-label
971                    'font-lock
972                    "Fontifying %s... buffer too big." 'abort
973                    (buffer-name)))))
974           (font-lock-fontified
975            (setq font-lock-fontified nil)
976            (font-lock-unfontify-region (point-min) (point-max))
977            (font-lock-thing-lock-cleanup))
978           (t
979            (font-lock-thing-lock-cleanup)))
980     (redraw-modeline)))
981
982 ;; For init-file hooks
983 ;;;###autoload
984 (defun turn-on-font-lock ()
985   "Unconditionally turn on Font Lock mode."
986   (interactive)
987   (font-lock-mode 1))
988
989 ;;;###autoload
990 (defun turn-off-font-lock ()
991   "Unconditionally turn off Font Lock mode."
992   (interactive)
993   (font-lock-mode 0))
994
995 ;;; FSF has here:
996
997 ;; support for add-keywords, global-font-lock-mode and
998 ;; font-lock-support-mode (unified support for various *-lock modes).
999
1000 \f
1001 ;; Fontification functions.
1002
1003 ;; We first define some defsubsts to encapsulate the way we add
1004 ;; faces to a region of text.  I am planning on modifying the
1005 ;; text-property mechanism so that multiple independent classes
1006 ;; of text properties can exist.  That way, for example, ediff's
1007 ;; face text properties don't interfere with font lock's face
1008 ;; text properties.  Due to the XEmacs implementation of text
1009 ;; properties in terms of extents, doing this is fairly trivial:
1010 ;; instead of using the `text-prop' property, you just use a
1011 ;; specified property.
1012
1013 (defsubst font-lock-set-face (start end face)
1014   ;; Set the face on the characters in the range.
1015   (put-nonduplicable-text-property start end 'face face)
1016   (put-nonduplicable-text-property start end 'font-lock t))
1017
1018 (defsubst font-lock-remove-face (start end)
1019   ;; Remove any syntax highlighting on the characters in the range.
1020   (put-nonduplicable-text-property start end 'face nil)
1021   (put-nonduplicable-text-property start end 'font-lock nil)
1022   (if lookup-syntax-properties
1023       (put-nonduplicable-text-property start end 'syntax-table nil)))
1024
1025 (defsubst font-lock-set-syntax (start end syntax)
1026   ;; Set the face on the characters in the range.
1027   (put-nonduplicable-text-property start end 'syntax-table syntax)
1028   (put-nonduplicable-text-property start end 'font-lock t))
1029
1030 (defsubst font-lock-any-faces-p (start end)
1031   ;; Return non-nil if we've put any syntax highlighting on
1032   ;; the characters in the range.
1033   ;;
1034   ;; used to look for 'text-prop property, but this has problems if
1035   ;; you put any other text properties in the vicinity.  Simon
1036   ;; Marshall suggested looking for the 'face property (this is what
1037   ;; FSF Emacs does) but that's equally bogus.  Only reliable way is
1038   ;; for font-lock to specially mark its extents.
1039   ;;
1040   ;; FSF's (equivalent) definition of this defsubst would be
1041   ;; (text-property-not-all start end 'font-lock nil)
1042   ;;
1043   ;; Perhaps our `map-extents' is faster than our definition
1044   ;; of `text-property-not-all'.  #### If so, `text-property-not-all'
1045   ;; should be fixed ...
1046   ;;
1047   (map-extents 'extent-property (current-buffer) start (1- end) 'font-lock))
1048
1049 \f
1050 ;; Fontification functions.
1051
1052 ;; Rather than the function, e.g., `font-lock-fontify-region' containing the
1053 ;; code to fontify a region, the function runs the function whose name is the
1054 ;; value of the variable, e.g., `font-lock-fontify-region-function'.  Normally,
1055 ;; the value of this variable is, e.g., `font-lock-default-fontify-region'
1056 ;; which does contain the code to fontify a region.  However, the value of the
1057 ;; variable could be anything and thus, e.g., `font-lock-fontify-region' could
1058 ;; do anything.  The indirection of the fontification functions gives major
1059 ;; modes the capability of modifying the way font-lock.el fontifies.  Major
1060 ;; modes can modify the values of, e.g., `font-lock-fontify-region-function',
1061 ;; via the variable `font-lock-defaults'.
1062 ;;
1063 ;; For example, Rmail mode sets the variable `font-lock-defaults' so that
1064 ;; font-lock.el uses its own function for buffer fontification.  This function
1065 ;; makes fontification be on a message-by-message basis and so visiting an
1066 ;; RMAIL file is much faster.  A clever implementation of the function might
1067 ;; fontify the headers differently than the message body.  (It should, and
1068 ;; correspondingly for Mail mode, but I can't be bothered to do the work.  Can
1069 ;; you?)  This hints at a more interesting use...
1070 ;;
1071 ;; Languages that contain text normally contained in different major modes
1072 ;; could define their own fontification functions that treat text differently
1073 ;; depending on its context.  For example, Perl mode could arrange that here
1074 ;; docs are fontified differently than Perl code.  Or Yacc mode could fontify
1075 ;; rules one way and C code another.  Neat!
1076 ;;
1077 ;; A further reason to use the fontification indirection feature is when the
1078 ;; default syntactual fontification, or the default fontification in general,
1079 ;; is not flexible enough for a particular major mode.  For example, perhaps
1080 ;; comments are just too hairy for `font-lock-fontify-syntactically-region' to
1081 ;; cope with.  You need to write your own version of that function, e.g.,
1082 ;; `hairy-fontify-syntactically-region', and make your own version of
1083 ;; `hairy-fontify-region' call that function before calling
1084 ;; `font-lock-fontify-keywords-region' for the normal regexp fontification
1085 ;; pass.  And Hairy mode would set `font-lock-defaults' so that font-lock.el
1086 ;; would call your region fontification function instead of its own.  For
1087 ;; example, TeX modes could fontify {\foo ...} and \bar{...}  etc. multi-line
1088 ;; directives correctly and cleanly.  (It is the same problem as fontifying
1089 ;; multi-line strings and comments; regexps are not appropriate for the job.)
1090
1091 ;;;###autoload
1092 (defun font-lock-fontify-buffer ()
1093   "Fontify the current buffer the way `font-lock-mode' would.
1094 See `font-lock-mode' for details.
1095
1096 This can take a while for large buffers."
1097   (interactive)
1098   (let ((font-lock-verbose (or font-lock-verbose (interactive-p))))
1099     (funcall font-lock-fontify-buffer-function)))
1100
1101 (defun font-lock-unfontify-buffer ()
1102   (funcall font-lock-unfontify-buffer-function))
1103
1104 (defun font-lock-fontify-region (beg end &optional loudly)
1105   (funcall font-lock-fontify-region-function beg end loudly))
1106
1107 (defun font-lock-unfontify-region (beg end &optional loudly)
1108   (funcall font-lock-unfontify-region-function beg end loudly))
1109
1110 (defun font-lock-default-fontify-buffer ()
1111   (interactive)
1112   ;; if we don't widen, then the C code will fail to
1113   ;; realize that we're inside a comment.
1114   (save-restriction
1115     (widen)
1116     (let ((was-on font-lock-mode)
1117           (font-lock-verbose (or font-lock-verbose (interactive-p)))
1118           (font-lock-message-threshold 0)
1119           (aborted nil))
1120       ;; Turn it on to run hooks and get the right font-lock-keywords.
1121       (or was-on (font-lock-mode 1))
1122       (font-lock-unfontify-region (point-min) (point-max) t)
1123       ;;    (buffer-syntactic-context-flush-cache)
1124     
1125       ;; If a ^G is typed during fontification, abort the fontification, but
1126       ;; return normally (do not signal.)  This is to make it easy to abort
1127       ;; fontification if it's taking a long time, without also causing the
1128       ;; buffer not to pop up.  If a real abort is desired, the user can ^G
1129       ;; again.
1130       ;;
1131       ;; Possibly this should happen down in font-lock-fontify-region instead
1132       ;; of here, but since that happens from the after-change-hook (meaning
1133       ;; much more frequently) I'm afraid of the bad consequences of stealing
1134       ;; the interrupt character at inopportune times.
1135       ;;
1136       (condition-case nil
1137           (save-excursion
1138             (font-lock-fontify-region (point-min) (point-max)))
1139         (t
1140          (setq aborted t)))
1141
1142       (or was-on                        ; turn it off if it was off.
1143           (let ((font-lock-fontified nil)) ; kludge to prevent defontification
1144             (font-lock-mode 0)))
1145       (set (make-local-variable 'font-lock-fontified) t)
1146       (when (and aborted font-lock-verbose)
1147         (progress-feedback-with-label 'font-lock "Fontifying %s... aborted."
1148                                       'abort (buffer-name))))
1149     (run-hooks 'font-lock-after-fontify-buffer-hook)))
1150
1151 (defun font-lock-default-unfontify-buffer ()
1152   (font-lock-unfontify-region (point-min) (point-max))
1153   (set (make-local-variable 'font-lock-fontified) nil))
1154
1155 ;; This used to be `font-lock-fontify-region', and before that,
1156 ;; `font-lock-fontify-region' used to be the name used for what is now
1157 ;; `font-lock-fontify-syntactically-region'.
1158 (defun font-lock-default-fontify-region (beg end &optional loudly)
1159   (let ((modified (buffer-modified-p))
1160         (buffer-undo-list t) (inhibit-read-only t)
1161         (old-syntax-table (syntax-table))
1162         buffer-file-name buffer-file-truename)
1163     (unwind-protect
1164         (progn
1165           ;; Use the fontification syntax table, if any.
1166           (if font-lock-syntax-table (set-syntax-table font-lock-syntax-table))
1167           ;; Now do the fontification.
1168           (font-lock-unfontify-region beg end)
1169           (when font-lock-syntactic-keywords
1170             (font-lock-fontify-syntactic-keywords-region beg end))
1171           (unless font-lock-keywords-only
1172             (font-lock-fontify-syntactically-region beg end loudly))
1173           (font-lock-fontify-keywords-region beg end loudly))
1174       ;; Clean up.
1175       (set-syntax-table old-syntax-table)
1176       (and (not modified) (buffer-modified-p) (set-buffer-modified-p nil)))))
1177
1178 ;; The following must be rethought, since keywords can override fontification.
1179 ;      ;; Now scan for keywords, but not if we are inside a comment now.
1180 ;      (or (and (not font-lock-keywords-only)
1181 ;              (let ((state (parse-partial-sexp beg end nil nil 
1182 ;                                               font-lock-cache-state)))
1183 ;                (or (nth 4 state) (nth 7 state))))
1184 ;         (font-lock-fontify-keywords-region beg end))
1185
1186 (defun font-lock-default-unfontify-region (beg end &optional maybe-loudly)
1187   (when (and maybe-loudly font-lock-verbose
1188              (>= (- end beg) font-lock-message-threshold))
1189     (progress-feedback-with-label 'font-lock "Fontifying %s..." 0
1190                                   (buffer-name)))
1191   (let ((modified (buffer-modified-p))
1192         (buffer-undo-list t) (inhibit-read-only t)
1193         buffer-file-name buffer-file-truename)
1194     (font-lock-remove-face beg end)
1195     (and (not modified) (buffer-modified-p) (set-buffer-modified-p nil))))
1196
1197 ;; Following is the original FSF version (similar to our original
1198 ;; version, before the deferred stuff was added).
1199 ;;
1200 ;; I think that lazy-lock v2 tries to do something similar.
1201 ;; Those efforts should be merged.
1202
1203 ;; Called when any modification is made to buffer text.
1204 ;(defun font-lock-after-change-function (beg end old-len)
1205 ;  (save-excursion
1206 ;    (save-match-data
1207 ;      ;; Rescan between start of line from `beg' and start of line after `end'.
1208 ;      (font-lock-fontify-region
1209 ;       (progn (goto-char beg) (beginning-of-line) (point))
1210 ;       (progn (goto-char end) (forward-line 1) (point))))))
1211
1212 (defvar font-lock-always-fontify-immediately nil
1213   "Set this to non-nil to disable font-lock deferral.
1214 Otherwise, changes to existing text will not be processed until the
1215 next redisplay cycle, avoiding excessive fontification when many
1216 buffer modifications are performed or a buffer is reverted.")
1217
1218 ;; list of buffers in which there is a pending change.
1219 (defvar font-lock-pending-buffer-table (make-hash-table :weakness 'key))
1220 ;; table used to keep track of ranges needing fontification.
1221 (defvar font-lock-range-table (make-range-table))
1222
1223 (defun font-lock-pre-idle-hook ()
1224   (condition-case font-lock-error
1225       (if (> (hash-table-count font-lock-pending-buffer-table) 0)
1226           (font-lock-fontify-pending-extents))
1227     (error (warn "Error caught in `font-lock-pre-idle-hook': %s"
1228                  font-lock-error))))
1229
1230 ;;; called when any modification is made to buffer text.  This function
1231 ;;; remembers the changed ranges until the next redisplay, at which point
1232 ;;; the extents are merged and pruned, and the resulting ranges fontified.
1233 ;;; This function could easily be adapted to other after-change-functions.
1234
1235 (defun font-lock-after-change-function (beg end old-len)
1236   (when font-lock-mode
1237     ;; treat deletions as if the following character (or previous, if
1238     ;; there is no following) were inserted. (also use the previous
1239     ;; character at end of line.  this avoids a problem when you
1240     ;; insert a comment on the line before a line of code: if we use
1241     ;; the following char, then when you hit backspace, the following
1242     ;; line of code turns the comment color.) this is a bit of a hack
1243     ;; but allows us to use text properties for everything.
1244     (if (= beg end)
1245         (cond ((not (save-excursion (goto-char end) (eolp)))
1246                (setq end (1+ end)))
1247               ((/= beg (point-min)) (setq beg (1- beg)))
1248               (t nil)))
1249     (put-text-property beg end 'font-lock-pending t)
1250     (puthash (current-buffer) t font-lock-pending-buffer-table)
1251     (if font-lock-always-fontify-immediately
1252         (font-lock-fontify-pending-extents))))
1253
1254 (defun font-lock-fontify-pending-extents ()
1255   ;; ah, the beauty of mapping functions.
1256   ;; this function is actually shorter than the old version, which handled
1257   ;; only one buffer and one contiguous region!
1258   (save-match-data
1259     (maphash
1260      #'(lambda (buffer dummy)
1261          ;; remove first, to avoid infinite reprocessing if error
1262          (remhash buffer font-lock-pending-buffer-table)
1263          (when (buffer-live-p buffer)
1264            (clear-range-table font-lock-range-table)
1265            (with-current-buffer buffer
1266              (save-excursion
1267                (save-restriction
1268                  ;; if we don't widen, then the C code in
1269                  ;; syntactically-sectionize will fail to realize that
1270                  ;; we're inside a comment. #### We don't actually use
1271                  ;; syntactically-sectionize any more.  Do we still
1272                  ;; need the widen?
1273                  (widen)
1274                  (let ((zmacs-region-stays
1275                         zmacs-region-stays)) ; protect from change!
1276                    (map-extents
1277                     #'(lambda (ex dummy-maparg)
1278                         ;; first expand the ranges to full lines,
1279                         ;; because that is what will be fontified;
1280                         ;; then use a range table to merge the
1281                         ;; ranges. (we could also do this simply using
1282                         ;; text properties.  the range table code was
1283                         ;; here from a previous version of this code
1284                         ;; and works just as well.)
1285                         (let* ((beg (extent-start-position ex))
1286                                (end (extent-end-position ex))
1287                                (beg (progn (goto-char beg)
1288                                            (beginning-of-line)
1289                                            (point)))
1290                                (end (progn (goto-char end)
1291                                            (forward-line 1)
1292                                            (point))))
1293                           (put-range-table beg end t
1294                                            font-lock-range-table)))
1295                     nil nil nil nil nil 'font-lock-pending t)
1296                    ;; clear all pending extents first in case of error below.
1297                    (put-text-property (point-min) (point-max)
1298                                       'font-lock-pending nil)
1299                    (map-range-table
1300                     #'(lambda (beg end val)
1301                         ;; This creates some unnecessary progress gauges.
1302 ;;                      (if (and (= beg (point-min))
1303 ;;                               (= end (point-max)))
1304 ;;                          (font-lock-fontify-buffer)
1305 ;;                        (font-lock-fontify-region beg end)))
1306                         (font-lock-fontify-region beg end))
1307                     font-lock-range-table)))))))
1308      font-lock-pending-buffer-table)))
1309 \f
1310 ;; Syntactic fontification functions.
1311
1312 (defun font-lock-lisp-like (mode)
1313   ;; Note: (or (get mode 'font-lock-lisp-like) (string-match ...)) is
1314   ;; not enough because the property needs to be able to specify a nil
1315   ;; value.
1316   (if (plist-member (symbol-plist mode) 'font-lock-lisp-like)
1317       (get mode 'font-lock-lisp-like)
1318     ;; If the property is not specified, guess.  Similar logic exists
1319     ;; in add-log, but I think this encompasses more modes.
1320     (string-match "lisp\\|scheme" (symbol-name mode))))
1321
1322 ;; fontify-syntactically-region used to use syntactically-sectionize, which
1323 ;; was supposedly much faster than the FSF version because it was written in
1324 ;; C. However, the FSF version uses parse-partial-sexp, which is also
1325 ;; written in C, and the benchmarking I did showed the
1326 ;; syntactically-sectionize code to be slower overall. So here's the
1327 ;; FSF version, modified to support font-lock-doc-string-face.
1328 ;; -- mct 2000-12-29
1329 ;; #### Andy conditionally reverted Matt's change when we were experimenting
1330 ;; with making lookup-syntax-properties an optional feature.  I don't see how
1331 ;; this code relates to lookup-syntax-properties, though.  I wonder if the
1332 ;; bug is in our (?) version of parse-partial-sexp.  Andy says no.  Of course,
1333 ;; Matt benchmarked ... WTF knows?  sjt 2002-09-28
1334 (defun font-lock-fontify-syntactically-region (start end &optional loudly)
1335   "Put proper face on each string and comment between START and END.
1336 START should be at the beginning of a line.  Optional argument LOUDLY
1337 is currently ignored."
1338   (if font-lock-keywords-only
1339       nil
1340
1341     ;; #### Shouldn't this just be using 'loudly??
1342     (when (and font-lock-verbose
1343                (>= (- end start) font-lock-message-threshold))
1344       (progress-feedback-with-label 'font-lock
1345                                     "Fontifying %s... (syntactically)" 5
1346                                     (buffer-name)))
1347     (goto-char start)
1348
1349     (let ((lisp-like (font-lock-lisp-like major-mode))
1350           (cache (marker-position font-lock-cache-position))
1351           state string beg depth)
1352       ;;
1353       ;; Find the state at the `beginning-of-line' before `start'.
1354       (if (eq start cache)
1355           ;; Use the cache for the state of `start'.
1356           (setq state font-lock-cache-state)
1357         ;; Find the state of `start'.
1358         (if (null font-lock-beginning-of-syntax-function)
1359             ;; Use the state at the previous cache position, if any, or
1360             ;; otherwise calculate from `point-min'.
1361             (if (or (null cache) (< start cache))
1362                 (setq state (parse-partial-sexp (point-min) start))
1363               (setq state (parse-partial-sexp cache start nil nil
1364                                               font-lock-cache-state)))
1365           ;; Call the function to move outside any syntactic block.
1366           (funcall font-lock-beginning-of-syntax-function)
1367           (setq state (parse-partial-sexp (point) start)))
1368         ;; Cache the state and position of `start'.
1369         (setq font-lock-cache-state state)
1370         (set-marker font-lock-cache-position start))
1371       ;;
1372       ;; If the region starts inside a string or comment, show the extent of it.
1373       (when (or (nth 3 state) (nth 4 state))
1374         (setq string (nth 3 state) beg (point))
1375         (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table))
1376         (font-lock-set-face beg (point) (if string 
1377                                             font-lock-string-face
1378                                           font-lock-comment-face)))
1379       ;;
1380       ;; Find each interesting place between here and `end'.
1381       (while (and (< (point) end)
1382                   (progn
1383                     (setq state (parse-partial-sexp (point) end nil nil state
1384                                                     'syntax-table))
1385                     (or (nth 3 state) (nth 4 state))))
1386         (setq depth (nth 0 state) string (nth 3 state) beg (nth 8 state))
1387         (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table))
1388         (if string
1389             ;; #### It would be nice if we handled Python and other
1390             ;; non-Lisp languages with docstrings correctly.
1391             (let ((face (if (and lisp-like (= depth 1))
1392                             'font-lock-doc-string-face
1393                           'font-lock-string-face)))
1394               (if font-lock-fontify-string-delimiters
1395                   (font-lock-set-face beg (point) face)
1396                 (font-lock-set-face (+ beg 1) (- (point) 1) face)))
1397           (font-lock-set-face beg (point)
1398                               font-lock-comment-face))))))
1399 \f
1400 ;;; Additional text property functions.
1401
1402 ;; The following three text property functions are not generally available (and
1403 ;; it's not certain that they should be) so they are inlined for speed.
1404 ;; The case for `fillin-text-property' is simple; it may or not be generally
1405 ;; useful.  (Since it is used here, it is useful in at least one place.;-)
1406 ;; However, the case for `append-text-property' and `prepend-text-property' is
1407 ;; more complicated.  Should they remove duplicate property values or not?  If
1408 ;; so, should the first or last duplicate item remain?  Or the one that was
1409 ;; added?  In our implementation, the first duplicate remains.
1410
1411 ;; XEmacs: modified all these functions to use
1412 ;; `put-nonduplicable-text-property' instead of `put-text-property', and
1413 ;; the first one to take both SETPROP and MARKPROP, in accordance with the
1414 ;; changed definitions of `font-lock-any-faces-p' and `font-lock-set-face'.
1415
1416 (defsubst font-lock-fillin-text-property (start end setprop markprop value &optional object)
1417   "Fill in one property of the text from START to END.
1418 Arguments PROP and VALUE specify the property and value to put where none are
1419 already in place.  Therefore existing property values are not overwritten.
1420 Optional argument OBJECT is the string or buffer containing the text."
1421   (let ((start (text-property-any start end markprop nil object)) next)
1422     (while start
1423       (setq next (next-single-property-change start markprop object end))
1424       (put-nonduplicable-text-property start next setprop value object)
1425       (put-nonduplicable-text-property start next markprop value object)
1426       (setq start (text-property-any next end markprop nil object)))))
1427
1428 ;; This function (from simon's unique.el) is rewritten and inlined for speed.
1429 ;(defun unique (list function)
1430 ;  "Uniquify LIST, deleting elements using FUNCTION.
1431 ;Return the list with subsequent duplicate items removed by side effects.
1432 ;FUNCTION is called with an element of LIST and a list of elements from LIST,
1433 ;and should return the list of elements with occurrences of the element removed,
1434 ;i.e., a function such as `delete' or `delq'.
1435 ;This function will work even if LIST is unsorted.  See also `uniq'."
1436 ;  (let ((list list))
1437 ;    (while list
1438 ;      (setq list (setcdr list (funcall function (car list) (cdr list))))))
1439 ;  list)
1440
1441 (defsubst font-lock-unique (list)
1442   "Uniquify LIST, deleting elements using `delq'.
1443 Return the list with subsequent duplicate items removed by side effects."
1444   (let ((list list))
1445     (while list
1446       (setq list (setcdr list (delq (car list) (cdr list))))))
1447   list)
1448
1449 ;; A generalisation of `facemenu-add-face' for any property, but without the
1450 ;; removal of inactive faces via `facemenu-discard-redundant-faces' and special
1451 ;; treatment of `default'.  Uses `unique' to remove duplicate property values.
1452 (defsubst font-lock-prepend-text-property (start end prop value &optional object)
1453   "Prepend to one property of the text from START to END.
1454 Arguments PROP and VALUE specify the property and value to prepend to the value
1455 already in place.  The resulting property values are always lists, and unique.
1456 Optional argument OBJECT is the string or buffer containing the text."
1457   (let ((val (if (listp value) value (list value))) next prev)
1458     (while (/= start end)
1459       (setq next (next-single-property-change start prop object end)
1460             prev (get-text-property start prop object))
1461       (put-text-property
1462        start next prop
1463        (font-lock-unique (append val (if (listp prev) prev (list prev))))
1464        object)
1465       (setq start next))))
1466
1467 (defsubst font-lock-append-text-property (start end prop value &optional object)
1468   "Append to one property of the text from START to END.
1469 Arguments PROP and VALUE specify the property and value to append to the value
1470 already in place.  The resulting property values are always lists, and unique.
1471 Optional argument OBJECT is the string or buffer containing the text."
1472   (let ((val (if (listp value) value (list value))) next prev)
1473     (while (/= start end)
1474       (setq next (next-single-property-change start prop object end)
1475             prev (get-text-property start prop object))
1476       (put-text-property
1477        start next prop
1478        (font-lock-unique (append (if (listp prev) prev (list prev)) val))
1479        object)
1480       (setq start next))))
1481 \f
1482 ;;; Syntactic regexp fontification functions (taken from FSF Emacs 20.7.1)
1483
1484 ;; These syntactic keyword pass functions are identical to those keyword pass
1485 ;; functions below, with the following exceptions; (a) they operate on
1486 ;; `font-lock-syntactic-keywords' of course, (b) they are all `defun' as speed
1487 ;; is less of an issue, (c) eval of property value does not occur JIT as speed
1488 ;; is less of an issue, (d) OVERRIDE cannot be `prepend' or `append' as it
1489 ;; makes no sense for `syntax-table' property values, (e) they do not do it
1490 ;; LOUDLY as it is not likely to be intensive.
1491
1492 (defun font-lock-apply-syntactic-highlight (highlight)
1493   "Apply HIGHLIGHT following a match.
1494 HIGHLIGHT should be of the form MATCH-HIGHLIGHT,
1495 see `font-lock-syntactic-keywords'."
1496   (let* ((match (nth 0 highlight))
1497          (start (match-beginning match)) (end (match-end match))
1498          (value (nth 1 highlight))
1499          (override (nth 2 highlight)))
1500     (unless (numberp (car-safe value))
1501       (setq value (eval value)))
1502     (cond ((not start)
1503            ;; No match but we might not signal an error.
1504            (or (nth 3 highlight)
1505                (error "No match %d in highlight %S" match highlight)))
1506           ((not override)
1507            ;; Cannot override existing fontification.
1508            (or (map-extents 'extent-property (current-buffer)
1509                             start end 'syntax-table)
1510                (font-lock-set-syntax start end value)))
1511           ((eq override t)
1512            ;; Override existing fontification.
1513            (font-lock-set-syntax start end value))
1514           ((eq override 'keep)
1515            ;; Keep existing fontification.
1516            (font-lock-fillin-text-property start end
1517                                            'syntax-table 'font-lock value)))))
1518
1519 (defun font-lock-fontify-syntactic-anchored-keywords (keywords limit)
1520   "Fontify according to KEYWORDS until LIMIT.
1521  KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords',
1522  LIMIT can be modified by the value of its PRE-MATCH-FORM."
1523   (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
1524         ;; Evaluate PRE-MATCH-FORM.
1525         (pre-match-value (eval (nth 1 keywords))))
1526     ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
1527     (if (and (numberp pre-match-value) (> pre-match-value (point)))
1528         (setq limit pre-match-value)
1529       (save-excursion (end-of-line) (setq limit (point))))
1530     (save-match-data
1531       ;; Find an occurrence of `matcher' before `limit'.
1532       (while (if (stringp matcher)
1533                  (re-search-forward matcher limit t)
1534                (funcall matcher limit))
1535         ;; Apply each highlight to this instance of `matcher'.
1536         (setq highlights lowdarks)
1537         (while highlights
1538           (font-lock-apply-syntactic-highlight (car highlights))
1539           (setq highlights (cdr highlights)))))
1540     ;; Evaluate POST-MATCH-FORM.
1541     (eval (nth 2 keywords))))
1542
1543 (defun font-lock-fontify-syntactic-keywords-region (start end)
1544   "Fontify according to `font-lock-syntactic-keywords' between START and END.
1545 START should be at the beginning of a line."
1546 ;;  ;; If `font-lock-syntactic-keywords' is a symbol, get the real keywords.
1547   (when (symbolp font-lock-syntactic-keywords)
1548     (setq font-lock-syntactic-keywords (font-lock-eval-keywords
1549                                         font-lock-syntactic-keywords)))
1550   ;; If `font-lock-syntactic-keywords' is not compiled, compile it.
1551   (unless (eq (car font-lock-syntactic-keywords) t)
1552     (setq font-lock-syntactic-keywords (font-lock-compile-keywords
1553                                         font-lock-syntactic-keywords)))
1554   ;; Get down to business.
1555   (let ((case-fold-search font-lock-keywords-case-fold-search)
1556         (keywords (cdr font-lock-syntactic-keywords))
1557         keyword matcher highlights)
1558     (while keywords
1559       ;; Find an occurrence of `matcher' from `start' to `end'.
1560       (setq keyword (car keywords) matcher (car keyword))
1561       (goto-char start)
1562       (while (if (stringp matcher)
1563                  (re-search-forward matcher end t)
1564                (funcall matcher end))
1565         ;; Apply each highlight to this instance of `matcher', which may be
1566         ;; specific highlights or more keywords anchored to `matcher'.
1567         (setq highlights (cdr keyword))
1568         (while highlights
1569           (if (numberp (car (car highlights)))
1570               (font-lock-apply-syntactic-highlight (car highlights))
1571             (font-lock-fontify-syntactic-anchored-keywords (car highlights)
1572                                                            end))
1573           (setq highlights (cdr highlights))))
1574       (setq keywords (cdr keywords)))))
1575 \f
1576 ;;; Regexp fontification functions.
1577
1578 (defsubst font-lock-apply-highlight (highlight)
1579   "Apply HIGHLIGHT following a match.
1580 HIGHLIGHT should be of the form MATCH-HIGHLIGHT, see `font-lock-keywords'."
1581   (let* ((match (nth 0 highlight))
1582          (start (match-beginning match)) (end (match-end match))
1583          (override (nth 2 highlight)))
1584     (let ((newface (nth 1 highlight)))
1585       (or (symbolp newface)
1586           (setq newface (eval newface)))
1587       (cond ((not start)
1588              ;; No match but we might not signal an error.
1589              (or (nth 3 highlight)
1590                  (error "No match %d in highlight %S" match highlight)))
1591             ((= start end) nil)
1592             ((not override)
1593              ;; Cannot override existing fontification.
1594              (or (font-lock-any-faces-p start end)
1595                  (font-lock-set-face start end newface)))
1596             ((eq override t)
1597              ;; Override existing fontification.
1598              (font-lock-set-face start end newface))
1599             ((eq override 'keep)
1600              ;; Keep existing fontification.
1601              (font-lock-fillin-text-property start end 'face 'font-lock
1602                                              newface))
1603             ((eq override 'prepend)
1604              ;; Prepend to existing fontification.
1605              (font-lock-prepend-text-property start end 'face newface))
1606             ((eq override 'append)
1607              ;; Append to existing fontification.
1608              (font-lock-append-text-property start end 'face newface))))))
1609
1610 (defsubst font-lock-fontify-anchored-keywords (keywords limit)
1611   "Fontify according to KEYWORDS until LIMIT.
1612 KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords',
1613 LIMIT can be modified by the value of its PRE-MATCH-FORM."
1614   (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
1615         ;; Evaluate PRE-MATCH-FORM.
1616         (pre-match-value (eval (nth 1 keywords))))
1617     ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
1618     (if (and (numberp pre-match-value) (> pre-match-value (point)))
1619         (setq limit pre-match-value)
1620       (save-excursion (end-of-line) (setq limit (point))))
1621     (save-match-data
1622       ;; Find an occurrence of `matcher' before `limit'.
1623       (while (if (stringp matcher)
1624                  (re-search-forward matcher limit t)
1625                (funcall matcher limit))
1626         ;; Apply each highlight to this instance of `matcher'.
1627         (setq highlights lowdarks)
1628         (while highlights
1629           (font-lock-apply-highlight (car highlights))
1630           (setq highlights (cdr highlights)))))
1631     ;; Evaluate POST-MATCH-FORM.
1632     (eval (nth 2 keywords))))
1633
1634 (defun font-lock-fontify-keywords-region (start end &optional loudvar)
1635   "Fontify according to `font-lock-keywords' between START and END.
1636 START should be at the beginning of a line."
1637   (let ((loudly (and font-lock-verbose
1638                      (>= (- end start) font-lock-message-threshold))))
1639     (unless (eq (car-safe font-lock-keywords) t)
1640       (setq font-lock-keywords
1641             (font-lock-compile-keywords font-lock-keywords)))
1642     (let* ((case-fold-search font-lock-keywords-case-fold-search)
1643            (keywords (cdr font-lock-keywords))
1644            (bufname (buffer-name)) 
1645            (progress 5) (old-progress 5)
1646            (iter 0)
1647            (nkeywords (length keywords))
1648            keyword matcher highlights)
1649       ;;
1650       ;; Fontify each item in `font-lock-keywords' from `start' to `end'.
1651       ;; In order to measure progress accurately we need to know how
1652       ;; many keywords we have and how big the region is. Then progress
1653       ;; is ((pos - start)/ (end - start) * nkeywords 
1654       ;;        + iteration / nkeywords) * 100
1655       (while keywords
1656         ;;
1657         ;; Find an occurrence of `matcher' from `start' to `end'.
1658         (setq keyword (car keywords) matcher (car keyword))
1659         (goto-char start)
1660         (while (and (< (point) end)
1661                     (if (stringp matcher)
1662                         (re-search-forward matcher end t)
1663                       (funcall matcher end)))
1664           ;; calculate progress
1665           (setq progress
1666                 (+ (/ (* (- (point) start) 95) (* (- end start) nkeywords))
1667                    (/ (* iter 95) nkeywords) 5))
1668           (when (and loudly (> progress old-progress))
1669             (progress-feedback-with-label 'font-lock
1670                                           "Fontifying %s... (regexps)"
1671                                           progress bufname))
1672           (setq old-progress progress)
1673           ;; Apply each highlight to this instance of `matcher', which may be
1674           ;; specific highlights or more keywords anchored to `matcher'.
1675           (setq highlights (cdr keyword))
1676           (while highlights
1677             (if (numberp (car (car highlights)))
1678                 (let ((end (match-end (car (car highlights)))))
1679                   (font-lock-apply-highlight (car highlights))
1680                   ;; restart search just after the end of the
1681                   ;; keyword so keywords can share bracketing
1682                   ;; expressions.
1683                   (and end (goto-char end)))
1684               (font-lock-fontify-anchored-keywords (car highlights) end))
1685             (setq highlights (cdr highlights))))
1686         (setq iter (1+ iter))
1687         (setq keywords (cdr keywords))))
1688     (if loudly
1689         (progress-feedback-with-label 'font-lock "Fontifying %s... " 100
1690                                       (buffer-name)))))
1691
1692 \f
1693 ;; Various functions.
1694
1695 ;; Turn off other related packages if they're on.  I prefer a hook. --sm.
1696 ;; These explicit calls are easier to understand
1697 ;; because people know what they will do.
1698 ;; A hook is a mystery because it might do anything whatever. --rms.
1699 (defun font-lock-thing-lock-cleanup ()
1700   (cond ((and (boundp 'fast-lock-mode) fast-lock-mode)
1701          (fast-lock-mode -1))
1702         ((and (boundp 'lazy-lock-mode) lazy-lock-mode)
1703          (lazy-lock-mode -1))
1704         ((and (boundp 'lazy-shot-mode) lazy-shot-mode)
1705          (lazy-shot-mode -1))))
1706
1707 ;; Do something special for these packages after fontifying.  I prefer a hook.
1708 (defun font-lock-after-fontify-buffer ()
1709   (cond ((and (boundp 'fast-lock-mode) fast-lock-mode)
1710          (fast-lock-after-fontify-buffer))
1711         ((and (boundp 'lazy-lock-mode) lazy-lock-mode)
1712          (lazy-lock-after-fontify-buffer))))
1713
1714 \f
1715 ;; Various functions.
1716
1717 (defun font-lock-compile-keywords (keywords)
1718   "Compile KEYWORDS (a list) and return the list of compiled keywords.
1719 Each keyword has the form (MATCHER HIGHLIGHT ...).  See `font-lock-keywords'."
1720   (if (eq (car-safe keywords) t)
1721       keywords
1722     (cons t (mapcar 'font-lock-compile-keyword keywords))))
1723
1724 (defun font-lock-compile-keyword (keyword)
1725   (cond ((nlistp keyword)               ; Just MATCHER
1726          (list keyword '(0 font-lock-keyword-face)))
1727         ((eq (car keyword) 'eval)       ; Specified (eval . FORM)
1728          (font-lock-compile-keyword (eval (cdr keyword))))
1729         ((numberp (cdr keyword))        ; Specified (MATCHER . MATCH)
1730          (list (car keyword) (list (cdr keyword) 'font-lock-keyword-face)))
1731         ((symbolp (cdr keyword))        ; Specified (MATCHER . FACENAME)
1732          (list (car keyword) (list 0 (cdr keyword))))
1733         ((nlistp (nth 1 keyword))       ; Specified (MATCHER . HIGHLIGHT)
1734          (list (car keyword) (cdr keyword)))
1735         (t                              ; Hopefully (MATCHER HIGHLIGHT ...)
1736          keyword)))
1737
1738 (defun font-lock-eval-keywords (keywords)
1739   "Evaluate KEYWORDS if a function (funcall) or variable (eval) name."
1740   (if (listp keywords)
1741       keywords
1742     (font-lock-eval-keywords (if (fboundp keywords)
1743                                  (funcall keywords)
1744                                (eval keywords)))))
1745
1746 (defun font-lock-choose-keywords (keywords level)
1747   ;; Return LEVELth element of KEYWORDS.  A LEVEL of nil is equal to a
1748   ;; LEVEL of 0, a LEVEL of t is equal to (1- (length KEYWORDS)).
1749   (let ((level (if (not (consp level))
1750                    level
1751                  (cdr (or (assq major-mode level) (assq t level))))))
1752     (cond ((symbolp keywords)
1753            keywords)
1754           ((numberp level)
1755            (or (nth level keywords) (car (reverse keywords))))
1756           ((eq level t)
1757            (car (reverse keywords)))
1758           (t
1759            (car keywords)))))
1760
1761 \f
1762 ;;; Determining which set of font-lock keywords to use.
1763
1764 (defun font-lock-find-font-lock-defaults (modesym)
1765   ;; Get the defaults based on the major mode.
1766   (let (raw-defaults)
1767     ;; I want a do-while loop!
1768     (while (progn
1769              (setq raw-defaults (get modesym 'font-lock-defaults))
1770              (and raw-defaults (symbolp raw-defaults)
1771                   (setq modesym raw-defaults)))
1772       )
1773     raw-defaults))
1774
1775 (defun font-lock-examine-syntax-table ()
1776   ; Computes the value of font-lock-keywords-only for this buffer.
1777   (if (eq (syntax-table) (standard-syntax-table))
1778       ;; Assume that modes which haven't bothered to install their own
1779       ;; syntax table don't do anything syntactically interesting.
1780       ;; Really, the standard-syntax-table shouldn't have comments and
1781       ;; strings in it, but changing that now might break things.
1782       nil
1783     ;; else map over the syntax table looking for strings or comments.
1784     (let (got-one)
1785       ;; XEmacs 20.0 ...
1786       (if (fboundp 'map-syntax-table)
1787           (setq got-one
1788                 (map-syntax-table
1789                  #'(lambda (key value)
1790                      (memq (char-syntax-from-code value)
1791                            '(?\" ?\< ?\> ?\$)))
1792                  (syntax-table)))
1793         ;; older Emacsen.
1794         (let ((i (1- (length (syntax-table)))))
1795           (while (>= i 0)
1796             (if (memq (char-syntax i) '(?\" ?\< ?\> ?\$))
1797                 (setq got-one t i 0))
1798             (setq i (1- i)))))
1799       (set (make-local-variable 'font-lock-keywords-only) (not got-one)))))
1800
1801 ;; font-lock-set-defaults is in fontl-hooks.el.
1802
1803 ;;;###autoload
1804 (defun font-lock-set-defaults-1 (&optional explicit-defaults)
1805   ;; does everything that font-lock-set-defaults does except
1806   ;; enable font-lock-mode.  This is called by `font-lock-mode'.
1807   ;; Note that the return value is used!
1808
1809   (if (and font-lock-defaults-computed (not explicit-defaults))
1810       ;; nothing to do.
1811       nil
1812
1813     (or font-lock-keywords
1814         (let* ((defaults (or (and (not (eq t explicit-defaults))
1815                                   explicit-defaults)
1816                              ;; in case modes decide to set
1817                              ;; `font-lock-defaults' themselves,
1818                              ;; as in FSF Emacs.
1819                              font-lock-defaults
1820                              (font-lock-find-font-lock-defaults major-mode)))
1821                (keywords (font-lock-choose-keywords
1822                           (nth 0 defaults) font-lock-maximum-decoration)))
1823
1824           ;; Keywords?
1825           (setq font-lock-keywords (if (fboundp keywords)
1826                                        (funcall keywords)
1827                                      (eval keywords)))
1828           (or font-lock-keywords
1829               ;; older way:
1830               ;; try to look for a variable `foo-mode-font-lock-keywords',
1831               ;; or similar.
1832               (let ((major (symbol-name major-mode))
1833                     (try #'(lambda (n)
1834                              (if (stringp n) (setq n (intern-soft n)))
1835                              (if (and n
1836                                       (boundp n))
1837                                  n
1838                                nil))))
1839                 (setq font-lock-keywords 
1840                       (symbol-value
1841                        (or (funcall try (get major-mode 'font-lock-keywords))
1842                            (funcall try (concat major "-font-lock-keywords"))
1843                            (funcall try (and (string-match "-mode\\'" major)
1844                                              (concat (substring 
1845                                                       major 0 
1846                                                       (match-beginning 0))
1847                                                      "-font-lock-keywords")))
1848                            'font-lock-keywords)))))
1849
1850           ;; Case fold?
1851           (if (>= (length defaults) 3)
1852               (setq font-lock-keywords-case-fold-search (nth 2 defaults))
1853             ;; older way:
1854             ;; look for a property 'font-lock-keywords-case-fold-search on
1855             ;; the major-mode symbol.
1856             (let* ((nonexist (make-symbol ""))
1857                    (value (get major-mode 'font-lock-keywords-case-fold-search
1858                                nonexist)))
1859               (if (not (eq nonexist value))
1860                   (setq font-lock-keywords-case-fold-search value))))
1861
1862           ;; Syntactic?
1863           (if (>= (length defaults) 2)
1864               (setq font-lock-keywords-only (nth 1 defaults))
1865             ;; older way:
1866             ;; cleverly examine the syntax table.
1867             (font-lock-examine-syntax-table))
1868            
1869           ;; Syntax table?
1870           (if (nth 3 defaults)
1871               (let ((slist (nth 3 defaults)))
1872                 (setq font-lock-syntax-table
1873                       (copy-syntax-table (syntax-table)))
1874                 (while slist
1875                   (modify-syntax-entry (car (car slist)) (cdr (car slist))
1876                                        font-lock-syntax-table)
1877                   (setq slist (cdr slist)))))
1878
1879           ;; Syntax function?
1880           (cond (defaults
1881                   (setq font-lock-beginning-of-syntax-function
1882                         (nth 4 defaults)))
1883                 (t
1884                  ;; older way:
1885                  ;; defaults not specified at all, so use `beginning-of-defun'.
1886                  (setq font-lock-beginning-of-syntax-function
1887                        'beginning-of-defun)))))
1888
1889     (setq font-lock-cache-position (make-marker))
1890     (setq font-lock-defaults-computed t)))
1891
1892 \f
1893 ;;;;;;;;;;;;;;;;;;;;;;         keywords         ;;;;;;;;;;;;;;;;;;;;;;
1894
1895 ;;; Various major-mode interfaces.
1896 ;;; Probably these should go in with the source of the respective major modes.
1897
1898 ;; The defaults and keywords listed here should perhaps be moved into
1899 ;; mode-specific files.
1900
1901 ;; For C and Lisp modes we use `beginning-of-defun', rather than nil,
1902 ;; for SYNTAX-BEGIN.  Thus the calculation of the cache is usually
1903 ;; faster but not infallible, so we risk mis-fontification.  --sm.
1904
1905 (put 'c-mode 'font-lock-defaults 
1906      '((c-font-lock-keywords
1907         c-font-lock-keywords-1 c-font-lock-keywords-2 c-font-lock-keywords-3)
1908        nil nil ((?_ . "w")) beginning-of-defun))
1909 (put 'c++-c-mode 'font-lock-defaults 'c-mode)
1910 (put 'elec-c-mode 'font-lock-defaults 'c-mode)
1911
1912 (put 'c++-mode 'font-lock-defaults
1913      '((c++-font-lock-keywords
1914         c++-font-lock-keywords-1 c++-font-lock-keywords-2
1915         c++-font-lock-keywords-3)
1916        nil nil ((?_ . "w") (?~ . "w")) beginning-of-defun))
1917
1918 (put 'java-mode 'font-lock-defaults 
1919      '((java-font-lock-keywords
1920         java-font-lock-keywords-1 java-font-lock-keywords-2
1921         java-font-lock-keywords-3)
1922        nil nil ((?_ . "w")) beginning-of-defun
1923        (font-lock-mark-block-function . mark-defun)))
1924
1925 (put 'lisp-mode 'font-lock-defaults
1926      '((lisp-font-lock-keywords
1927         lisp-font-lock-keywords-1 lisp-font-lock-keywords-2)
1928        nil nil
1929        ((?: . "w") (?- . "w") (?* . "w") (?+ . "w") (?. . "w") (?< . "w")
1930         (?> . "w") (?= . "w") (?! . "w") (?? . "w") (?$ . "w") (?% . "w")
1931         (?_ . "w") (?& . "w") (?~ . "w") (?^ . "w") (?/ . "w"))
1932        beginning-of-defun))
1933 (put 'emacs-lisp-mode 'font-lock-defaults 'lisp-mode)
1934 (put 'lisp-interaction-mode 'font-lock-defaults 'lisp-mode)
1935
1936 (put 'scheme-mode 'font-lock-defaults
1937      '(scheme-font-lock-keywords
1938        nil t
1939        ((?: . "w") (?- . "w") (?* . "w") (?+ . "w") (?. . "w") (?< . "w")
1940         (?> . "w") (?= . "w") (?! . "w") (?? . "w") (?$ . "w") (?% . "w")
1941         (?_ . "w") (?& . "w") (?~ . "w") (?^ . "w") (?/ . "w"))
1942        beginning-of-defun))
1943 (put 'inferior-scheme-mode 'font-lock-defaults 'scheme-mode)
1944 (put 'scheme-interaction-mode 'font-lock-defaults 'scheme-mode)
1945
1946 (put 'tex-mode 'font-lock-defaults
1947      ;; For TeX modes we could use `backward-paragraph' for the same reason.
1948      '(tex-font-lock-keywords nil nil ((?$ . "\""))))
1949 ;; the nine billion names of TeX mode...
1950 (put 'bibtex-mode       'font-lock-defaults 'tex-mode)
1951 (put 'plain-tex-mode    'font-lock-defaults 'tex-mode)
1952 (put 'slitex-tex-mode   'font-lock-defaults 'tex-mode)
1953 (put 'SliTeX-mode       'font-lock-defaults 'tex-mode)
1954 (put 'slitex-mode       'font-lock-defaults 'tex-mode)
1955 (put 'latex-tex-mode    'font-lock-defaults 'tex-mode)
1956 (put 'LaTex-tex-mode    'font-lock-defaults 'tex-mode)
1957 (put 'latex-mode        'font-lock-defaults 'tex-mode)
1958 (put 'LaTeX-mode        'font-lock-defaults 'tex-mode)
1959 (put 'japanese-LaTeX-mode 'font-lock-defaults 'tex-mode)
1960 (put 'japanese-SliTeX-mode 'font-lock-defaults 'tex-mode)
1961 (put 'FoilTeX-mode      'font-lock-defaults 'tex-mode)
1962 (put 'LATeX-MoDe        'font-lock-defaults 'tex-mode)
1963 (put 'lATEx-mODe        'font-lock-defaults 'tex-mode)
1964 ;; ok, this is getting a bit silly ...
1965 (put 'eDOm-xETAl        'font-lock-defaults 'tex-mode)
1966
1967 ;;; Various regexp information shared by several modes.
1968 ;;; Information specific to a single mode should go in its load library.
1969
1970 (defconst lisp-font-lock-keywords-1
1971   (list
1972    ;; Anything not a variable or type declaration is fontified as a function.
1973    ;; It would be cleaner to allow preceding whitespace, but it would also be
1974    ;; about five times slower.
1975    (list (concat "^(\\(def\\("
1976                   ;; Variable declarations.
1977                   "\\(const\\(\\|ant\\)\\|ine-key\\(\\|-after\\)\\|var\\|custom\\)\\|"
1978                   ;; Structure declarations.
1979                   "\\(class\\|struct\\|type\\)\\|"
1980                   ;; Everything else is a function declaration.
1981                   "\\([^ \t\n\(\)]+\\)"
1982                   "\\)\\)\\>"
1983                   ;; Any whitespace and declared object.
1984                   "[ \t'\(]*"
1985                   "\\([^ \t\n\(\)]+\\)?")
1986           '(1 font-lock-keyword-face)
1987           '(8 (cond ((match-beginning 3) 'font-lock-variable-name-face)
1988                     ((match-beginning 6) 'font-lock-type-face)
1989                     (t 'font-lock-function-name-face))
1990               nil t))
1991    )
1992  "Subdued level highlighting Lisp modes.")
1993
1994 (defconst lisp-font-lock-keywords-2
1995   (append lisp-font-lock-keywords-1
1996    (list
1997     ;;
1998     ;; Control structures.  ELisp and CLisp combined.
1999     ;;
2000     (cons
2001      (concat
2002       "(\\("
2003       ;; beginning of generated stuff
2004       ;; to regenerate, use the regexp-opt below, then delete the outermost
2005       ;; grouping, then use the macro below to break up the string.
2006       ;; (regexp-opt
2007       ;;   '("cond" "if" "while" "let" "let*" "prog" "progn" "prog1"
2008       ;;     "prog2" "progv" "catch" "throw" "save-restriction"
2009       ;;     "save-excursion" "save-window-excursion"
2010       ;;     "save-current-buffer" "with-current-buffer"
2011       ;;     "save-selected-window" "with-selected-window"
2012       ;;     "save-selected-frame" "with-selected-frame"
2013       ;;     "with-temp-file" "with-temp-buffer" "with-output-to-string"
2014       ;;     "with-string-as-buffer-contents"
2015       ;;     "save-match-data" "unwind-protect" "call-with-condition-handler"
2016       ;;     "condition-case" "track-mouse" "autoload"
2017       ;;     "eval-after-load" "eval-and-compile" "eval-when-compile"
2018       ;;     "when" "unless" "do" "dolist" "dotimes" "flet" "labels"
2019       ;;     "lambda" "block" "return" "return-from" "loop") t)
2020       ;; (setq last-kbd-macro
2021       ;;   (read-kbd-macro "\" C-7 C-1 <right> C-r \\\\| 3*<right> \" RET"))
2022       "autoload\\|block\\|c\\(?:a\\(?:ll-with-condition-handler\\|tch\\)\\|"
2023       "ond\\(?:ition-case\\)?\\)\\|do\\(?:list\\|times\\)?\\|"
2024       "eval-\\(?:a\\(?:fter-load\\|nd-compile\\)\\|when-compile\\)\\|flet\\|"
2025       "if\\|l\\(?:a\\(?:bels\\|mbda\\)\\|et\\*?\\|oop\\)\\|prog[12nv]?\\|"
2026       "return\\(?:-from\\)?\\|save-\\(?:current-buffer\\|excursion\\|"
2027       "match-data\\|restriction\\|selected-\\(?:frame\\|window\\)\\|"
2028       "window-excursion\\)\\|t\\(?:hrow\\|rack-mouse\\)\\|un\\(?:less\\|"
2029       "wind-protect\\)\\|w\\(?:h\\(?:en\\|ile\\)\\|ith-\\(?:current-buffer\\|"
2030       "output-to-string\\|s\\(?:elected-\\(?:frame\\|window\\)\\|"
2031       "tring-as-buffer-contents\\)\\|temp-\\(?:buffer\\|file\\)\\)\\)"
2032       ;; end of generated stuff
2033       "\\)\\>") 1)
2034     ;;
2035     ;; Feature symbols as references.
2036     '("(\\(featurep\\|provide\\|require\\)\\>[ \t']*\\(\\sw+\\)?"
2037       (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
2038     ;;
2039     ;; Words inside \\[] tend to be for `substitute-command-keys'.
2040     '("\\\\\\\\\\[\\(\\sw+\\)]" 1 font-lock-reference-face prepend)
2041     ;;
2042     ;; Words inside `' tend to be symbol names.
2043     '("`\\(\\sw\\sw+\\)'" 1 font-lock-reference-face prepend)
2044     ;;
2045     ;; CLisp `:' keywords as references.
2046     '("\\<:\\sw+\\>" 0 font-lock-reference-face prepend)
2047     ;;
2048     ;; ELisp and CLisp `&' keywords as types.
2049     '("\\<\\&\\(optional\\|rest\\|whole\\)\\>" . font-lock-type-face)
2050     ))
2051   "Gaudy level highlighting for Lisp modes.")
2052
2053 (defvar lisp-font-lock-keywords lisp-font-lock-keywords-1
2054   "Default expressions to highlight in Lisp modes.")
2055
2056 ;; The previous version, before replacing it with the FSF version.
2057 ;(defconst lisp-font-lock-keywords-1 (purecopy
2058 ; '(;;
2059 ;   ;; highlight defining forms.  This doesn't work too nicely for
2060 ;   ;; (defun (setf foo) ...) but it does work for (defvar foo) which
2061 ;   ;; is more important.
2062 ;   ("^(def[-a-z]+\\s +\\([^ \t\n\)]+\\)" 1 font-lock-function-name-face)
2063 ;   ;;
2064 ;   ;; highlight CL keywords (three clauses seems faster than one)
2065 ;   ("\\s :\\(\\(\\sw\\|\\s_\\)+\\)\\>" . 1)
2066 ;   ("(:\\(\\(\\sw\\|\\s_\\)+\\)\\>" . 1)
2067 ;   ("':\\(\\(\\sw\\|\\s_\\)+\\)\\>" . 1)
2068 ;   ;;
2069 ;   ;; this is highlights things like (def* (setf foo) (bar baz)), but may
2070 ;   ;; be slower (I haven't really thought about it)
2071 ;;   ("^(def[-a-z]+\\s +\\(\\s(\\S)*\\s)\\|\\S(\\S *\\)"
2072 ;;    1 font-lock-function-name-face)
2073 ;   ))
2074 ; "For consideration as a value of `lisp-font-lock-keywords'.
2075 ;This does fairly subdued highlighting.")
2076 ;
2077 ;(defconst lisp-font-lock-keywords-2 (purecopy
2078 ;  (append lisp-font-lock-keywords-1
2079 ;   '(;;
2080 ;     ;; Highlight control structures
2081 ;     ("(\\(cond\\|if\\|when\\|unless\\|[ec]?\\(type\\)?case\\)[ \t\n]" . 1)
2082 ;     ("(\\(while\\|do\\|let\\*?\\|flet\\|labels\\|prog[nv12*]?\\)[ \t\n]" . 1)
2083 ;     ("(\\(do\\*\\|dotimes\\|dolist\\|loop\\)[ \t\n]" . 1)
2084 ;     ("(\\(catch\\|\\throw\\|block\\|return\\|return-from\\)[ \t\n]" . 1)
2085 ;     ("(\\(save-restriction\\|save-window-restriction\\)[ \t\n]" . 1)
2086 ;     ("(\\(save-excursion\\|unwind-protect\\|condition-case\\)[ \t\n]" . 1)
2087 ;     ;;
2088 ;     ;; highlight function names in emacs-lisp docstrings (in the syntax
2089 ;     ;; that substitute-command-keys understands.)
2090 ;     ("\\\\\\\\\\[\\([^]\\\n]+\\)]" 1 font-lock-keyword-face t)
2091 ;     ;;
2092 ;     ;; highlight words inside `' which tend to be function names
2093 ;     ("`\\([-a-zA-Z0-9_][-a-zA-Z0-9_][-a-zA-Z0-9_.]+\\)'"
2094 ;      1 font-lock-keyword-face t)
2095 ;     )))
2096 ; "For consideration as a value of `lisp-font-lock-keywords'.
2097 ;
2098 ;This does a lot more highlighting.")
2099
2100 (defvar scheme-font-lock-keywords
2101   (eval-when-compile
2102     (list
2103      ;;
2104      ;; Declarations.  Hannes Haug <hannes.haug@student.uni-tuebingen.de> says
2105      ;; this works for SOS, STklos, SCOOPS, Meroon and Tiny CLOS.
2106      (list (concat "(\\(define\\("
2107                    ;; Function names.
2108                    "\\(\\|-\\(generic\\(\\|-procedure\\)\\|method\\)\\)\\|"
2109                    ;; Macro names, as variable names.  A bit dubious, this.
2110                    "\\(-syntax\\)\\|"
2111                    ;; Class names.
2112                    "\\(-class\\)"
2113                    "\\)\\)\\>"
2114                    ;; Any whitespace and declared object.
2115                    "[ \t]*(?"
2116                    "\\(\\sw+\\)?")
2117            '(1 font-lock-keyword-face)
2118            '(8 (cond ((match-beginning 3) 'font-lock-function-name-face)
2119                      ((match-beginning 6) 'font-lock-variable-name-face)
2120                      (t 'font-lock-type-face))
2121                nil t))
2122      ;;
2123      ;; Control structures.
2124 ;(regexp-opt '("begin" "call-with-current-continuation" "call/cc"
2125 ;              "call-with-input-file" "call-with-output-file" "case" "cond"
2126 ;              "do" "else" "for-each" "if" "lambda"
2127 ;              "let\\*?" "let-syntax" "letrec" "letrec-syntax"
2128 ;              ;; Hannes Haug <hannes.haug@student.uni-tuebingen.de> wants:
2129 ;              "and" "or" "delay"
2130 ;              ;; Stefan Monnier <stefan.monnier@epfl.ch> says don't bother:
2131 ;              ;;"quasiquote" "quote" "unquote" "unquote-splicing"
2132 ;              "map" "syntax" "syntax-rules"))
2133      (cons
2134       (concat "(\\("
2135               "and\\|begin\\|c\\(a\\(ll\\(-with-\\(current-continuation\\|"
2136               "input-file\\|output-file\\)\\|/cc\\)\\|se\\)\\|ond\\)\\|"
2137               "d\\(elay\\|o\\)\\|else\\|for-each\\|if\\|"
2138               "l\\(ambda\\|et\\(-syntax\\|\\*?\\|rec\\(\\|-syntax\\)\\)\\)\\|"
2139               "map\\|or\\|syntax\\(\\|-rules\\)"
2140               "\\)\\>") 1)
2141      ;;
2142      ;; David Fox <fox@graphics.cs.nyu.edu> for SOS/STklos class specifiers.
2143      '("\\<<\\sw+>\\>" . font-lock-type-face)
2144      ;;
2145      ;; Scheme `:' keywords as references.
2146      '("\\<:\\sw+\\>" . font-lock-reference-face)
2147      ))
2148 "Default expressions to highlight in Scheme modes.")
2149
2150 ;; The previous version, before replacing it with the FSF version.
2151 ;(defconst scheme-font-lock-keywords (purecopy
2152 ; '(("(define[ \t]+(?\\([^ \t\n\)]+\\)" 1 font-lock-function-name-face)
2153 ;   ("(\\(cond\\|lambda\\|begin\\|if\\|else\\|case\\|do\\)[ \t\n]" . 1)
2154 ;   ("(\\(\\|letrec\\|let\\*?\\|set!\\|and\\|or\\)[ \t\n]" . 1)
2155 ;   ("(\\(quote\\|unquote\\|quasiquote\\|unquote-splicing\\)[ \t\n]" . 1)
2156 ;   ("(\\(syntax\\|syntax-rules\\|define-syntax\\|let-syntax\\|letrec-syntax\\)[ \t\n]" . 1)))
2157 ;  "Expressions to highlight in Scheme buffers.")
2158
2159 (defconst c-font-lock-keywords-1 nil
2160   "Subdued level highlighting for C modes.")
2161
2162 (defconst c-font-lock-keywords-2 nil
2163   "Medium level highlighting for C modes.")
2164
2165 (defconst c-font-lock-keywords-3 nil
2166   "Gaudy level highlighting for C modes.")
2167
2168 (defconst c++-font-lock-keywords-1 nil
2169   "Subdued level highlighting for C++ modes.")
2170
2171 (defconst c++-font-lock-keywords-2 nil
2172   "Medium level highlighting for C++ modes.")
2173
2174 (defconst c++-font-lock-keywords-3 nil
2175   "Gaudy level highlighting for C++ modes.")
2176
2177 (defun font-lock-match-c++-style-declaration-item-and-skip-to-next (limit)
2178   ;; Match, and move over, any declaration/definition item after point.
2179   ;; The expect syntax of an item is "word" or "word::word", possibly ending
2180   ;; with optional whitespace and a "(".  Everything following the item (but
2181   ;; belonging to it) is expected to by skip-able by `forward-sexp', and items
2182   ;; are expected to be separated with a "," or ";".
2183   (if (looking-at "[ \t*&]*\\(\\(?:\\sw\\|\\s_\\)+\\)\\(::\\(\\(?:\\sw\\|\\s_\\)+\\)\\)?[ \t]*\\((\\)?")
2184       (save-match-data
2185         (condition-case nil
2186             (save-restriction
2187               ;; Restrict to the end of line, currently guaranteed to be LIMIT.
2188               (narrow-to-region (point-min) limit)
2189               (goto-char (match-end 1))
2190               ;; Move over any item value, etc., to the next item.
2191               (while (not (looking-at "[ \t]*\\([,;]\\|$\\)"))
2192                 (goto-char (or (scan-sexps (point) 1) (point-max))))
2193               (goto-char (match-end 0)))
2194           (error t)))))
2195
2196 (let ((c-keywords
2197 ;      ("break" "continue" "do" "else" "for" "if" "return" "switch" "while")
2198        "break\\|continue\\|do\\|else\\|for\\|if\\|return\\|switch\\|while")
2199       (c-type-types
2200 ;      ("auto" "extern" "register" "static" "typedef" "struct" "union" "enum"
2201 ;       "signed" "unsigned" "short" "long" "int" "char" "float" "double"
2202 ;       "void" "volatile" "const")
2203        (concat "auto\\|c\\(har\\|onst\\)\\|double\\|e\\(num\\|xtern\\)\\|"
2204                "float\\|int\\|long\\|register\\|"
2205                "s\\(hort\\|igned\\|t\\(atic\\|ruct\\)\\)\\|typedef\\|"
2206                "un\\(ion\\|signed\\)\\|vo\\(id\\|latile\\)"))   ; 6 ()s deep.
2207       (c++-keywords
2208 ;      ("break" "continue" "do" "else" "for" "if" "return" "switch" "while"
2209 ;       "asm" "catch" "delete" "new" "operator" "sizeof" "this" "throw" "try"
2210 ;       "protected" "private" "public" "const_cast" "dynamic_cast" "reinterpret_cast"
2211 ;       "static_cast" "and" "bitor" "or" "xor" "compl" "bitand" "and_eq"
2212 ;       "or_eq" "xor_eq" "not" "not_eq" "typeid" "false" "true")
2213        (concat "a\\(nd\\(\\|_eq\\)\\|sm\\)\\|"
2214                "b\\(it\\(or\\|and\\)\\|reak\\)\\|"
2215                "c\\(atch\\|o\\(mpl\\|n\\(tinue\\|st_cast\\)\\)\\)\\|"
2216                "d\\(elete\\|o\\|ynamic_cast\\)\\|"
2217                "else\\|"
2218                "f\\(alse\\|or\\)\\|if\\|"
2219                "n\\(ew\\|ot\\(\\|_eq\\)\\)\\|"
2220                "p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|"
2221                "or\\(\\|_eq\\)\\|"
2222                "re\\(interpret_cast\\|turn\\)\\|"
2223                "s\\(izeof\\|tatic_cast\\|witch\\)\\|"
2224                "t\\(h\\(is\\|row\\)\\|r\\(ue\\|y\\)\\|ypeid\\)\\|"
2225                "xor\\(\\|_eq\\)\\|while"))
2226       (c++-type-types
2227 ;      ("auto" "extern" "register" "static" "typedef" "struct" "union" "enum"
2228 ;       "signed" "unsigned" "short" "long" "int" "char" "float" "double"
2229 ;       "void" "volatile" "const" "class" "inline" "friend" "bool"
2230 ;       "virtual" "complex" "template" "explicit" "mutable" "export" "namespace"
2231 ;       "using" "typename" "wchar_t")
2232        (concat "auto\\|bool\\|c\\(har\\|lass\\|o\\(mplex\\|nst\\)\\)\\|"
2233                "double\\|"
2234                "e\\(num\\|x\\(p\\(licit\\|ort\\)\\|tern\\)\\)\\|"
2235                "f\\(loat\\|riend\\)\\|"
2236                "in\\(line\\|t\\)\\|long\\|mutable\\|namespace\\|register\\|"
2237                "s\\(hort\\|igned\\|t\\(atic\\|ruct\\)\\)\\|"
2238                "t\\(emplate\\|ype\\(def\\|name\\)\\)\\|"
2239                "u\\(\\(n\\(ion\\|signed\\)\\|sing\\)\\)\\|"
2240                "v\\(irtual\\|o\\(id\\|latile\\)\\)\\|"
2241                "wchar_t"))              ; 11 ()s deep.
2242       (ctoken "\\(\\sw\\|\\s_\\|[:~*&]\\)+")
2243       )
2244  (setq c-font-lock-keywords-1
2245   (list
2246    ;;
2247    ;; These are all anchored at the beginning of line for speed.
2248    ;;
2249    ;; Fontify function name definitions (GNU style; without type on line).
2250    
2251    ;; In FSF this has the simpler definition of "\\sw+" for ctoken.
2252    ;; I'm not sure if ours is more correct.
2253    ;; This is a subset of the next rule, and is slower when present. --dmoore
2254    ;; (list (concat "^\\(" ctoken "\\)[ \t]*(") 1 'font-lock-function-name-face)
2255    ;;
2256    ;; fontify the names of functions being defined.
2257    ;; FSF doesn't have this but I think it should be fast for us because
2258    ;; our regexp routines are more intelligent than FSF's about handling
2259    ;; anchored-at-newline. (When I added this hack in regex.c, it halved
2260    ;; the time to do the regexp phase of font-lock for a C file!) Not
2261    ;; including this discriminates against those who don't follow the
2262    ;; GNU coding style. --ben
2263    ;; x?x?x?y?z should always be: (x(xx?)?)?y?z --dmoore
2264    (list (concat
2265           "^\\("
2266           "\\(" ctoken "[ \t]+\\)"      ; type specs; there can be no
2267           "\\("
2268           "\\(" ctoken "[ \t]+\\)"      ; more than 3 tokens, right?
2269           "\\(" ctoken "[ \t]+\\)"
2270           "?\\)?\\)?"
2271           "\\([*&]+[ \t]*\\)?"          ; pointer
2272           "\\(" ctoken "\\)[ \t]*(")    ; name
2273          10 'font-lock-function-name-face)
2274    ;;
2275    ;; This is faster but not by much.  I don't see why not.
2276    ;(list (concat "^\\(" ctoken "\\)[ \t]*(") 1 'font-lock-function-name-face)
2277    ;;
2278    ;; Added next two; they're both jolly-good fastmatch candidates so
2279    ;; should be fast. --ben
2280    ;;
2281    ;; Fontify structure names (in structure definition form).
2282    (list (concat "^\\(typedef[ \t]+struct\\|struct\\|static[ \t]+struct\\)"
2283            "[ \t]+\\(" ctoken "\\)[ \t]*\\(\{\\|$\\)")
2284          2 'font-lock-function-name-face)
2285    ;;
2286    ;; Fontify case clauses.  This is fast because its anchored on the left.
2287    '("case[ \t]+\\(\\(\\sw\\|\\s_\\)+\\)[ \t]+:". 1)
2288    ;;
2289    '("\\<\\(default\\):". 1)
2290    ;; Fontify filenames in #include <...> preprocessor directives as strings.
2291    '("^#[ \t]*include[ \t]+\\(<[^>\"\n]+>\\)" 1 font-lock-string-face)
2292    ;;
2293    ;; Fontify function macro names.
2294    '("^#[ \t]*define[ \t]+\\(\\(\\sw+\\)(\\)" 2 font-lock-function-name-face)
2295    ;;
2296    ;; Fontify symbol names in #if ... defined preprocessor directives.
2297    '("^#[ \t]*if\\>"
2298      ("\\<\\(defined\\)\\>[ \t]*(?\\(\\sw+\\)?" nil nil
2299       (1 font-lock-preprocessor-face) (2 font-lock-variable-name-face nil t)))
2300    ;;
2301    ;; Fontify symbol names in #elif ... defined preprocessor directives.
2302    '("^#[ \t]*elif\\>"
2303      ("\\<\\(defined\\)\\>[ \t]*(?\\(\\sw+\\)?" nil nil
2304       (1 font-lock-preprocessor-face) (2 font-lock-variable-name-face nil t)))
2305    ;;
2306    ;; Fontify otherwise as symbol names, and the preprocessor directive names.
2307    '("^\\(#[ \t]*[a-z]+\\)\\>[ \t]*\\(\\sw+\\)?"
2308      (1 font-lock-preprocessor-face) (2 font-lock-variable-name-face nil t))
2309    ))
2310
2311  (setq c-font-lock-keywords-2
2312   (append c-font-lock-keywords-1
2313    (list
2314     ;;
2315     ;; Simple regexps for speed.
2316     ;;
2317     ;; Fontify all type specifiers.
2318     (cons (concat "\\<\\(" c-type-types "\\)\\>") 'font-lock-type-face)
2319     ;;
2320     ;; Fontify all builtin keywords (except case, default and goto; see below).
2321     (cons (concat "\\<\\(" c-keywords "\\)\\>") 'font-lock-keyword-face)
2322     ;;
2323     ;; Fontify case/goto keywords and targets, and case default/goto tags.
2324     '("\\<\\(case\\|goto\\)\\>[ \t]*\\([^ \t\n:;]+\\)?"
2325       (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
2326     '("^[ \t]*\\(\\sw+\\)[ \t]*:" 1 font-lock-reference-face)
2327     )))
2328
2329  (setq c-font-lock-keywords-3
2330   (append c-font-lock-keywords-2
2331    ;;
2332    ;; More complicated regexps for more complete highlighting for types.
2333    ;; We still have to fontify type specifiers individually, as C is so hairy.
2334    (list
2335     ;;
2336     ;; Fontify all storage classes and type specifiers, plus their items.
2337     (list (concat "\\<\\(" c-type-types "\\)\\>"
2338                   "\\([ \t*&]+\\sw+\\>\\)*")
2339           ;; Fontify each declaration item.
2340           '(font-lock-match-c++-style-declaration-item-and-skip-to-next
2341             ;; Start with point after all type specifiers.
2342             (goto-char (or (match-beginning 8) (match-end 1)))
2343             ;; Finish with point after first type specifier.
2344             (goto-char (match-end 1))
2345             ;; Fontify as a variable or function name.
2346             (1 (if (match-beginning 4)
2347                    font-lock-function-name-face
2348                  font-lock-variable-name-face))))
2349     ;;
2350     ;; Fontify structures, or typedef names, plus their items.
2351     '("\\(}\\)[ \t*]*\\sw"
2352       (font-lock-match-c++-style-declaration-item-and-skip-to-next
2353        (goto-char (match-end 1)) nil
2354        (1 (if (match-beginning 4)
2355               font-lock-function-name-face
2356             font-lock-variable-name-face))))
2357     ;;
2358     ;; Fontify anything at beginning of line as a declaration or definition.
2359     '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*"
2360       (1 font-lock-type-face)
2361       (font-lock-match-c++-style-declaration-item-and-skip-to-next
2362        (goto-char (or (match-beginning 2) (match-end 1))) nil
2363        (1 (if (match-beginning 4)
2364               font-lock-function-name-face
2365             font-lock-variable-name-face))))
2366     )))
2367
2368  (setq c++-font-lock-keywords-1
2369   (append
2370    ;;
2371    ;; The list `c-font-lock-keywords-1' less that for function names.
2372    ;; the simple function form regexp has been removed. --dmoore
2373    ;;(cdr c-font-lock-keywords-1)
2374    c-font-lock-keywords-1
2375    ;;
2376    ;; Fontify function name definitions, possibly incorporating class name.
2377    (list
2378     '("^\\(\\sw+\\)\\(::\\(\\sw+\\)\\)?[ \t]*("
2379       (1 (if (match-beginning 2)
2380              font-lock-type-face
2381            font-lock-function-name-face))
2382       (3 (if (match-beginning 2) font-lock-function-name-face) nil t))
2383     )))
2384
2385  (setq c++-font-lock-keywords-2
2386   (append c++-font-lock-keywords-1
2387    (list
2388     ;;
2389     ;; The list `c-font-lock-keywords-2' for C++ plus operator overloading.
2390     (cons (concat "\\<\\(" c++-type-types "\\)\\>") 'font-lock-type-face)
2391     ;;
2392     ;; Fontify operator function name overloading.
2393     '("\\<\\(operator\\)\\>[ \t]*\\([][)(><!=+-][][)(><!=+-]?\\)?"
2394       (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t))
2395     ;;
2396     ;; Fontify case/goto keywords and targets, and case default/goto tags.
2397     '("\\<\\(case\\|goto\\)\\>[ \t]*\\([^ \t\n:;]+\\)?"
2398       (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
2399     '("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-reference-face)
2400     ;;
2401     ;; Fontify other builtin keywords.
2402     (cons (concat "\\<\\(" c++-keywords "\\)\\>") 'font-lock-keyword-face)
2403     )))
2404
2405  (setq c++-font-lock-keywords-3
2406   (append c++-font-lock-keywords-2
2407    ;;
2408    ;; More complicated regexps for more complete highlighting for types.
2409    (list
2410     ;;
2411     ;; Fontify all storage classes and type specifiers, plus their items.
2412     (list (concat "\\<\\(" c++-type-types "\\)\\>"
2413                   "\\([ \t*&]+\\sw+\\>\\)*")
2414           ;; Fontify each declaration item.
2415           '(font-lock-match-c++-style-declaration-item-and-skip-to-next
2416             ;; Start with point after all type specifiers.
2417             (goto-char (or (match-beginning 13) (match-end 1)))
2418             ;; Finish with point after first type specifier.
2419             (goto-char (match-end 1))
2420             ;; Fontify as a variable or function name.
2421             (1 (cond ((match-beginning 2) 'font-lock-type-face)
2422                      ((match-beginning 4) 'font-lock-function-name-face)
2423                      (t 'font-lock-variable-name-face)))
2424             (3 (if (match-beginning 4)
2425                    'font-lock-function-name-face
2426                  'font-lock-variable-name-face) nil t)))
2427     ;;
2428     ;; Fontify structures, or typedef names, plus their items.
2429     '("\\(}\\)[ \t*]*\\sw"
2430       (font-lock-match-c++-style-declaration-item-and-skip-to-next
2431        (goto-char (match-end 1)) nil
2432        (1 (if (match-beginning 4)
2433               font-lock-function-name-face
2434             font-lock-variable-name-face))))
2435     ;;
2436     ;; Fontify anything at beginning of line as a declaration or definition.
2437     '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*"
2438       (1 font-lock-type-face)
2439       (font-lock-match-c++-style-declaration-item-and-skip-to-next
2440        (goto-char (or (match-beginning 2) (match-end 1))) nil
2441        (1 (cond ((match-beginning 2) 'font-lock-type-face)
2442                 ((match-beginning 4) 'font-lock-function-name-face)
2443                 (t 'font-lock-variable-name-face)))
2444        (3 (if (match-beginning 4)
2445               'font-lock-function-name-face
2446             'font-lock-variable-name-face) nil t)))
2447     )))
2448  )
2449
2450 (defvar c-font-lock-keywords c-font-lock-keywords-1
2451   "Default expressions to highlight in C mode.")
2452
2453 (defvar c++-font-lock-keywords c++-font-lock-keywords-1
2454   "Default expressions to highlight in C++ mode.")
2455 \f
2456 ;;; Java.
2457
2458 ;; Java support has been written by XEmacs people, and it's apparently
2459 ;; totally divergent from the FSF.  I don't know if it's better or
2460 ;; worse, so I'm leaving it in until someone convinces me the FSF
2461 ;; version is better.  --hniksic
2462
2463 (defconst java-font-lock-keywords-1 nil
2464  "For consideration as a value of `java-font-lock-keywords'.
2465 This does fairly subdued highlighting.")
2466
2467 (defconst java-font-lock-keywords-2 nil
2468  "For consideration as a value of `java-font-lock-keywords'.
2469 This adds highlighting of types and identifier names.")
2470
2471 (defconst java-font-lock-keywords-3 nil
2472  "For consideration as a value of `java-font-lock-keywords'.
2473 This adds highlighting of Java documentation tags, such as @see.")
2474
2475 (defvar java-font-lock-type-regexp
2476   (concat "\\<\\(boolean\\|byte\\|char\\|double\\|float\\|int"
2477          "\\|long\\|short\\|void\\)\\>")
2478   "Regexp which should match a primitive type.")
2479
2480 (defvar java-font-lock-identifier-regexp
2481   (let ((letter "a-zA-Z_$\300-\326\330-\366\370-\377")
2482         (digit  "0-9"))
2483     (concat "\\<\\([" letter "][" letter digit "]*\\)\\>"))
2484   "Regexp which should match all Java identifiers.")
2485
2486 (defvar java-font-lock-class-name-regexp
2487   (let ((capital-letter "A-Z\300-\326\330-\337")
2488         (letter "a-zA-Z_$\300-\326\330-\366\370-\377")
2489         (digit  "0-9"))
2490     (concat "\\<\\([" capital-letter "][" letter digit "]*\\)\\>"))
2491   "Regexp which should match a class or an interface name.
2492 The name is assumed to begin with a capital letter.")
2493
2494 (let ((java-modifier-regexp
2495        (concat "\\<\\(abstract\\|const\\|final\\|native\\|"
2496                "private\\|protected\\|public\\|"
2497                "static\\|synchronized\\|transient\\|volatile\\)\\>")))
2498
2499   ;; Basic font-lock support:
2500   (setq java-font-lock-keywords-1
2501         (list
2502          ;; Keywords:
2503          (list        
2504           (concat
2505            "\\<\\("
2506            "break\\|byvalue\\|"
2507            "case\\|cast\\|catch\\|class\\|continue\\|"
2508            "do\\|else\\|extends\\|"
2509            "finally\\|for\\|future\\|"
2510            "generic\\|goto\\|"
2511            "if\\|implements\\|import\\|"
2512            "instanceof\\|interface\\|"
2513            "new\\|package\\|return\\|switch\\|"
2514            "throws?\\|try\\|while\\)\\>")
2515           1 'font-lock-keyword-face)
2516
2517          ;; Modifiers:
2518          (list java-modifier-regexp 1 font-lock-type-face)
2519
2520          ;; Special constants:
2521          '("\\<\\(this\\|super\\)\\>" (1 font-lock-reference-face))
2522          '("\\<\\(false\\|null\\|true\\)\\>" (1 font-lock-keyword-face))
2523
2524          ;; Class names:
2525          (list (concat "\\<\\(class\\|interface\\)\\>\\s *"
2526                        java-font-lock-identifier-regexp)
2527                2 'font-lock-function-name-face)
2528         
2529          ;; Package declarations:
2530          (list (concat "\\<\\(package\\|import\\)\\>\\s *"
2531                        java-font-lock-identifier-regexp)
2532                '(2 font-lock-reference-face)
2533                (list (concat
2534                       "\\=\\.\\(" java-font-lock-identifier-regexp "\\)")
2535                      nil nil '(1 (if (equal (char-after (match-end 0)) ?.)
2536                                      'font-lock-reference-face
2537                                    'font-lock-type-face))))
2538          
2539          ;; Constructors:
2540          (list (concat
2541                 "^\\s *\\(" java-modifier-regexp "\\s +\\)*"
2542                 java-font-lock-class-name-regexp "\\s *\(")
2543                (list 3
2544                      '(condition-case nil
2545                           (save-excursion
2546                             (goto-char (scan-sexps (- (match-end 0) 1) 1))
2547                             (parse-partial-sexp (point) (point-max) nil t)
2548                             (and (looking-at "\\($\\|\\<throws\\>\\|{\\)")
2549                                  'font-lock-function-name-face))
2550                         (error 'font-lock-function-name-face))))
2551
2552          ;; Methods:
2553          (list (concat "\\(" java-font-lock-type-regexp "\\|"
2554                        java-font-lock-class-name-regexp "\\)"
2555                        "\\s *\\(\\[\\s *\\]\\s *\\)*"
2556                        java-font-lock-identifier-regexp "\\s *\(")
2557                5
2558                'font-lock-function-name-face)
2559
2560          ;; Labels:
2561          (list ":"
2562                (list
2563                 (concat "^\\s *" java-font-lock-identifier-regexp "\\s *:")
2564                 '(beginning-of-line) '(end-of-line)
2565                 '(1 font-lock-reference-face)))
2566
2567          ;; `break' and continue' destination labels:
2568          (list (concat "\\<\\(break\\|continue\\)\\>\\s *"
2569                        java-font-lock-identifier-regexp)
2570                2 'font-lock-reference-face)
2571
2572          ;; Case statements:
2573          ;; In Java, any constant expression is allowed.
2574          '("\\<case\\>\\s *\\(.*\\):" 1 font-lock-reference-face)))
2575
2576   ;; Types and declared variable names:
2577   (setq java-font-lock-keywords-2
2578         (append 
2579
2580          java-font-lock-keywords-1
2581          (list
2582           ;; Keywords followed by a type:
2583           (list (concat "\\<\\(extends\\|instanceof\\|new\\)\\>\\s *"
2584                         java-font-lock-identifier-regexp)
2585                 '(2 (if (equal (char-after (match-end 0)) ?.)
2586                         'font-lock-reference-face 'font-lock-type-face))
2587                 (list (concat "\\=\\." java-font-lock-identifier-regexp)
2588                       '(goto-char (match-end 0)) nil
2589                       '(1 (if (equal (char-after (match-end 0)) ?.)
2590                               'font-lock-reference-face 'font-lock-type-face))))
2591
2592           ;; Keywords followed by a type list:
2593           (list (concat "\\<\\(implements\\|throws\\)\\>\\ s*"
2594                         java-font-lock-identifier-regexp)
2595                 '(2 (if (equal (char-after (match-end 0)) ?.)
2596                         font-lock-reference-face font-lock-type-face))
2597                 (list (concat "\\=\\(\\.\\|\\s *\\(,\\)\\s *\\)"
2598                               java-font-lock-identifier-regexp)
2599                       '(goto-char (match-end 0)) nil
2600                       '(3 (if (equal (char-after (match-end 0)) ?.)
2601                               font-lock-reference-face font-lock-type-face))))
2602
2603           ;; primitive types, can't be confused with anything else.
2604           (list java-font-lock-type-regexp
2605                 '(1 font-lock-type-face)
2606                 '(font-lock-match-java-declarations
2607                   (goto-char (match-end 0))
2608                   (goto-char (match-end 0))
2609                   (0 font-lock-variable-name-face)))
2610
2611           ;; Declarations, class types and capitalized variables:
2612           ;;
2613           ;; Declarations are easy to recognize.  Capitalized words
2614           ;; followed by a closing parenthesis are treated as casts if they
2615           ;; also are followed by an expression.  Expressions beginning with
2616           ;; a unary numerical operator, e.g. +, can't be cast to an object
2617           ;; type.
2618           ;;
2619           ;; The path of a fully qualified type, e.g. java.lang.Foo, is
2620           ;; fontified in the reference face.
2621           ;;
2622           ;; An access to a static field, e.g. System.out.println, is
2623           ;; not fontified since it can't be distinguished from the
2624           ;; usage of a capitalized variable, e.g. Foo.out.println.
2625
2626           (list (concat java-font-lock-class-name-regexp
2627                         "\\s *\\(\\[\\s *\\]\\s *\\)*"
2628                         "\\(\\<\\|$\\|)\\s *\\([\(\"]\\|\\<\\)\\)")
2629                 '(1 (save-match-data
2630                       (save-excursion
2631                         (goto-char
2632                          (match-beginning 3))
2633                         (if (not (looking-at "\\<instanceof\\>"))
2634                             'font-lock-type-face))))
2635                 (list (concat "\\=" java-font-lock-identifier-regexp "\\.")
2636                       '(progn
2637                          (goto-char (match-beginning 0))
2638                          (while (or (= (preceding-char) ?.)
2639                                     (= (char-syntax (preceding-char)) ?w))
2640                            (backward-char)))
2641                       '(goto-char (match-end 0))
2642                       '(1 font-lock-reference-face)
2643                       '(0 nil))         ; Workaround for bug in XEmacs.
2644                 '(font-lock-match-java-declarations
2645                   (goto-char (match-end 1))
2646                   (goto-char (match-end 0))
2647                   (1 font-lock-variable-name-face))))))
2648         
2649   ;; Modifier keywords and Java doc tags
2650   (setq java-font-lock-keywords-3
2651         (append
2652  
2653          '(
2654            ;; Feature scoping:
2655            ;; These must come first or the Modifiers from keywords-1 will
2656            ;; catch them.  We don't want to use override fontification here
2657            ;; because then these terms will be fontified within comments.
2658            ("\\<private\\>"   0 font-lock-string-face)
2659            ("\\<protected\\>" 0 font-lock-preprocessor-face)
2660            ("\\<public\\>"    0 font-lock-reference-face))
2661          java-font-lock-keywords-2
2662  
2663          (list
2664
2665           ;; Javadoc tags
2666           '("@\\(author\\|deprecated\\|exception\\|throws\\|param\\|return\\|see\\|since\\|version\\|serial\\|serialData\\|serialField\\)\\s "
2667             0 font-lock-keyword-face t)
2668
2669           ;; Doc tag - Parameter identifiers
2670           (list (concat "@param\\s +" java-font-lock-identifier-regexp)
2671                 1 'font-lock-variable-name-face t)
2672
2673           ;; Doc tag - Exception types
2674           (list (concat "@\\(exception\\|throws\\)\\s +"
2675                         java-font-lock-identifier-regexp)
2676                 '(2 (if (equal (char-after (match-end 0)) ?.)
2677                         font-lock-reference-face font-lock-type-face) t)
2678                 (list (concat "\\=\\." java-font-lock-identifier-regexp)
2679                       '(goto-char (match-end 0)) nil
2680                       '(1 (if (equal (char-after (match-end 0)) ?.)
2681                               'font-lock-reference-face 'font-lock-type-face) t)))
2682     
2683           ;; Doc tag - Cross-references, usually to methods 
2684           '("@see\\s +\\(\\S *[^][ \t\n\r\f(){},.;:]\\)"
2685             1 font-lock-function-name-face t)
2686     
2687           ;; Doc tag - docRoot (1.3)
2688           '("\\({ *@docRoot *}\\)"
2689             0 font-lock-keyword-face t)
2690           ;; Doc tag - beaninfo, unofficial but widely used, even by Sun
2691           '("\\(@beaninfo\\)"
2692             0 font-lock-keyword-face t)
2693           ;; Doc tag - Links
2694           '("{ *@link\\s +\\([^}]+\\)}"
2695             0 font-lock-keyword-face t)
2696           ;; Doc tag - Links
2697           '("{ *@link\\s +\\(\\(\\S +\\)\\|\\(\\S +\\s +\\S +\\)\\) *}"
2698             1 font-lock-function-name-face t)
2699     
2700           )))
2701   )
2702
2703 (defvar java-font-lock-keywords java-font-lock-keywords-1
2704   "Additional expressions to highlight in Java mode.")
2705
2706 ;; Match and move over any declaration/definition item after
2707 ;; point.  Does not match items which look like a type declaration
2708 ;; (primitive types and class names, i.e. capitalized words.)
2709 ;; Should the variable name be followed by a comma, we reposition
2710 ;; the cursor to fontify more identifiers.
2711 (defun font-lock-match-java-declarations (limit)
2712   "Match and skip over variable definitions."
2713   (save-restriction
2714     (narrow-to-region (point-min) limit)
2715
2716     (if (looking-at "\\s *\\(\\[\\s *\\]\\s *\\)*")
2717         (goto-char (match-end 0)))
2718     (and
2719      (looking-at java-font-lock-identifier-regexp)
2720      (save-match-data
2721        (not (string-match java-font-lock-type-regexp
2722                           (buffer-substring (match-beginning 1)
2723                                             (match-end 1)))))
2724      (save-match-data
2725        (save-excursion
2726          (goto-char (match-beginning 1))
2727          (not (looking-at
2728                (concat java-font-lock-class-name-regexp
2729                        "\\s *\\(\\[\\s *\\]\\s *\\)*\\<")))))
2730      (save-match-data
2731        (condition-case nil
2732            (progn
2733              (goto-char (match-end 0))
2734              ;; Note: Both `scan-sexps' and the second goto-char can
2735              ;; generate an error which is caught by the
2736              ;; `condition-case' expression.
2737              (while (not (looking-at "\\s *\\(\\(,\\)\\|;\\|$\\)"))
2738                (goto-char (or (scan-sexps (point) 1) (point-max))))
2739              (goto-char (match-end 2)))   ; non-nil
2740          (error t))))))
2741
2742
2743 (defvar tex-font-lock-keywords
2744 ;  ;; Regexps updated with help from Ulrik Dickow <dickow@nbi.dk>.
2745 ;  '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}"
2746 ;     2 font-lock-function-name-face)
2747 ;    ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}"
2748 ;     2 font-lock-reference-face)
2749 ;    ;; It seems a bit dubious to use `bold' and `italic' faces since we might
2750 ;    ;; not be able to display those fonts.
2751 ;    ("{\\\\bf\\([^}]+\\)}" 1 'bold keep)
2752 ;    ("{\\\\\\(em\\|it\\|sl\\)\\([^}]+\\)}" 2 'italic keep)
2753 ;    ("\\\\\\([a-zA-Z@]+\\|.\\)" . font-lock-keyword-face)
2754 ;    ("^[ \t\n]*\\\\def[\\\\@]\\(\\w+\\)" 1 font-lock-function-name-face keep))
2755   ;; Rewritten and extended for LaTeX2e by Ulrik Dickow <dickow@nbi.dk>.
2756   '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}"
2757      2 font-lock-function-name-face)
2758     ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}"
2759      2 font-lock-reference-face)
2760     ("^[ \t]*\\\\def\\\\\\(\\(\\w\\|@\\)+\\)" 1 font-lock-function-name-face)
2761     "\\\\\\([a-zA-Z@]+\\|.\\)"
2762     ;; It seems a bit dubious to use `bold' and `italic' faces since we might
2763     ;; not be able to display those fonts.
2764     ;; LaTeX2e: \emph{This is emphasized}.
2765     ("\\\\emph{\\([^}]+\\)}" 1 'italic keep)
2766     ;; LaTeX2e: \textbf{This is bold}, \textit{...}, \textsl{...}
2767     ("\\\\text\\(\\(bf\\)\\|it\\|sl\\){\\([^}]+\\)}"
2768      3 (if (match-beginning 2) 'bold 'italic) keep)
2769     ;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for good tables.
2770     ("\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)"
2771      3 (if (match-beginning 2) 'bold 'italic) keep))
2772   "Default expressions to highlight in TeX modes.")
2773
2774 (defconst ksh-font-lock-keywords 
2775   (list
2776    '("\\(^\\|[^\$\\\]\\)#.*" . font-lock-comment-face)
2777    '("\\<\\(if\\|then\\|else\\|elif\\|fi\\|case\\|esac\\|for\\|do\\|done\\|foreach\\|in\\|end\\|select\\|while\\|repeat\\|time\\|function\\|until\\|exec\\|command\\|coproc\\|noglob\\|nohup\\|nocorrect\\|source\\|autoload\\|alias\\|unalias\\|export\\|set\\|echo\\|eval\\|cd\\|log\\|compctl\\)\\>" . font-lock-keyword-face)
2778    '("\\<\\[\\[.*\\]\\]\\>" . font-lock-type-face)
2779    '("\$\(.*\)" . font-lock-type-face)
2780    )
2781   "Additional expressions to highlight in ksh-mode.")
2782
2783 (defconst sh-font-lock-keywords 
2784   (list
2785    '("\\(^\\|[^\$\\\]\\)#.*" . font-lock-comment-face)
2786    '("\\<\\(if\\|then\\|else\\|elif\\|fi\\|case\\|esac\\|for\\|do\\|done\\|in\\|while\\|exec\\|export\\|set\\|echo\\|eval\\|cd\\)\\>" . font-lock-keyword-face)
2787    '("\\[.*\\]" . font-lock-type-face)
2788    '("`.*`" . font-lock-type-face)
2789    )
2790   "Additional expressions to highlight in sh-mode.")
2791
2792 \f
2793 ;; Install ourselves:
2794
2795 (add-hook 'find-file-hooks 'font-lock-set-defaults t)
2796
2797 ;;;###autoload
2798 (add-minor-mode 'font-lock-mode " Font")
2799
2800 ;; Provide ourselves:
2801
2802 (provide 'font-lock)
2803
2804 ;;; font-lock.el ends here