Make sure shell-cd sets list-buffers-directory to a directory ending with `/'.
[bpt/emacs.git] / lisp / font-lock.el
CommitLineData
030f4a35 1;; Electric Font Lock Mode
d733c5ec 2;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
030f4a35 3
a1eb1cf1 4;; Author: jwz, then rms and sm (simon.marshall@mail.esrin.esa.it)
030f4a35
RS
5;; Maintainer: FSF
6;; Keywords: languages, faces
7
8;; This file is part of GNU Emacs.
9
10;; GNU Emacs is free software; you can redistribute it and/or modify
11;; it under the terms of the GNU General Public License as published by
12;; the Free Software Foundation; either version 2, or (at your option)
13;; any later version.
14
15;; GNU Emacs is distributed in the hope that it will be useful,
16;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18;; GNU General Public License for more details.
19
20;; You should have received a copy of the GNU General Public License
21;; along with GNU Emacs; see the file COPYING. If not, write to
22;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
23
24
25;;; Commentary:
26
b89e1134
SM
27;; Font Lock mode is a minor mode that causes your comments to be displayed in
28;; one face, strings in another, reserved words in another, and so on.
030f4a35
RS
29;;
30;; Comments will be displayed in `font-lock-comment-face'.
31;; Strings will be displayed in `font-lock-string-face'.
a1eb1cf1 32;; Regexps are used to display selected patterns in other faces.
030f4a35
RS
33;;
34;; To make the text you type be fontified, use M-x font-lock-mode.
b89e1134 35;; When this minor mode is on, the faces of the current line are
030f4a35
RS
36;; updated with every insertion or deletion.
37;;
b89e1134 38;; To turn Font Lock mode on automatically, add this to your .emacs file:
030f4a35 39;;
b89e1134 40;; (add-hook 'emacs-lisp-mode-hook 'turn-on-font-lock)
030f4a35 41;;
b89e1134 42;; On a Sparc2, `font-lock-fontify-buffer' takes about 10 seconds for a 120k
a1eb1cf1
RS
43;; file of C code using the default configuration, and about 25 seconds using
44;; the more extensive configuration, though times also depend on file contents.
45;; You can speed this up substantially by removing some of the patterns that
46;; are highlighted by default. Fontifying Lisp code is significantly faster,
47;; because Lisp has a more regular syntax than C, so the expressions don't have
48;; to be as hairy.
49;;
b89e1134
SM
50;; If you add patterns for a new mode, say foo.el's `foo-mode', say in which
51;; you don't want syntactic fontification to occur, you can make Font Lock mode
52;; use your regexps when turning on Font Lock by adding to `foo-mode-hook':
53;;
54;; (add-hook 'foo-mode-hook
55;; '(lambda () (make-local-variable 'font-lock-defaults)
56;; (setq font-lock-defaults '(foo-font-lock-keywords t))))
57;;
a1eb1cf1
RS
58;; Nasty regexps of the form "bar\\(\\|lo\\)\\|f\\(oo\\|u\\(\\|bar\\)\\)\\|lo"
59;; are made thusly: (make-regexp '("foo" "fu" "fubar" "bar" "barlo" "lo")) for
60;; efficiency. See /pub/gnu/emacs/elisp-archive/functions/make-regexp.el.Z on
61;; archive.cis.ohio-state.edu for this and other functions.
62\f
030f4a35
RS
63;;; Code:
64
a1eb1cf1
RS
65(defvar font-lock-comment-face 'font-lock-comment-face
66 "Face to use for comments.")
030f4a35 67
a1eb1cf1
RS
68(defvar font-lock-string-face 'font-lock-string-face
69 "Face to use for strings.")
030f4a35 70
a1eb1cf1 71(defvar font-lock-function-name-face 'font-lock-function-name-face
030f4a35
RS
72 "Face to use for function names.")
73
a1eb1cf1
RS
74(defvar font-lock-variable-name-face 'font-lock-variable-name-face
75 "Face to use for variable names.")
76
77(defvar font-lock-keyword-face 'font-lock-keyword-face
030f4a35
RS
78 "Face to use for keywords.")
79
a1eb1cf1 80(defvar font-lock-type-face 'font-lock-type-face
030f4a35
RS
81 "Face to use for data types.")
82
a1eb1cf1
RS
83(defvar font-lock-reference-face 'font-lock-reference-face
84 "Face to use for references.")
85
8f261d40 86(defvar font-lock-no-comments nil
b89e1134 87 "Non-nil means Font Lock should not fontify comments or strings.")
8f261d40 88
030f4a35
RS
89(make-variable-buffer-local 'font-lock-keywords)
90(defvar font-lock-keywords nil
91 "*The keywords to highlight.
a1eb1cf1
RS
92Elements should be of the form:
93
94 REGEXP
95 (REGEXP . MATCH)
96 (REGEXP . FACENAME)
97 (REGEXP . HIGHLIGHT)
98 (REGEXP HIGHLIGHT ...)
99
100where HIGHLIGHT should be of the form (MATCH FACENAME OVERRIDE LAXMATCH).
101REGEXP is the regexp to search for, MATCH is the subexpression of REGEXP to be
102highlighted, FACENAME is an expression whose value is the face name to use.
103FACENAME's default attributes may be defined in `font-lock-face-attributes'.
104
105OVERRIDE and LAXMATCH are flags. If OVERRIDE is t, existing fontification may
106be overriden. If `keep', only parts not already fontified are highlighted.
107If LAXMATCH is non-nil, no error is signalled if there is no MATCH in REGEXP.
108
109These regular expressions should not match text which spans lines. While
110\\[font-lock-fontify-buffer] handles multi-line patterns correctly, updating
111when you edit the buffer does not, since it considers text one line at a time.
112
113Be careful composing regexps for this list;
114the wrong pattern can dramatically slow things down!")
030f4a35 115
b89e1134
SM
116(defvar font-lock-defaults nil
117 "If set by a major mode, should be the defaults for Font Lock mode.
118The value should look like the `cdr' of an item in `font-lock-defaults-alist'.")
119
120(defvar font-lock-defaults-alist
121 '((bibtex-mode . (tex-font-lock-keywords))
122 (c++-c-mode . (c-font-lock-keywords nil nil ((?\_ . "w"))))
123 (c++-mode . (c++-font-lock-keywords nil nil ((?\_ . "w"))))
124 (c-mode . (c-font-lock-keywords nil nil ((?\_ . "w"))))
125 (emacs-lisp-mode . (lisp-font-lock-keywords))
126 (latex-mode . (tex-font-lock-keywords))
127 (lisp-mode . (lisp-font-lock-keywords))
128 (plain-tex-mode . (tex-font-lock-keywords))
5c06a8eb 129 (scheme-mode . (lisp-font-lock-keywords))
b89e1134
SM
130 (slitex-mode . (tex-font-lock-keywords))
131 (tex-mode . (tex-font-lock-keywords)))
132 "*Alist of default major mode and Font Lock defaults.
133Each item should be a list of the form:
134 (MAJOR-MODE . (FONT-LOCK-KEYWORDS KEYWORDS-ONLY CASE-FOLD FONT-LOCK-SYNTAX))
135where both MAJOR-MODE and FONT-LOCK-KEYWORDS are symbols. If KEYWORDS-ONLY is
136non-nil, syntactic fontification (strings and comments) is not performed.
137If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
138FONT-LOCK-SYNTAX should be a list of cons pairs of the form (CHAR . STRING), it
139is used to set the local Font Lock syntax table for keyword fontification.")
140
141(defvar font-lock-maximum-size (* 100 1024)
142 "*If non-nil, the maximum size for buffers.
143Only buffers less than are fontified when Font Lock mode is turned on.
144If nil, means size is irrelevant.")
145
030f4a35
RS
146(defvar font-lock-keywords-case-fold-search nil
147 "*Non-nil means the patterns in `font-lock-keywords' are case-insensitive.")
148
b056da51
RS
149(defvar font-lock-syntax-table nil
150 "*Non-nil means use this syntax table for fontifying.
151If this is nil, the major mode's syntax table is used.")
152
030f4a35
RS
153(defvar font-lock-verbose t
154 "*Non-nil means `font-lock-fontify-buffer' should print status messages.")
155
60b691e2 156;;;###autoload
030f4a35
RS
157(defvar font-lock-mode-hook nil
158 "Function or functions to run on entry to Font Lock mode.")
a1eb1cf1
RS
159\f
160;; Colour etc. support.
161
b89e1134 162(defvar font-lock-display-type nil
a1eb1cf1
RS
163 "A symbol indicating the display Emacs is running under.
164The symbol should be one of `color', `grayscale' or `mono'.
165If Emacs guesses this display attribute wrongly, either set this variable in
b89e1134 166your `~/.emacs' or set the resource `Emacs.displayType' in your `~/.Xdefaults'.
a1eb1cf1
RS
167See also `font-lock-background-mode' and `font-lock-face-attributes'.")
168
b89e1134 169(defvar font-lock-background-mode nil
a1eb1cf1
RS
170 "A symbol indicating the Emacs background brightness.
171The symbol should be one of `light' or `dark'.
172If Emacs guesses this frame attribute wrongly, either set this variable in
b89e1134
SM
173your `~/.emacs' or set the resource `Emacs.backgroundMode' in your
174`~/.Xdefaults'.
a1eb1cf1
RS
175See also `font-lock-display-type' and `font-lock-face-attributes'.")
176
b89e1134 177(defvar font-lock-face-attributes nil
a1eb1cf1
RS
178 "A list of default attributes to use for face attributes.
179Each element of the list should be of the form
180
181 (FACE FOREGROUND BACKGROUND BOLD-P ITALIC-P UNDERLINE-P)
182
183where FACE should be one of the face symbols `font-lock-comment-face',
184`font-lock-string-face', `font-lock-keyword-face', `font-lock-type-face',
185`font-lock-function-name-face', `font-lock-variable-name-face', and
186`font-lock-reference-face'. A form for each of these face symbols should be
187provided in the list, but other face symbols and attributes may be given and
188used in highlighting. See `font-lock-keywords'.
189
190Subsequent element items should be the attributes for the corresponding
191Font Lock mode faces. Attributes FOREGROUND and BACKGROUND should be strings
192\(default if nil), while BOLD-P, ITALIC-P, and UNDERLINE-P should specify the
193corresponding face attributes (yes if non-nil).
194
195Emacs uses default attributes based on display type and background brightness.
196See variables `font-lock-display-type' and `font-lock-background-mode'.
197
198Resources can be used to over-ride these face attributes. For example, the
199resource `Emacs.font-lock-comment-face.attributeUnderline' can be used to
200specify the UNDERLINE-P attribute for face `font-lock-comment-face'.")
201
b89e1134
SM
202(defun font-lock-make-faces ()
203 "Make faces from `font-lock-face-attributes'.
204A default list is used if this is nil.
205See `font-lock-make-face' and `list-faces-display'."
206 ;; We don't need to `setq' any of these variables, but the user can see what
207 ;; is being used if we do.
208 (if (null font-lock-display-type)
209 (setq font-lock-display-type
210 (let ((display-resource (x-get-resource ".displayType"
211 "DisplayType")))
212 (cond (display-resource (intern (downcase display-resource)))
213 ((x-display-color-p) 'color)
214 ((x-display-grayscale-p) 'grayscale)
215 (t 'mono)))))
216 (if (null font-lock-background-mode)
217 (setq font-lock-background-mode
218 (let ((bg-resource (x-get-resource ".backgroundMode"
219 "BackgroundMode"))
220 (params (frame-parameters)))
221 (cond (bg-resource (intern (downcase bg-resource)))
222 ((or (string-equal "white"
223 (downcase (cdr (assq 'foreground-color params))))
224 (string-equal "black"
225 (downcase (cdr (assq 'background-color params)))))
226 'dark)
227 (t 'light)))))
228 (if (null font-lock-face-attributes)
229 (setq font-lock-face-attributes
230 (let ((light-bg (eq font-lock-background-mode 'light)))
231 (cond ((memq font-lock-display-type '(mono monochrome))
232 ;; Emacs 19.25's font-lock defaults:
233 ;;'((font-lock-comment-face nil nil nil t nil)
234 ;; (font-lock-string-face nil nil nil nil t)
235 ;; (font-lock-keyword-face nil nil t nil nil)
236 ;; (font-lock-function-name-face nil nil t t nil)
237 ;; (font-lock-type-face nil nil nil t nil))
238 (list '(font-lock-comment-face nil nil t t nil)
239 '(font-lock-string-face nil nil nil t nil)
240 '(font-lock-keyword-face nil nil t nil nil)
241 (list
242 'font-lock-function-name-face
243 (cdr (assq 'background-color (frame-parameters)))
244 (cdr (assq 'foreground-color (frame-parameters)))
245 t nil nil)
246 '(font-lock-variable-name-face nil nil t t nil)
247 '(font-lock-type-face nil nil t nil t)
248 '(font-lock-reference-face nil nil t nil t)))
249 ((memq font-lock-display-type '(grayscale greyscale
250 grayshade greyshade))
251 (list
252 (list 'font-lock-comment-face
253 (if light-bg "DimGray" "Gray80") nil t t nil)
254 (list 'font-lock-string-face
255 (if light-bg "Gray50" "LightGray") nil nil t nil)
256 (list 'font-lock-keyword-face
257 (if light-bg "DimGray" "Gray90") nil t nil nil)
258 (list 'font-lock-function-name-face
259 (cdr (assq 'background-color (frame-parameters)))
260 (cdr (assq 'foreground-color (frame-parameters)))
261 t nil nil)
262 (list 'font-lock-variable-name-face
263 (if light-bg "DimGray" "Gray90") nil t t nil)
264 (list 'font-lock-type-face
0caef3e3
SM
265 (if light-bg "DimGray" "Gray80") nil t nil t)
266 (list 'font-lock-reference-face
267 (if light-bg "Gray50" "LightGray") nil t nil t)))
b89e1134
SM
268 (light-bg ; light colour background
269 '((font-lock-comment-face "Firebrick")
270 (font-lock-string-face "RosyBrown")
271 (font-lock-keyword-face "Purple")
272 (font-lock-function-name-face "Blue")
273 (font-lock-variable-name-face "DarkGoldenrod")
274 (font-lock-type-face "DarkOliveGreen")
275 (font-lock-reference-face "CadetBlue")))
276 (t ; dark colour background
277 '((font-lock-comment-face "OrangeRed")
278 (font-lock-string-face "LightSalmon")
279 (font-lock-keyword-face "LightSteelBlue")
280 (font-lock-function-name-face "LightSkyBlue")
281 (font-lock-variable-name-face "LightGoldenrod")
282 (font-lock-type-face "PaleGreen")
283 (font-lock-reference-face "Aquamarine")))))))
284 (mapcar 'font-lock-make-face font-lock-face-attributes))
285
a1eb1cf1
RS
286(defun font-lock-make-face (face-attributes)
287 "Make a face from FACE-ATTRIBUTES.
288FACE-ATTRIBUTES should be like an element `font-lock-face-attributes', so that
289the face name is the first item in the list. A variable with the same name as
290the face is also set; its value is the face name."
291 (let* ((face (nth 0 face-attributes))
292 (face-name (symbol-name face))
293 (set-p (function (lambda (face-name resource)
294 (x-get-resource (concat face-name ".attribute" resource)
295 (concat "Face.Attribute" resource)))))
296 (on-p (function (lambda (face-name resource)
297 (let ((set (funcall set-p face-name resource)))
298 (and set (member (downcase set) '("on" "true"))))))))
299 (make-face face)
300 ;; Set attributes not set from X resources (and therefore `make-face').
301 (or (funcall set-p face-name "Foreground")
302 (condition-case nil
303 (set-face-foreground face (nth 1 face-attributes))
304 (error nil)))
305 (or (funcall set-p face-name "Background")
306 (condition-case nil
307 (set-face-background face (nth 2 face-attributes))
308 (error nil)))
309 (if (funcall set-p face-name "Bold")
310 (and (funcall on-p face-name "Bold") (make-face-bold face nil t))
311 (and (nth 3 face-attributes) (make-face-bold face nil t)))
312 (if (funcall set-p face-name "Italic")
313 (and (funcall on-p face-name "Italic") (make-face-italic face nil t))
314 (and (nth 4 face-attributes) (make-face-italic face nil t)))
315 (or (funcall set-p face-name "Underline")
316 (set-face-underline-p face (nth 5 face-attributes)))
317 (set face face)))
318\f
319;; Fontification.
030f4a35 320
a1eb1cf1
RS
321;; These variables record, for each buffer, the parse state at a particular
322;; position, always the start of a line. Used to make font-lock-fontify-region
323;; faster.
030f4a35
RS
324(defvar font-lock-cache-position nil)
325(defvar font-lock-cache-state nil)
326(make-variable-buffer-local 'font-lock-cache-position)
327(make-variable-buffer-local 'font-lock-cache-state)
328
a1eb1cf1 329(defun font-lock-fontify-region (start end &optional loudly)
030f4a35
RS
330 "Put proper face on each string and comment between START and END."
331 (save-excursion
a1eb1cf1
RS
332 (save-restriction
333 (widen)
334 (goto-char start)
335 (beginning-of-line)
336 (if loudly (message "Fontifying %s... (syntactically...)" (buffer-name)))
3de76c48
RS
337 (let ((inhibit-read-only t)
338 ;; Prevent warnings if the disk file has been altered.
339 (buffer-file-name)
e547d71e
RS
340 ;; Suppress all undo activity.
341 (buffer-undo-list t)
a1eb1cf1
RS
342 (modified (buffer-modified-p))
343 (cstart (if comment-start-skip
344 (concat "\\s\"\\|" comment-start-skip)
345 "\\s\""))
346 (cend (if comment-end
c9ed66f4
RS
347 (concat "\\s>\\|"
348 (regexp-quote
349 ;; Discard leading spaces from comment-end.
350 ;; In C mode, it is " */"
351 ;; and we don't want to fail to notice a */
352 ;; just because there's no space there.
2f12628e
SM
353 (save-match-data
354 (if (string-match "^ +" comment-end)
355 (substring comment-end (match-end 0))
356 comment-end))))
a1eb1cf1
RS
357 "\\s>"))
358 (startline (point))
359 state prev prevstate)
360 ;; Find the state at the line-beginning before START.
b89e1134 361 (if (eq startline font-lock-cache-position)
a1eb1cf1
RS
362 (setq state font-lock-cache-state)
363 ;; Find outermost containing sexp.
364 (beginning-of-defun)
365 ;; Find the state at STARTLINE.
366 (while (< (point) startline)
367 (setq state (parse-partial-sexp (point) startline 0)))
368 (setq font-lock-cache-state state
369 font-lock-cache-position (point)))
370 ;; Now find the state precisely at START.
371 (setq state (parse-partial-sexp (point) start nil nil state))
372 ;; If the region starts inside a string, show the extent of it.
373 (if (nth 3 state)
374 (let ((beg (point)))
375 (while (and (re-search-forward "\\s\"" end 'move)
b89e1134
SM
376 (nth 3 (parse-partial-sexp beg (point) nil nil
377 state))))
a1eb1cf1
RS
378 (put-text-property beg (point) 'face font-lock-string-face)
379 (setq state (parse-partial-sexp beg (point) nil nil state))))
380 ;; Likewise for a comment.
381 (if (or (nth 4 state) (nth 7 state))
382 (let ((beg (point)))
383 (while (and (re-search-forward cend end 'move)
b89e1134
SM
384 (nth 3 (parse-partial-sexp beg (point) nil nil
385 state))))
a1eb1cf1
RS
386 (put-text-property beg (point) 'face font-lock-comment-face)
387 (setq state (parse-partial-sexp beg (point) nil nil state))))
388 ;; Find each interesting place between here and END.
389 (while (and (< (point) end)
390 (setq prev (point) prevstate state)
391 (re-search-forward cstart end t)
392 (progn
393 ;; Clear out the fonts of what we skip over.
394 (remove-text-properties prev (point) '(face nil))
395 ;; Verify the state at that place
396 ;; so we don't get fooled by \" or \;.
b89e1134
SM
397 (setq state (parse-partial-sexp prev (point) nil nil
398 state))))
a1eb1cf1
RS
399 (let ((here (point)))
400 (if (or (nth 4 state) (nth 7 state))
401 ;; We found a real comment start.
030f4a35 402 (let ((beg (match-beginning 0)))
a1eb1cf1
RS
403 (goto-char beg)
404 (save-restriction
405 (narrow-to-region (point-min) end)
406 (condition-case nil
407 (progn
408 (forward-comment 1)
409 ;; forward-comment skips all whitespace,
410 ;; so go back to the real end of the comment.
411 (skip-chars-backward " \t"))
412 (error (goto-char end))))
413 (put-text-property beg (point) 'face font-lock-comment-face)
414 (setq state (parse-partial-sexp here (point) nil nil state)))
415 (if (nth 3 state)
416 (let ((beg (match-beginning 0)))
417 (while (and (re-search-forward "\\s\"" end 'move)
b89e1134
SM
418 (nth 3 (parse-partial-sexp here (point) nil nil
419 state))))
a1eb1cf1 420 (put-text-property beg (point) 'face font-lock-string-face)
b89e1134
SM
421 (setq state (parse-partial-sexp here (point) nil nil
422 state))))))
a1eb1cf1
RS
423 ;; Make sure PREV is non-nil after the loop
424 ;; only if it was set on the very last iteration.
425 (setq prev nil))
426 (and prev
427 (remove-text-properties prev end '(face nil)))
428 (and (buffer-modified-p)
429 (not modified)
430 (set-buffer-modified-p nil))))))
030f4a35
RS
431
432;; This code used to be used to show a string on reaching the end of it.
433;; It is probably not needed due to later changes to handle strings
434;; starting before the region in question.
435;; (if (and (null (nth 3 state))
436;; (eq (char-syntax (preceding-char)) ?\")
437;; (save-excursion
438;; (nth 3 (parse-partial-sexp prev (1- (point))
439;; nil nil prevstate))))
440;; ;; We found the end of a string.
441;; (save-excursion
442;; (setq foo2 (point))
443;; (let ((ept (point)))
444;; (forward-sexp -1)
445;; ;; Highlight the string when we see the end.
446;; ;; Doing it at the start leads to trouble:
447;; ;; either it fails to handle multiline strings
448;; ;; or it can run away when an unmatched " is inserted.
449;; (put-text-property (point) ept 'face
450;; (if (= (car state) 1)
451;; font-lock-doc-string-face
452;; font-lock-string-face)))))
453
454(defun font-lock-unfontify-region (beg end)
313d590c 455 (let ((modified (buffer-modified-p))
e547d71e 456 (buffer-undo-list t)
3de76c48
RS
457 (inhibit-read-only t)
458 ;; Prevent warnings if the disk file has been altered.
459 (buffer-file-name))
313d590c
RS
460 (remove-text-properties beg end '(face nil))
461 (set-buffer-modified-p modified)))
030f4a35
RS
462
463;; Called when any modification is made to buffer text.
464(defun font-lock-after-change-function (beg end old-len)
465 (save-excursion
466 (save-match-data
030f4a35
RS
467 ;; Discard the cache info if text before it has changed.
468 (and font-lock-cache-position
469 (> font-lock-cache-position beg)
470 (setq font-lock-cache-position nil))
a1eb1cf1 471 ;; Rescan between start of line from `beg' and start of line after `end'.
030f4a35
RS
472 (goto-char beg)
473 (beginning-of-line)
474 (setq beg (point))
a1eb1cf1
RS
475 (goto-char end)
476 (forward-line 1)
477 (setq end (point))
1ec9e15b
RS
478 ;; First scan for strings and comments.
479 ;; Must scan from line start in case of
a1eb1cf1 480 ;; inserting space into `intfoo () {}', and after widened.
8f261d40 481 (if font-lock-no-comments
a1eb1cf1
RS
482 (remove-text-properties beg end '(face nil))
483 (font-lock-fontify-region beg end))
9e116f87
SM
484 (font-lock-hack-keywords beg end))))
485
486; ;; Now scan for keywords, but not if we are inside a comment now.
487; (or (and (not font-lock-no-comments)
488; (let ((state (parse-partial-sexp beg end nil nil
489; font-lock-cache-state)))
490; (or (nth 4 state) (nth 7 state))))
491; (font-lock-hack-keywords beg end))
030f4a35
RS
492\f
493;;; Fontifying arbitrary patterns
494
030f4a35 495(defun font-lock-hack-keywords (start end &optional loudly)
a1eb1cf1 496 "Fontify according to `font-lock-keywords' between START and END."
030f4a35 497 (let ((case-fold-search font-lock-keywords-case-fold-search)
a1eb1cf1 498 (keywords font-lock-keywords)
030f4a35 499 (count 0)
3de76c48
RS
500 ;; Prevent warnings if the disk file has been altered.
501 (buffer-file-name)
502 (inhibit-read-only t)
e547d71e 503 (buffer-undo-list t)
313d590c 504 (modified (buffer-modified-p))
a1eb1cf1
RS
505 (old-syntax (syntax-table))
506 (bufname (buffer-name)))
b056da51 507 (unwind-protect
a1eb1cf1
RS
508 (let (keyword regexp match highlights hs h s e)
509 (if loudly (message "Fontifying %s... (regexps...)" bufname))
510 (if font-lock-syntax-table (set-syntax-table font-lock-syntax-table))
511 (while keywords
512 (setq keyword (car keywords) keywords (cdr keywords)
513 regexp (if (stringp keyword) keyword (car keyword))
514 highlights (cond ((stringp keyword)
515 '((0 font-lock-keyword-face)))
516 ((numberp (cdr keyword))
517 (list (list (cdr keyword)
518 'font-lock-keyword-face)))
519 ((symbolp (cdr keyword))
520 (list (list 0 (cdr keyword))))
521 ((nlistp (nth 1 keyword))
522 (list (cdr keyword)))
523 (t
524 (cdr keyword))))
b056da51 525 (goto-char start)
a1eb1cf1
RS
526 (while (re-search-forward regexp end t)
527 (setq hs highlights)
528 (while hs
529 (setq h (car hs) match (nth 0 h)
530 s (match-beginning match) e (match-end match)
531 hs (cdr hs))
532 (cond ((not s)
533 ;; No match but we might not signal an error
534 (or (nth 3 h)
535 (error "No subexpression %d in expression %d"
536 match (1+ count))))
537 ((and (not (nth 2 h))
538 (text-property-not-all s e 'face nil))
539 ;; Can't override and already fontified
540 nil)
541 ((not (eq (nth 2 h) 'keep))
542 ;; Can override but need not keep existing fontification
543 (put-text-property s e 'face (eval (nth 1 h))))
544 (t
545 ;; Can override but must keep existing fontification
546 ;; (Does anyone use this? sm.)
547 (let ((p (text-property-any s e 'face nil)) n
548 (face (eval (nth 1 h))))
549 (while p
550 (setq n (next-single-property-change p 'face nil e))
551 (put-text-property p n 'face face)
552 (setq p (text-property-any n e 'face nil))))))))
553;; the above form was:
554; (save-excursion
555; (goto-char s)
556; (while (< (point) e)
557; (let ((next (next-single-property-change (point) 'face
558; nil e)))
559; (if (or (null next) (> next e))
560; (setq next e))
561; (if (not (get-text-property (point) 'face))
562; (put-text-property (point) next 'face face))
563; (goto-char next))))
564
565 (if loudly (message "Fontifying %s... (regexps...%s)" bufname
b056da51
RS
566 (make-string (setq count (1+ count)) ?.)))))
567 (set-syntax-table old-syntax))
65df0851
RS
568 (and (buffer-modified-p)
569 (not modified)
570 (set-buffer-modified-p nil))))
030f4a35
RS
571\f
572;; The user level functions
573
574(defvar font-lock-mode nil) ; for modeline
030f4a35
RS
575
576(defvar font-lock-fontified nil) ; whether we have hacked this buffer
577(put 'font-lock-fontified 'permanent-local t)
578
579;;;###autoload
580(defun font-lock-mode (&optional arg)
581 "Toggle Font Lock mode.
582With arg, turn Font Lock mode on if and only if arg is positive.
583
584When Font Lock mode is enabled, text is fontified as you type it:
585
a1eb1cf1
RS
586 - Comments are displayed in `font-lock-comment-face';
587 - Strings are displayed in `font-lock-string-face';
588 - Certain other expressions are displayed in other faces according to the
589 value of the variable `font-lock-keywords'.
590
591You can enable Font Lock mode in any major mode automatically by turning on in
592the major mode's hook. For example, put in your ~/.emacs:
593
594 (add-hook 'c-mode-hook 'turn-on-font-lock)
595
596Or for any visited file with the following in your ~/.emacs:
597
598 (add-hook 'find-file-hooks 'turn-on-font-lock)
599
600The default Font Lock mode faces and their attributes are defined in the
601variable `font-lock-face-attributes', and Font Lock mode default settings in
602the variable `font-lock-defaults-alist'.
030f4a35 603
b89e1134
SM
604When you turn Font Lock mode on/off the buffer is fontified/defontified, though
605fontification occurs only if the buffer is less than `font-lock-maximum-size'.
606To fontify a buffer without turning on Font Lock mode, and regardless of buffer
607size, you can use \\[font-lock-fontify-buffer]."
030f4a35 608 (interactive "P")
a1eb1cf1 609 (let ((on-p (if arg (> (prefix-numeric-value arg) 0) (not font-lock-mode))))
030f4a35
RS
610 (if (equal (buffer-name) " *Compiler Input*") ; hack for bytecomp...
611 (setq on-p nil))
a1eb1cf1
RS
612 (if (not on-p)
613 (remove-hook 'after-change-functions 'font-lock-after-change-function)
614 (make-local-variable 'after-change-functions)
615 (add-hook 'after-change-functions 'font-lock-after-change-function))
030f4a35
RS
616 (set (make-local-variable 'font-lock-mode) on-p)
617 (cond (on-p
618 (font-lock-set-defaults)
7daa8d6b 619 (make-local-variable 'before-revert-hook)
87cd38d6 620 (make-local-variable 'after-revert-hook)
7daa8d6b
KH
621 ;; If buffer is reverted, must clean up the state.
622 (add-hook 'before-revert-hook 'font-lock-revert-setup)
623 (add-hook 'after-revert-hook 'font-lock-revert-cleanup)
030f4a35 624 (run-hooks 'font-lock-mode-hook)
b89e1134
SM
625 (cond (font-lock-fontified
626 nil)
627 ((or (null font-lock-maximum-size)
628 (> font-lock-maximum-size (buffer-size)))
629 (font-lock-fontify-buffer))
630 (font-lock-verbose
631 (message "Fontifying %s... buffer too big." (buffer-name)))))
030f4a35
RS
632 (font-lock-fontified
633 (setq font-lock-fontified nil)
7daa8d6b
KH
634 (remove-hook 'before-revert-hook 'font-lock-revert-setup)
635 (remove-hook 'after-revert-hook 'font-lock-revert-cleanup)
030f4a35
RS
636 (font-lock-unfontify-region (point-min) (point-max))))
637 (force-mode-line-update)))
638
a1eb1cf1
RS
639;;;###autoload
640(defun turn-on-font-lock ()
641 "Unconditionally turn on Font Lock mode."
642 (font-lock-mode 1))
643
7daa8d6b
KH
644;; If the buffer is about to be reverted, it won't be fontified.
645(defun font-lock-revert-setup ()
646 (setq font-lock-fontified nil))
647
648;; If the buffer has just been reverted, we might not even be in font-lock
649;; mode anymore, and if we are, the buffer may or may not have already been
650;; refontified. Refontify here if it looks like we need to.
651(defun font-lock-revert-cleanup ()
652 (and font-lock-mode
653 (not font-lock-fontified)
654 (font-lock-mode 1)))
655
a1eb1cf1 656;;;###autoload
030f4a35 657(defun font-lock-fontify-buffer ()
a1eb1cf1 658 "Fontify the current buffer the way `font-lock-mode' would."
030f4a35
RS
659 (interactive)
660 (let ((was-on font-lock-mode)
a1eb1cf1
RS
661 (verbose (or font-lock-verbose (interactive-p)))
662 (modified (buffer-modified-p)))
b89e1134 663 (set (make-local-variable 'font-lock-fontified) nil)
a1eb1cf1 664 (if verbose (message "Fontifying %s..." (buffer-name)))
b89e1134 665 ;; Turn it on to run hooks and get the right `font-lock-keywords' etc.
366b3ecc 666 (or was-on (font-lock-set-defaults))
a1eb1cf1
RS
667 (condition-case nil
668 (save-excursion
669 (font-lock-unfontify-region (point-min) (point-max))
670 (if (not font-lock-no-comments)
671 (font-lock-fontify-region (point-min) (point-max) verbose))
672 (font-lock-hack-keywords (point-min) (point-max) verbose)
673 (setq font-lock-fontified t))
674 ;; We don't restore the old fontification, so it's best to unfontify.
b89e1134 675 (quit (font-lock-unfontify-region (point-min) (point-max))))
a1eb1cf1
RS
676 (if verbose (message "Fontifying %s... %s." (buffer-name)
677 (if font-lock-fontified "done" "aborted")))
678 (and (buffer-modified-p)
679 (not modified)
680 (set-buffer-modified-p nil))))
030f4a35
RS
681
682\f
a1eb1cf1
RS
683;;; Various information shared by several modes.
684;;; Information specific to a single mode should go in its load library.
030f4a35 685
030f4a35 686(defconst lisp-font-lock-keywords-1
a1eb1cf1 687 (list
030f4a35
RS
688 ;; highlight defining forms. This doesn't work too nicely for
689 ;; (defun (setf foo) ...) but it does work for (defvar foo) which
690 ;; is more important.
a1eb1cf1
RS
691 (list (concat "^(\\(def\\(const\\|ine-key\\(\\|-after\\)\\|var\\)\\)\\>"
692 "\\s *\\([^ \t\n\)]+\\)?")
693 '(1 font-lock-keyword-face) '(4 font-lock-variable-name-face nil t))
694 (list (concat "^(\\(def\\(a\\(dvice\\|lias\\)\\|macro\\|subst\\|un\\)\\)\\>"
695 "\\s *\\([^ \t\n\)]+\\)?")
696 '(1 font-lock-keyword-face) '(4 font-lock-function-name-face nil t))
030f4a35
RS
697 ;;
698 ;; this is highlights things like (def* (setf foo) (bar baz)), but may
699 ;; be slower (I haven't really thought about it)
700; ("^(def[-a-z]+\\s +\\(\\s(\\S)*\\s)\\|\\S(\\S *\\)"
701; 1 font-lock-function-name-face)
702 )
703 "For consideration as a value of `lisp-font-lock-keywords'.
704This does fairly subdued highlighting.")
705
706(defconst lisp-font-lock-keywords-2
707 (append
708 lisp-font-lock-keywords-1
a1eb1cf1
RS
709 (list
710 ;;
711 ;; Control structures.
712 ;; ELisp:
713; ("cond" "if" "while" "let\\*?" "prog[nv12*]?" "catch" "throw"
714; "save-restriction" "save-excursion"
715; "save-window-excursion" "save-match-data" "unwind-protect"
716; "condition-case" "track-mouse")
717 (cons
718 (concat "(\\("
719 "c\\(atch\\|ond\\(\\|ition-case\\)\\)\\|if\\|let\\*?\\|prog[nv12*]?\\|"
720 "save-\\(excursion\\|match-data\\|restriction\\|window-excursion\\)\\|"
721 "t\\(hrow\\|rack-mouse\\)\\|unwind-protect\\|while"
722 "\\)[ \t\n]") 1)
723 ;; CLisp:
724; ("when" "unless" "do" "flet" "labels" "return" "return-from")
b89e1134 725 '("(\\(do\\|flet\\|labels\\|return\\(\\|-from\\)\\|unless\\|when\\)[ \t\n]"
a1eb1cf1
RS
726 . 1)
727 ;;
728 ;; Fontify CLisp keywords.
729 '("\\s :\\([-a-zA-Z0-9]+\\)\\>" . 1)
730 ;;
731 ;; Function names in emacs-lisp docstrings (in the syntax that
732 ;; substitute-command-keys understands.)
733 '("\\\\\\\\\\[\\([^]\\\n]+\\)]" 1 font-lock-reference-face t)
734 ;;
735 ;; Words inside `' which tend to be function names
9e116f87 736 (let ((word-char "[-+a-zA-Z0-9_:*]"))
a1eb1cf1
RS
737 (list (concat "`\\(" word-char word-char "+\\)'")
738 1 'font-lock-reference-face t))
739 ;;
740 ;; & keywords as types
741 '("\\&\\(optional\\|rest\\)\\>" . font-lock-type-face)
742 ))
030f4a35
RS
743 "For consideration as a value of `lisp-font-lock-keywords'.
744This does a lot more highlighting.")
745
746;; default to the gaudier variety?
747;(defvar lisp-font-lock-keywords lisp-font-lock-keywords-2
748; "Additional expressions to highlight in Lisp modes.")
749(defvar lisp-font-lock-keywords lisp-font-lock-keywords-1
750 "Additional expressions to highlight in Lisp modes.")
751
752
753(defconst c-font-lock-keywords-1 nil
b89e1134 754 "For consideration as a value of `c-font-lock-keywords'.
030f4a35
RS
755This does fairly subdued highlighting.")
756
757(defconst c-font-lock-keywords-2 nil
b89e1134 758 "For consideration as a value of `c-font-lock-keywords'.
030f4a35
RS
759This does a lot more highlighting.")
760
1bd50840 761(defconst c++-font-lock-keywords-1 nil
b89e1134 762 "For consideration as a value of `c++-font-lock-keywords'.
1bd50840
RS
763This does fairly subdued highlighting.")
764
765(defconst c++-font-lock-keywords-2 nil
b89e1134 766 "For consideration as a value of `c++-font-lock-keywords'.
1bd50840
RS
767This does a lot more highlighting.")
768
b89e1134
SM
769(let ((c-keywords
770; ("break" "continue" "do" "else" "for" "if" "return" "switch" "while")
771 "break\\|continue\\|do\\|else\\|for\\|if\\|return\\|switch\\|while")
772 (c-type-types
a1eb1cf1
RS
773; ("auto" "extern" "register" "static" "typedef" "struct" "union" "enum"
774; "signed" "unsigned" "short" "long" "int" "char" "float" "double"
b89e1134
SM
775; "void" "volatile" "const")
776 (concat "auto\\|c\\(har\\|onst\\)\\|double\\|e\\(num\\|xtern\\)\\|"
777 "float\\|int\\|long\\|register\\|"
778 "s\\(hort\\|igned\\|t\\(atic\\|ruct\\)\\)\\|typedef\\|"
779 "un\\(ion\\|signed\\)\\|vo\\(id\\|latile\\)")) ; 6 ()s deep.
780 (c++-keywords
781; ("break" "continue" "do" "else" "for" "if" "return" "switch" "while"
782; "asm" "catch" "delete" "new" "operator" "sizeof" "this" "throw" "try"
783; "protected" "private" "public")
784 (concat "asm\\|break\\|c\\(atch\\|ontinue\\)\\|d\\(elete\\|o\\)\\|"
785 "else\\|for\\|if\\|new\\|operator\\|"
786 "p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|return\\|"
787 "s\\(izeof\\|witch\\)\\|t\\(h\\(is\\|row\\)\\|ry\\)\\|while"))
788 (c++-type-types
789; ("auto" "extern" "register" "static" "typedef" "struct" "union" "enum"
790; "signed" "unsigned" "short" "long" "int" "char" "float" "double"
791; "void" "volatile" "const" "class" "inline" "friend" "bool"
792; "virtual" "complex" "template")
793 (concat "auto\\|bool\\|c\\(har\\|lass\\|o\\(mplex\\|nst\\)\\)\\|"
794 "double\\|e\\(num\\|xtern\\)\\|f\\(loat\\|riend\\)\\|"
795 "in\\(line\\|t\\)\\|long\\|register\\|"
796 "s\\(hort\\|igned\\|t\\(atic\\|ruct\\)\\)\\|"
797 "t\\(emplate\\|ypedef\\)\\|un\\(ion\\|signed\\)\\|"
798 "v\\(irtual\\|o\\(id\\|latile\\)\\)")) ; 11 ()s deep.
a1eb1cf1 799 (ctoken "[a-zA-Z0-9_:~]+"))
f60f18ae
KH
800 (setq c-font-lock-keywords-1
801 (list
f60f18ae 802 ;;
a1eb1cf1 803 ;; Fontify filenames in #include <...> preprocessor directives.
f60f18ae
KH
804 '("^#[ \t]*include[ \t]+\\(<[^>\"\n]+>\\)" 1 font-lock-string-face)
805 ;;
a1eb1cf1
RS
806 ;; Fontify function macro names.
807 '("^#[ \t]*define[ \t]+\\(\\(\\sw+\\)(\\)" 2 font-lock-function-name-face)
f60f18ae 808 ;;
a1eb1cf1
RS
809 ;; Fontify otherwise as symbol names, and the preprocessor directive names.
810 '("^\\(#[ \t]*[a-z]+\\)\\>[ \t]*\\(\\sw+\\)?"
811 (1 font-lock-reference-face) (2 font-lock-variable-name-face nil t))
f60f18ae 812 ;;
a1eb1cf1
RS
813 ;; Fontify function name definitions (without type on line).
814 (list (concat "^\\(" ctoken "\\)[ \t]*(") 1 'font-lock-function-name-face)
f60f18ae
KH
815 ))
816
817 (setq c-font-lock-keywords-2
818 (append c-font-lock-keywords-1
030f4a35 819 (list
030f4a35 820 ;;
a1eb1cf1 821 ;; Fontify all storage classes and type specifiers (before declarations).
b89e1134 822 (cons (concat "\\<\\(" c-type-types "\\)\\>") 'font-lock-type-face)
030f4a35 823 ;;
a1eb1cf1
RS
824 ;; Fontify variable/structure name declarations and definitions, or
825 ;; function name declarations (plus definitions with type on same line).
b89e1134
SM
826 (list (concat "\\<\\(" c-type-types "\\)[ \t*]+"
827 "\\(" ctoken "[ \t*]+\\)*"
828 "\\(" ctoken "\\)[ \t]*\\((\\)?")
829 9
830 '(if (match-beginning 10)
831 font-lock-function-name-face
832 font-lock-variable-name-face))
833 ;;
834 ;; Fontify function/variable name declarations at the start of the line.
835 ;; (Not everyone follows the GNU convention of function name at the start.)
836 (list (concat "^" ctoken "[ \t*]+"
837 "\\(" ctoken "[ \t*]+\\)*"
a1eb1cf1 838 "\\(" ctoken "\\)[ \t]*\\((\\)?")
b89e1134
SM
839 2
840 '(if (match-beginning 3)
841 font-lock-function-name-face
842 font-lock-variable-name-face))
030f4a35 843 ;;
a1eb1cf1 844 ;; Fontify variable names declared with structures, or typedef names.
b89e1134 845 '("}[ \t*]*\\(\\sw+\\)[ \t]*[;,[]" 1 font-lock-variable-name-face)
030f4a35 846 ;;
b89e1134
SM
847 ;; Fontify all builtin keywords (except case, default and goto; see below).
848 (concat "\\<\\(" c-keywords "\\)\\>")
030f4a35 849 ;;
b89e1134 850 ;; Fontify case/goto keywords and targets, and goto tags (incl "default:").
a1eb1cf1
RS
851 '("\\<\\(case\\|goto\\)\\>[ \t]*\\([^ \t\n:;]+\\)?"
852 (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
853 '("^[ \t]*\\(\\sw+\\)[ \t]*:" 1 font-lock-reference-face)
f60f18ae 854 )))
1bd50840 855
a1eb1cf1 856 (setq c++-font-lock-keywords-1 c-font-lock-keywords-1)
1bd50840 857 (setq c++-font-lock-keywords-2
b89e1134 858 (append c++-font-lock-keywords-1
a1eb1cf1 859 (list
b89e1134
SM
860 ;; We don't just add to the C keywords for subtle differences and speed.
861 ;; See the above comments for `c-font-lock-keywords-2'.
862 (cons (concat "\\<\\(" c++-type-types "\\)\\>") 'font-lock-type-face)
863 (list (concat "\\<\\(" c++-type-types "\\)[ \t*&]+"
864 "\\(" ctoken "[ \t*&]+\\)*"
865 "\\(" ctoken "\\)[ \t]*\\((\\)?")
866 14
867 '(if (match-beginning 15)
868 font-lock-function-name-face
869 font-lock-variable-name-face))
870 (list (concat "^" ctoken "[ \t*]+"
871 "\\(" ctoken "[ \t*]+\\)*"
872 "\\(" ctoken "\\)[ \t]*\\((\\)?")
873 2
874 '(if (match-beginning 3)
875 font-lock-function-name-face
876 font-lock-variable-name-face))
877 '("}[ \t*]*\\(\\sw+\\)[ \t]*[;,[]" 1 font-lock-variable-name-face)
878 (concat "\\<\\(" c++-keywords "\\)\\>")
879 '("\\<\\(case\\|goto\\)\\>[ \t]*\\([^ \t\n:;]+\\)?"
880 (1 font-lock-keyword-face) (2 font-lock-reference-face nil t))
881 '("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-reference-face))))
f60f18ae 882 )
030f4a35
RS
883
884; default to the gaudier variety?
030f4a35
RS
885(defvar c-font-lock-keywords c-font-lock-keywords-1
886 "Additional expressions to highlight in C mode.")
887
1bd50840 888(defvar c++-font-lock-keywords c++-font-lock-keywords-1
030f4a35
RS
889 "Additional expressions to highlight in C++ mode.")
890
030f4a35
RS
891(defvar tex-font-lock-keywords
892 (list
055c8d71 893 '("\\(\\\\\\([a-zA-Z@]+\\|.\\)\\)" 1 font-lock-keyword-face t)
030f4a35
RS
894 '("{\\\\em\\([^}]+\\)}" 1 font-lock-comment-face t)
895 '("{\\\\bf\\([^}]+\\)}" 1 font-lock-keyword-face t)
896 '("^[ \t\n]*\\\\def[\\\\@]\\(\\w+\\)" 1 font-lock-function-name-face t)
897 '("\\\\\\(begin\\|end\\){\\([a-zA-Z0-9\\*]+\\)}"
898 2 font-lock-function-name-face t)
899 '("[^\\\\]\\$\\([^$]*\\)\\$" 1 font-lock-string-face t)
900; '("\\$\\([^$]*\\)\\$" 1 font-lock-string-face t)
901 )
902 "Additional expressions to highlight in TeX mode.")
903
b89e1134
SM
904;; There is no html-mode.el shipped with Emacs; `font-lock-defaults' entry
905; would be: (html-font-lock-keywords nil t)
906;(defconst html-font-lock-keywords
a1eb1cf1
RS
907; '(("<!--[^>]*>" 0 font-lock-comment-face t) ; Comment.
908; ("</?\\sw+" . font-lock-type-face) ; Normal tag start.
909; (">" . font-lock-type-face) ; Normal tag end.
910; ("<\\(/?\\(a\\|form\\|img\\|input\\)\\)\\>" ; Special tag name.
911; 1 font-lock-function-name-face t)
912; ("\\<\\(\\sw+\\)[>=]" 1 font-lock-keyword-face)) ; Tag attribute.
913; "Additional expressions to highlight in HTML mode.")
914
8f261d40 915(defun font-lock-set-defaults ()
a1eb1cf1 916 "Set fontification defaults appropriately for this mode.
b89e1134
SM
917Sets `font-lock-keywords', `font-lock-no-comments', `font-lock-syntax-table'
918and `font-lock-keywords-case-fold-search' using `font-lock-defaults-alist'."
919 (or font-lock-keywords ; if not already set.
2df1ee23
RS
920 (let ((defaults (or font-lock-defaults
921 (cdr (assq major-mode font-lock-defaults-alist)))))
922 ;; Keywords?
923 (setq font-lock-keywords (eval (nth 0 defaults)))
924 ;; Syntactic?
925 (if (nth 1 defaults)
926 (set (make-local-variable 'font-lock-no-comments) t))
927 ;; Case fold?
928 (if (nth 2 defaults)
929 (set (make-local-variable 'font-lock-keywords-case-fold-search) t))
930 ;; Syntax table?
b89e1134
SM
931 (if (nth 3 defaults)
932 (let ((slist (nth 3 defaults)))
933 (make-local-variable 'font-lock-syntax-table)
934 (setq font-lock-syntax-table (copy-syntax-table (syntax-table)))
935 (while slist
936 (modify-syntax-entry (car (car slist)) (cdr (car slist))
937 font-lock-syntax-table)
938 (setq slist (cdr slist))))))))
a1eb1cf1
RS
939
940;; Install ourselves:
941
d8a1aa6e 942(if purify-flag
b89e1134
SM
943 (add-hook 'after-init-hook 'font-lock-make-faces)
944 (font-lock-make-faces))
a1eb1cf1
RS
945
946(or (assq 'font-lock-mode minor-mode-alist)
947 (setq minor-mode-alist (cons '(font-lock-mode " Font") minor-mode-alist)))
948
949;; Provide ourselves:
8f261d40 950
030f4a35
RS
951(provide 'font-lock)
952
953;;; font-lock.el ends here