comparison lisp/font-lock.el @ 217:d44af0c54775 r20-4b7

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