comparison lisp/packages/font-lock.el @ 0:376386a54a3c r19-14

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