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