(c-parse-state): Added kludge to avoid an infinite loop when Emacs'
[bpt/emacs.git] / lisp / font-core.el
1 ;;; font-core.el --- Core interface to font-lock
2
3 ;; Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 1999, 2000, 2001, 2002
4 ;; Free Software Foundation, Inc.
5
6 ;; Maintainer: FSF
7 ;; Keywords: languages, faces
8
9 ;; This file is part of GNU Emacs.
10
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
14 ;; any later version.
15
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
20
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24 ;; Boston, MA 02111-1307, USA.
25
26 ;;; Code:
27
28 (defvar font-lock-maximum-size)
29 (defvar font-lock-verbose)
30
31 ;; This variable is used by mode packages that support Font Lock mode by
32 ;; defining their own keywords to use for `font-lock-keywords'. (The mode
33 ;; command should make it buffer-local and set it to provide the set up.)
34 (defvar font-lock-defaults nil
35 "Defaults for Font Lock mode specified by the major mode.
36 Defaults should be of the form:
37
38 (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN ...)
39
40 KEYWORDS may be a symbol (a variable or function whose value is the keywords to
41 use for fontification) or a list of symbols. If KEYWORDS-ONLY is non-nil,
42 syntactic fontification (strings and comments) is not performed.
43 If CASE-FOLD is non-nil, the case of the keywords is ignored when fontifying.
44 If SYNTAX-ALIST is non-nil, it should be a list of cons pairs of the form
45 \(CHAR-OR-STRING . STRING) used to set the local Font Lock syntax table, for
46 keyword and syntactic fontification (see `modify-syntax-entry').
47
48 If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move
49 backwards outside any enclosing syntactic block, for syntactic fontification.
50 Typical values are `beginning-of-line' (i.e., the start of the line is known to
51 be outside a syntactic block), or `beginning-of-defun' for programming modes or
52 `backward-paragraph' for textual modes (i.e., the mode-dependent function is
53 known to move outside a syntactic block). If nil, the beginning of the buffer
54 is used as a position outside of a syntactic block, in the worst case.
55
56 These item elements are used by Font Lock mode to set the variables
57 `font-lock-keywords', `font-lock-keywords-only',
58 `font-lock-keywords-case-fold-search', `font-lock-syntax-table' and
59 `font-lock-beginning-of-syntax-function', respectively.
60
61 Further item elements are alists of the form (VARIABLE . VALUE) and are in no
62 particular order. Each VARIABLE is made buffer-local before set to VALUE.
63
64 Currently, appropriate variables include `font-lock-mark-block-function'.
65 If this is non-nil, it should be a function with no args used to mark any
66 enclosing block of text, for fontification via \\[font-lock-fontify-block].
67 Typical values are `mark-defun' for programming modes or `mark-paragraph' for
68 textual modes (i.e., the mode-dependent function is known to put point and mark
69 around a text block relevant to that mode).
70
71 Other variables include that for syntactic keyword fontification,
72 `font-lock-syntactic-keywords'
73 and those for buffer-specialized fontification functions,
74 `font-lock-fontify-buffer-function', `font-lock-unfontify-buffer-function',
75 `font-lock-fontify-region-function', `font-lock-unfontify-region-function',
76 `font-lock-inhibit-thing-lock' and `font-lock-maximum-size'.")
77 (make-variable-buffer-local 'font-lock-defaults)
78
79 ;; This variable is used where font-lock.el itself supplies the
80 ;; keywords. Really, this shouldn't need to be in font-core.el, but
81 ;; we can't avoid it. In the future, this stuff will hopefully be
82 ;; moved to cc-mode itself.
83 (defvar font-lock-defaults-alist
84 (let (;; We use `beginning-of-defun', rather than nil, for SYNTAX-BEGIN.
85 ;; Thus the calculation of the cache is usually faster but not
86 ;; infallible, so we risk mis-fontification. sm.
87 (c-mode-defaults
88 '((c-font-lock-keywords c-font-lock-keywords-1
89 c-font-lock-keywords-2 c-font-lock-keywords-3)
90 nil nil ((?_ . "w")) beginning-of-defun
91 (font-lock-syntactic-face-function
92 . c-font-lock-syntactic-face-function)
93 (font-lock-mark-block-function . mark-defun)))
94 (c++-mode-defaults
95 '((c++-font-lock-keywords c++-font-lock-keywords-1
96 c++-font-lock-keywords-2 c++-font-lock-keywords-3)
97 nil nil ((?_ . "w")) beginning-of-defun
98 (font-lock-syntactic-face-function
99 . c-font-lock-syntactic-face-function)
100 (font-lock-mark-block-function . mark-defun)))
101 (objc-mode-defaults
102 '((objc-font-lock-keywords objc-font-lock-keywords-1
103 objc-font-lock-keywords-2 objc-font-lock-keywords-3)
104 nil nil ((?_ . "w") (?$ . "w")) nil
105 (font-lock-syntactic-face-function
106 . c-font-lock-syntactic-face-function)
107 (font-lock-mark-block-function . mark-defun)))
108 (java-mode-defaults
109 '((java-font-lock-keywords java-font-lock-keywords-1
110 java-font-lock-keywords-2 java-font-lock-keywords-3)
111 nil nil ((?_ . "w") (?$ . "w")) nil
112 (font-lock-syntactic-face-function
113 . java-font-lock-syntactic-face-function)
114 (font-lock-mark-block-function . mark-defun))))
115 (list
116 (cons 'c-mode c-mode-defaults)
117 (cons 'c++-mode c++-mode-defaults)
118 (cons 'objc-mode objc-mode-defaults)
119 (cons 'java-mode java-mode-defaults)))
120 "Alist of fall-back Font Lock defaults for major modes.
121
122 This variable should not be used any more.
123 Set the buffer-local `font-lock-keywords' in the major mode instead.
124
125 Each item should be a list of the form:
126
127 (MAJOR-MODE . FONT-LOCK-DEFAULTS)
128
129 where MAJOR-MODE is a symbol and FONT-LOCK-DEFAULTS is a list of default
130 settings. See the variable `font-lock-defaults', which takes precedence.")
131 (make-obsolete-variable 'font-lock-defaults-alist 'font-lock-defaults)
132
133 (defvar font-lock-multiline nil
134 "Whether font-lock should cater to multiline keywords.
135 If nil, don't try to handle multiline patterns.
136 If t, always handle multiline patterns.
137 If `undecided', don't try to handle multiline patterns until you see one.
138 Major/minor modes can set this variable if they know which option applies.")
139
140 (defvar font-lock-fontified nil) ; Whether we have fontified the buffer.
141
142 (defvar font-lock-function 'font-lock-default-function
143 "A function which is called when `font-lock-mode' is toggled.
144 It will be passed one argument, which is the current value of
145 `font-lock-mode'.")
146 (make-variable-buffer-local 'font-lock-function)
147
148 (define-minor-mode font-lock-mode
149 "Toggle Font Lock mode.
150 With arg, turn Font Lock mode off if and only if arg is a non-positive
151 number; if arg is nil, toggle Font Lock mode; anything else turns Font
152 Lock on.
153 \(Font Lock is also known as \"syntax highlighting\".)
154
155 When Font Lock mode is enabled, text is fontified as you type it:
156
157 - Comments are displayed in `font-lock-comment-face';
158 - Strings are displayed in `font-lock-string-face';
159 - Certain other expressions are displayed in other faces according to the
160 value of the variable `font-lock-keywords'.
161
162 To customize the faces (colors, fonts, etc.) used by Font Lock for
163 fontifying different parts of buffer text, use \\[customize-face].
164
165 You can enable Font Lock mode in any major mode automatically by turning on in
166 the major mode's hook. For example, put in your ~/.emacs:
167
168 (add-hook 'c-mode-hook 'turn-on-font-lock)
169
170 Alternatively, you can use Global Font Lock mode to automagically turn on Font
171 Lock mode in buffers whose major mode supports it and whose major mode is one
172 of `font-lock-global-modes'. For example, put in your ~/.emacs:
173
174 (global-font-lock-mode t)
175
176 There are a number of support modes that may be used to speed up Font Lock mode
177 in various ways, specified via the variable `font-lock-support-mode'. Where
178 major modes support different levels of fontification, you can use the variable
179 `font-lock-maximum-decoration' to specify which level you generally prefer.
180 When you turn Font Lock mode on/off the buffer is fontified/defontified, though
181 fontification occurs only if the buffer is less than `font-lock-maximum-size'.
182
183 For example, to specify that Font Lock mode use use Lazy Lock mode as a support
184 mode and use maximum levels of fontification, put in your ~/.emacs:
185
186 (setq font-lock-support-mode 'lazy-lock-mode)
187 (setq font-lock-maximum-decoration t)
188
189 To add your own highlighting for some major mode, and modify the highlighting
190 selected automatically via the variable `font-lock-maximum-decoration', you can
191 use `font-lock-add-keywords'.
192
193 To fontify a buffer, without turning on Font Lock mode and regardless of buffer
194 size, you can use \\[font-lock-fontify-buffer].
195
196 To fontify a block (the function or paragraph containing point, or a number of
197 lines around point), perhaps because modification on the current line caused
198 syntactic change on other lines, you can use \\[font-lock-fontify-block].
199
200 See the variable `font-lock-defaults-alist' for the Font Lock mode default
201 settings. You can set your own default settings for some mode, by setting a
202 buffer local value for `font-lock-defaults', via its mode hook.
203
204 The above is the default behavior of `font-lock-mode'; you may specify
205 your own function which is called when `font-lock-mode' is toggled via
206 `font-lock-function'. "
207 nil nil nil
208 ;; Don't turn on Font Lock mode if we don't have a display (we're running a
209 ;; batch job) or if the buffer is invisible (the name starts with a space).
210 (when (or noninteractive (eq (aref (buffer-name) 0) ?\ ))
211 (setq font-lock-mode nil))
212 (funcall font-lock-function font-lock-mode)
213 ;; Arrange to unfontify this buffer if we change major mode later.
214 (if font-lock-mode
215 (add-hook 'change-major-mode-hook 'font-lock-change-mode nil t)
216 (remove-hook 'change-major-mode-hook 'font-lock-change-mode t)))
217
218 ;; Get rid of fontification for the old major mode.
219 ;; We do this when changing major modes.
220 (defun font-lock-change-mode ()
221 (font-lock-mode -1))
222
223 (defun font-lock-defontify ()
224 "Clear out all `font-lock-face' properties in current buffer.
225 A major mode that uses `font-lock-face' properties should put
226 this function onto `change-major-mode-hook'."
227 (let ((modp (buffer-modified-p))
228 (inhibit-read-only t))
229 (save-restriction
230 (widen)
231 (remove-list-of-text-properties (point-min) (point-max)
232 '(font-lock-face)))
233 (restore-buffer-modified-p modp)))
234
235 (defun font-lock-default-function (mode)
236 ;; Turn on Font Lock mode.
237 (when mode
238 (font-lock-set-defaults)
239 (set (make-local-variable 'char-property-alias-alist)
240 (copy-tree char-property-alias-alist))
241 ;; Add `font-lock-face' as an alias for the `face' property.
242 (let ((elt (assq 'face char-property-alias-alist)))
243 (if elt
244 (unless (memq 'font-lock-face (cdr elt))
245 (setcdr elt (nconc (cdr elt) (list 'font-lock-face))))
246 (push (list 'face 'font-lock-face) char-property-alias-alist)))
247 ;; Only do hard work if the mode has specified stuff in
248 ;; `font-lock-defaults'.
249 (when font-lock-defaults
250 (add-hook 'after-change-functions 'font-lock-after-change-function t t)
251 (font-lock-turn-on-thing-lock)
252 ;; Fontify the buffer if we have to.
253 (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
254 (cond (font-lock-fontified
255 nil)
256 ((or (null max-size) (> max-size (buffer-size)))
257 (font-lock-fontify-buffer))
258 (font-lock-verbose
259 (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
260 (buffer-name)))))))
261 ;; Turn off Font Lock mode.
262 (unless mode
263 ;; Remove `font-lock-face' as an alias for the `face' property.
264 (set (make-local-variable 'char-property-alias-alist)
265 (copy-tree char-property-alias-alist))
266 (let ((elt (assq 'face char-property-alias-alist)))
267 (when elt
268 (setcdr elt (remq 'font-lock-face (cdr elt)))
269 (when (null (cdr elt))
270 (setq char-property-alias-alist (delq elt char-property-alias-alist)))))
271 (when font-lock-defaults
272 (remove-hook 'after-change-functions 'font-lock-after-change-function t)
273 (font-lock-unfontify-buffer)
274 (font-lock-turn-off-thing-lock))))
275
276 (defun turn-on-font-lock ()
277 "Turn on Font Lock mode (only if the terminal can display it)."
278 (unless font-lock-mode
279 (font-lock-mode)))
280
281 (defvar font-lock-set-defaults nil) ; Whether we have set up defaults.
282
283 (defun font-lock-set-defaults ()
284 "Set fontification defaults appropriately for this mode.
285 Sets various variables using `font-lock-defaults' (or, if nil, using
286 `font-lock-defaults-alist') and `font-lock-maximum-decoration'."
287 (unless font-lock-set-defaults
288 (set (make-local-variable 'font-lock-set-defaults) t)
289 (make-local-variable 'font-lock-fontified)
290 (make-local-variable 'font-lock-multiline)
291 (let ((defaults (or font-lock-defaults
292 (cdr (assq major-mode font-lock-defaults-alist)))))
293 (when defaults
294 (require 'font-lock)
295 (font-lock-set-defaults-1)))))
296
297 ;;; Global Font Lock mode.
298
299 ;; A few people have hassled in the past for a way to make it easier to turn on
300 ;; Font Lock mode, without the user needing to know for which modes s/he has to
301 ;; turn it on, perhaps the same way hilit19.el/hl319.el does. I've always
302 ;; balked at that way, as I see it as just re-moulding the same problem in
303 ;; another form. That is; some person would still have to keep track of which
304 ;; modes (which may not even be distributed with Emacs) support Font Lock mode.
305 ;; The list would always be out of date. And that person might have to be me.
306
307 ;; Implementation.
308 ;;
309 ;; In a previous discussion the following hack came to mind. It is a gross
310 ;; hack, but it generally works. We use the convention that major modes start
311 ;; by calling the function `kill-all-local-variables', which in turn runs
312 ;; functions on the hook variable `change-major-mode-hook'. We attach our
313 ;; function `font-lock-change-major-mode' to that hook. Of course, when this
314 ;; hook is run, the major mode is in the process of being changed and we do not
315 ;; know what the final major mode will be. So, `font-lock-change-major-mode'
316 ;; only (a) notes the name of the current buffer, and (b) adds our function
317 ;; `turn-on-font-lock-if-enabled' to the hook variables `find-file-hook' and
318 ;; `post-command-hook' (for buffers that are not visiting files). By the time
319 ;; the functions on the first of these hooks to be run are run, the new major
320 ;; mode is assumed to be in place. This way we get a Font Lock function run
321 ;; when a major mode is turned on, without knowing major modes or their hooks.
322 ;;
323 ;; Naturally this requires that (a) major modes run `kill-all-local-variables',
324 ;; as they are supposed to do, and (b) the major mode is in place after the
325 ;; file is visited or the command that ran `kill-all-local-variables' has
326 ;; finished, whichever the sooner. Arguably, any major mode that does not
327 ;; follow the convension (a) is broken, and I can't think of any reason why (b)
328 ;; would not be met (except `gnudoit' on non-files). However, it is not clean.
329 ;;
330 ;; Probably the cleanest solution is to have each major mode function run some
331 ;; hook, e.g., `major-mode-hook', but maybe implementing that change is
332 ;; impractical. I am personally against making `setq' a macro or be advised,
333 ;; or have a special function such as `set-major-mode', but maybe someone can
334 ;; come up with another solution?
335
336 ;; User interface.
337 ;;
338 ;; Although Global Font Lock mode is a pseudo-mode, I think that the user
339 ;; interface should conform to the usual Emacs convention for modes, i.e., a
340 ;; command to toggle the feature (`global-font-lock-mode') with a variable for
341 ;; finer control of the mode's behaviour (`font-lock-global-modes').
342 ;;
343 ;; The feature should not be enabled by loading font-lock.el, since other
344 ;; mechanisms for turning on Font Lock mode, such as M-x font-lock-mode RET or
345 ;; (add-hook 'c-mode-hook 'turn-on-font-lock), would cause Font Lock mode to be
346 ;; turned on everywhere. That would not be intuitive or informative because
347 ;; loading a file tells you nothing about the feature or how to control it. It
348 ;; would also be contrary to the Principle of Least Surprise. sm.
349
350 (defcustom font-lock-global-modes t
351 "*Modes for which Font Lock mode is automagically turned on.
352 Global Font Lock mode is controlled by the command `global-font-lock-mode'.
353 If nil, means no modes have Font Lock mode automatically turned on.
354 If t, all modes that support Font Lock mode have it automatically turned on.
355 If a list, it should be a list of `major-mode' symbol names for which Font Lock
356 mode should be automatically turned on. The sense of the list is negated if it
357 begins with `not'. For example:
358 (c-mode c++-mode)
359 means that Font Lock mode is turned on for buffers in C and C++ modes only."
360 :type '(choice (const :tag "none" nil)
361 (const :tag "all" t)
362 (set :menu-tag "mode specific" :tag "modes"
363 :value (not)
364 (const :tag "Except" not)
365 (repeat :inline t (symbol :tag "mode"))))
366 :group 'font-lock)
367
368 (defun turn-on-font-lock-if-enabled ()
369 (unless (and (eq (car-safe font-lock-global-modes) 'not)
370 (memq major-mode (cdr font-lock-global-modes)))
371 (let (inhibit-quit)
372 (turn-on-font-lock))))
373
374 (easy-mmode-define-global-mode
375 global-font-lock-mode font-lock-mode turn-on-font-lock-if-enabled
376 :extra-args (dummy))
377
378 ;;; End of Global Font Lock mode.
379
380 (provide 'font-core)
381
382 ;;; font-core.el ends here
383