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