Line data Source code
1 : ;;; font-lock.el --- Electric font lock mode
2 :
3 : ;; Copyright (C) 1992-2017 Free Software Foundation, Inc.
4 :
5 : ;; Author: Jamie Zawinski
6 : ;; Richard Stallman
7 : ;; Stefan Monnier
8 : ;; Maintainer: emacs-devel@gnu.org
9 : ;; Keywords: languages, faces
10 : ;; Package: emacs
11 :
12 : ;; This file is part of GNU Emacs.
13 :
14 : ;; GNU Emacs is free software: you can redistribute it and/or modify
15 : ;; it under the terms of the GNU General Public License as published by
16 : ;; the Free Software Foundation, either version 3 of the License, or
17 : ;; (at your option) any later version.
18 :
19 : ;; GNU Emacs is distributed in the hope that it will be useful,
20 : ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 : ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 : ;; GNU General Public License for more details.
23 :
24 : ;; You should have received a copy of the GNU General Public License
25 : ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
26 :
27 : ;;; Commentary:
28 :
29 : ;; Font Lock mode is a minor mode that causes your comments to be displayed in
30 : ;; one face, strings in another, reserved words in another, and so on.
31 : ;;
32 : ;; Comments will be displayed in `font-lock-comment-face'.
33 : ;; Strings will be displayed in `font-lock-string-face'.
34 : ;; Regexps are used to display selected patterns in other faces.
35 : ;;
36 : ;; To make the text you type be fontified, use M-x font-lock-mode RET.
37 : ;; When this minor mode is on, the faces of the current line are updated with
38 : ;; every insertion or deletion.
39 : ;;
40 : ;; To turn Font Lock mode on automatically, add this to your init file:
41 : ;;
42 : ;; (add-hook 'emacs-lisp-mode-hook #'turn-on-font-lock)
43 : ;;
44 : ;; Or if you want to turn Font Lock mode on in many modes:
45 : ;;
46 : ;; (global-font-lock-mode t)
47 : ;;
48 : ;; Fontification for a particular mode may be available in a number of levels
49 : ;; of decoration. The higher the level, the more decoration, but the more time
50 : ;; it takes to fontify. See the variable `font-lock-maximum-decoration', and
51 : ;; also the variable `font-lock-maximum-size'. Support modes for Font Lock
52 : ;; mode can be used to speed up Font Lock mode. See `font-lock-support-mode'.
53 :
54 : ;;; How Font Lock mode fontifies:
55 :
56 : ;; When Font Lock mode is turned on in a buffer, it (a) fontifies the entire
57 : ;; buffer and (b) installs one of its fontification functions on one of the
58 : ;; hook variables that are run by Emacs after every buffer change (i.e., an
59 : ;; insertion or deletion). Fontification means the replacement of `face' text
60 : ;; properties in a given region; Emacs displays text with these `face' text
61 : ;; properties appropriately.
62 : ;;
63 : ;; Fontification normally involves syntactic (i.e., strings and comments) and
64 : ;; regexp (i.e., keywords and everything else) passes. There are actually
65 : ;; three passes; (a) the syntactic keyword pass, (b) the syntactic pass and (c)
66 : ;; the keyword pass. Confused?
67 : ;;
68 : ;; The syntactic keyword pass places `syntax-table' text properties in the
69 : ;; buffer according to the variable `font-lock-syntactic-keywords'. It is
70 : ;; necessary because Emacs's syntax table is not powerful enough to describe all
71 : ;; the different syntactic constructs required by the sort of people who decide
72 : ;; that a single quote can be syntactic or not depending on the time of day.
73 : ;; (What sort of person could decide to overload the meaning of a quote?)
74 : ;; Obviously the syntactic keyword pass must occur before the syntactic pass.
75 : ;;
76 : ;; The syntactic pass places `face' text properties in the buffer according to
77 : ;; syntactic context, i.e., according to the buffer's syntax table and buffer
78 : ;; text's `syntax-table' text properties. It involves using a syntax parsing
79 : ;; function to determine the context of different parts of a region of text. A
80 : ;; syntax parsing function is necessary because generally strings and/or
81 : ;; comments can span lines, and so the context of a given region is not
82 : ;; necessarily apparent from the content of that region. Because the keyword
83 : ;; pass only works within a given region, it is not generally appropriate for
84 : ;; syntactic fontification. This is the first fontification pass that makes
85 : ;; changes visible to the user; it fontifies strings and comments.
86 : ;;
87 : ;; The keyword pass places `face' text properties in the buffer according to
88 : ;; the variable `font-lock-keywords'. It involves searching for given regexps
89 : ;; (or calling given search functions) within the given region. This is the
90 : ;; second fontification pass that makes changes visible to the user; it
91 : ;; fontifies language reserved words, etc.
92 : ;;
93 : ;; Oh, and the answer is, "Yes, obviously just about everything should be done
94 : ;; in a single syntactic pass, but the only syntactic parser available
95 : ;; understands only strings and comments." Perhaps one day someone will write
96 : ;; some syntactic parsers for common languages and a son-of-font-lock.el could
97 : ;; use them rather then relying so heavily on the keyword (regexp) pass.
98 :
99 : ;;; How Font Lock mode supports modes or is supported by modes:
100 :
101 : ;; Modes that support Font Lock mode do so by defining one or more variables
102 : ;; whose values specify the fontification. Font Lock mode knows of these
103 : ;; variable names from the buffer local variable `font-lock-defaults'.
104 : ;; (Font Lock mode is set up via (a) where a mode's patterns are
105 : ;; distributed with the mode's package library, and (b) where a mode's
106 : ;; patterns are distributed with font-lock.el itself. An example of (a)
107 : ;; is Pascal mode, an example of (b) is Lisp mode. Normally, the mechanism is
108 : ;; (a); (b) is used where it is not clear which package library should contain
109 : ;; the pattern definitions.) Font Lock mode chooses which variable to use for
110 : ;; fontification based on `font-lock-maximum-decoration'.
111 : ;;
112 : ;; Font Lock mode fontification behavior can be modified in a number of ways.
113 : ;; See the below comments and the comments distributed throughout this file.
114 :
115 : ;;; Constructing patterns:
116 :
117 : ;; See the documentation for the variable `font-lock-keywords'.
118 : ;;
119 : ;; Efficient regexps for use as MATCHERs for `font-lock-keywords' and
120 : ;; `font-lock-syntactic-keywords' can be generated via the function
121 : ;; `regexp-opt'.
122 :
123 : ;;; Adding patterns for modes that already support Font Lock:
124 :
125 : ;; Though Font Lock highlighting patterns already exist for many modes, it's
126 : ;; likely there's something that you want fontified that currently isn't, even
127 : ;; at the maximum fontification level. You can add highlighting patterns via
128 : ;; `font-lock-add-keywords'. For example, say in some C
129 : ;; header file you #define the token `and' to expand to `&&', etc., to make
130 : ;; your C code almost readable. In your ~/.emacs there could be:
131 : ;;
132 : ;; (font-lock-add-keywords 'c-mode '("\\<\\(and\\|or\\|not\\)\\>"))
133 : ;;
134 : ;; Some modes provide specific ways to modify patterns based on the values of
135 : ;; other variables. For example, additional C types can be specified via the
136 : ;; variable `c-font-lock-extra-types'.
137 :
138 : ;;; Adding patterns for modes that do not support Font Lock:
139 :
140 : ;; Not all modes support Font Lock mode. If you (as a user of the mode) add
141 : ;; patterns for a new mode, you must define in your ~/.emacs a variable or
142 : ;; variables that specify regexp fontification. Then, you should indicate to
143 : ;; Font Lock mode, via the mode hook setting `font-lock-defaults', exactly what
144 : ;; support is required. For example, say Foo mode should have the following
145 : ;; regexps fontified case-sensitively, and comments and strings should not be
146 : ;; fontified automagically. In your ~/.emacs there could be:
147 : ;;
148 : ;; (defvar foo-font-lock-keywords
149 : ;; '(("\\<\\(one\\|two\\|three\\)\\>" . 'font-lock-keyword-face)
150 : ;; ("\\<\\(four\\|five\\|six\\)\\>" . 'font-lock-type-face))
151 : ;; "Default expressions to highlight in Foo mode.")
152 : ;;
153 : ;; (add-hook 'foo-mode-hook
154 : ;; (lambda ()
155 : ;; (set (make-local-variable 'font-lock-defaults)
156 : ;; '(foo-font-lock-keywords t))))
157 :
158 : ;;; Adding Font Lock support for modes:
159 :
160 : ;; Of course, it would be better that the mode already supports Font Lock mode.
161 : ;; The package author would do something similar to above. The mode must
162 : ;; define at the top-level a variable or variables that specify regexp
163 : ;; fontification. Then, the mode command should indicate to Font Lock mode,
164 : ;; via `font-lock-defaults', exactly what support is required. For example,
165 : ;; say Bar mode should have the following regexps fontified case-insensitively,
166 : ;; and comments and strings should be fontified automagically. In bar.el there
167 : ;; could be:
168 : ;;
169 : ;; (defvar bar-font-lock-keywords
170 : ;; '(("\\<\\(uno\\|due\\|tre\\)\\>" . 'font-lock-keyword-face)
171 : ;; ("\\<\\(quattro\\|cinque\\|sei\\)\\>" . 'font-lock-type-face))
172 : ;; "Default expressions to highlight in Bar mode.")
173 : ;;
174 : ;; and within `bar-mode' there could be:
175 : ;;
176 : ;; (set (make-local-variable 'font-lock-defaults)
177 : ;; '(bar-font-lock-keywords nil t))
178 :
179 : ;; What is fontification for? You might say, "It's to make my code look nice."
180 : ;; I think it should be for adding information in the form of cues. These cues
181 : ;; should provide you with enough information to both (a) distinguish between
182 : ;; different items, and (b) identify the item meanings, without having to read
183 : ;; the items and think about it. Therefore, fontification allows you to think
184 : ;; less about, say, the structure of code, and more about, say, why the code
185 : ;; doesn't work. Or maybe it allows you to think less and drift off to sleep.
186 : ;;
187 : ;; So, here are my opinions/advice/guidelines:
188 : ;;
189 : ;; - Highlight conceptual objects, such as function and variable names, and
190 : ;; different objects types differently, i.e., (a) and (b) above, highlight
191 : ;; function names differently to variable names.
192 : ;; - Keep the faces distinct from each other as far as possible.
193 : ;; i.e., (a) above.
194 : ;; - Use the same face for the same conceptual object, across all modes.
195 : ;; i.e., (b) above, all modes that have items that can be thought of as, say,
196 : ;; keywords, should be highlighted with the same face, etc.
197 : ;; - Make the face attributes fit the concept as far as possible.
198 : ;; i.e., function names might be a bold color such as blue, comments might
199 : ;; be a bright color such as red, character strings might be brown, because,
200 : ;; err, strings are brown (that was not the reason, please believe me).
201 : ;; - Don't use a non-nil OVERRIDE unless you have a good reason.
202 : ;; Only use OVERRIDE for special things that are easy to define, such as the
203 : ;; way `...' quotes are treated in strings and comments in Emacs Lisp mode.
204 : ;; Don't use it to, say, highlight keywords in commented out code or strings.
205 : ;; - Err, that's it.
206 :
207 : ;;; Code:
208 :
209 : (require 'syntax)
210 : (eval-when-compile (require 'cl-lib))
211 :
212 : ;; Define core `font-lock' group.
213 : (defgroup font-lock '((jit-lock custom-group))
214 : "Font Lock mode text highlighting package."
215 : :link '(custom-manual :tag "Emacs Manual" "(emacs)Font Lock")
216 : :link '(custom-manual :tag "Elisp Manual" "(elisp)Font Lock Mode")
217 : :group 'faces)
218 :
219 : (defgroup font-lock-faces nil
220 : "Faces for highlighting text."
221 : :prefix "font-lock-"
222 : :group 'font-lock)
223 :
224 : (defgroup font-lock-extra-types nil
225 : "Extra mode-specific type names for highlighting declarations."
226 : :group 'font-lock)
227 :
228 : ;; User variables.
229 :
230 : (defcustom font-lock-maximum-size 256000
231 : "Maximum buffer size for unsupported buffer fontification.
232 : When `font-lock-support-mode' is nil, only buffers smaller than
233 : this are fontified. This variable has no effect if a Font Lock
234 : support mode (usually `jit-lock-mode') is enabled.
235 :
236 : If nil, means size is irrelevant.
237 : If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE),
238 : where MAJOR-MODE is a symbol or t (meaning the default). For example:
239 : ((c-mode . 256000) (c++-mode . 256000) (rmail-mode . 1048576))
240 : means that the maximum size is 250K for buffers in C or C++ modes, one megabyte
241 : for buffers in Rmail mode, and size is irrelevant otherwise."
242 : :type '(choice (const :tag "none" nil)
243 : (integer :tag "size")
244 : (repeat :menu-tag "mode specific" :tag "mode specific"
245 : :value ((t . nil))
246 : (cons :tag "Instance"
247 : (radio :tag "Mode"
248 : (const :tag "all" t)
249 : (symbol :tag "name"))
250 : (radio :tag "Size"
251 : (const :tag "none" nil)
252 : (integer :tag "size")))))
253 : :group 'font-lock)
254 : (make-obsolete-variable 'font-lock-maximum-size nil "24.1")
255 :
256 : (defcustom font-lock-maximum-decoration t
257 : "Maximum decoration level for fontification.
258 : If nil, use the default decoration (typically the minimum available).
259 : If t, use the maximum decoration available.
260 : If a number, use that level of decoration (or if not available the maximum).
261 : The higher the number, the more decoration is done.
262 : If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL),
263 : where MAJOR-MODE is a symbol or t (meaning the default). For example:
264 : ((c-mode . t) (c++-mode . 2) (t . 1))
265 : means use the maximum decoration available for buffers in C mode, level 2
266 : decoration for buffers in C++ mode, and level 1 decoration otherwise."
267 : :type '(choice (const :tag "default" nil)
268 : (const :tag "maximum" t)
269 : (integer :tag "level" 1)
270 : (repeat :menu-tag "mode specific" :tag "mode specific"
271 : :value ((t . t))
272 : (cons :tag "Instance"
273 : (radio :tag "Mode"
274 : (const :tag "all" t)
275 : (symbol :tag "name"))
276 : (radio :tag "Decoration"
277 : (const :tag "default" nil)
278 : (const :tag "maximum" t)
279 : (integer :tag "level" 1)))))
280 : :group 'font-lock)
281 :
282 : (defcustom font-lock-verbose nil
283 : "If non-nil, means show status messages for buffer fontification.
284 : If a number, only buffers greater than this size have fontification messages."
285 : :type '(choice (const :tag "never" nil)
286 : (other :tag "always" t)
287 : (integer :tag "size"))
288 : :group 'font-lock
289 : :version "24.1")
290 :
291 :
292 : ;; Originally these variable values were face names such as `bold' etc.
293 : ;; Now we create our own faces, but we keep these variables for compatibility
294 : ;; and they give users another mechanism for changing face appearance.
295 : ;; We now allow a FACENAME in `font-lock-keywords' to be any expression that
296 : ;; returns a face. So the easiest thing is to continue using these variables,
297 : ;; rather than sometimes evalling FACENAME and sometimes not. sm.
298 :
299 : ;; Note that in new code, in the vast majority of cases there is no
300 : ;; need to create variables that specify face names. Simply using
301 : ;; faces directly is enough. Font-lock is not a template to be
302 : ;; followed in this area.
303 : (defvar font-lock-comment-face 'font-lock-comment-face
304 : "Face name to use for comments.")
305 :
306 : (defvar font-lock-comment-delimiter-face 'font-lock-comment-delimiter-face
307 : "Face name to use for comment delimiters.")
308 :
309 : (defvar font-lock-string-face 'font-lock-string-face
310 : "Face name to use for strings.")
311 :
312 : (defvar font-lock-doc-face 'font-lock-doc-face
313 : "Face name to use for documentation.")
314 :
315 : (defvar font-lock-keyword-face 'font-lock-keyword-face
316 : "Face name to use for keywords.")
317 :
318 : (defvar font-lock-builtin-face 'font-lock-builtin-face
319 : "Face name to use for builtins.")
320 :
321 : (defvar font-lock-function-name-face 'font-lock-function-name-face
322 : "Face name to use for function names.")
323 :
324 : (defvar font-lock-variable-name-face 'font-lock-variable-name-face
325 : "Face name to use for variable names.")
326 :
327 : (defvar font-lock-type-face 'font-lock-type-face
328 : "Face name to use for type and class names.")
329 :
330 : (defvar font-lock-constant-face 'font-lock-constant-face
331 : "Face name to use for constant and label names.")
332 :
333 : (defvar font-lock-warning-face 'font-lock-warning-face
334 : "Face name to use for things that should stand out.")
335 :
336 : (defvar font-lock-negation-char-face 'font-lock-negation-char-face
337 : "Face name to use for easy to overlook negation.
338 : This can be an \"!\" or the \"n\" in \"ifndef\".")
339 :
340 : (defvar font-lock-preprocessor-face 'font-lock-preprocessor-face
341 : "Face name to use for preprocessor directives.")
342 :
343 : (define-obsolete-variable-alias
344 : 'font-lock-reference-face 'font-lock-constant-face "20.3")
345 :
346 : ;; Fontification variables:
347 :
348 : (defvar font-lock-keywords nil
349 : "A list of the keywords to highlight.
350 : There are two kinds of values: user-level, and compiled.
351 :
352 : A user-level keywords list is what a major mode or the user would
353 : set up. Normally the list would come from `font-lock-defaults'.
354 : through selection of a fontification level and evaluation of any
355 : contained expressions. You can also alter it by calling
356 : `font-lock-add-keywords' or `font-lock-remove-keywords' with MODE = nil.
357 :
358 : Each element in a user-level keywords list should have one of these forms:
359 :
360 : MATCHER
361 : (MATCHER . SUBEXP)
362 : (MATCHER . FACENAME)
363 : (MATCHER . HIGHLIGHT)
364 : (MATCHER HIGHLIGHT ...)
365 : (eval . FORM)
366 :
367 : where MATCHER can be either the regexp to search for, or the
368 : function name to call to make the search (called with one
369 : argument, the limit of the search; it should return non-nil, move
370 : point, and set `match-data' appropriately if it succeeds; like
371 : `re-search-forward' would). MATCHER regexps can be generated via
372 : the function `regexp-opt'.
373 :
374 : FORM is an expression, whose value should be a keyword element,
375 : evaluated when the keyword is (first) used in a buffer. This
376 : feature can be used to provide a keyword that can only be
377 : generated when Font Lock mode is actually turned on.
378 :
379 : HIGHLIGHT should be either MATCH-HIGHLIGHT or MATCH-ANCHORED.
380 :
381 : For highlighting single items, for example each instance of the
382 : word \"foo\", typically only MATCH-HIGHLIGHT is required.
383 : However, if an item or (typically) items are to be highlighted
384 : following the instance of another item (the anchor), for example
385 : each instance of the word \"bar\" following the word \"anchor\"
386 : then MATCH-ANCHORED may be required.
387 :
388 : MATCH-HIGHLIGHT should be of the form:
389 :
390 : (SUBEXP FACENAME [OVERRIDE [LAXMATCH]])
391 :
392 : SUBEXP is the number of the subexpression of MATCHER to be
393 : highlighted.
394 :
395 : FACENAME is an expression whose value is the face name to use.
396 : Instead of a face, FACENAME can evaluate to a property list of
397 : the form (face FACE PROP1 VAL1 PROP2 VAL2 ...) in which case all
398 : the listed text-properties will be set rather than just FACE. In
399 : such a case, you will most likely want to put those properties in
400 : `font-lock-extra-managed-props' or to override
401 : `font-lock-unfontify-region-function'.
402 :
403 : OVERRIDE and LAXMATCH are flags. If OVERRIDE is t, existing
404 : fontification can be overwritten. If `keep', only parts not
405 : already fontified are highlighted. If `prepend' or `append',
406 : existing fontification is merged with the new, in which the new
407 : or existing fontification, respectively, takes precedence. If
408 : LAXMATCH is non-nil, that means don't signal an error if there is
409 : no match for SUBEXP in MATCHER.
410 :
411 : For example, an element of the form highlights (if not already
412 : highlighted):
413 :
414 : \"\\\\\\=<foo\\\\\\=>\"
415 : Discrete occurrences of \"foo\" in the value of the variable
416 : `font-lock-keyword-face'.
417 :
418 : (\"fu\\\\(bar\\\\)\" . 1)
419 : Substring \"bar\" within all occurrences of \"fubar\" in the
420 : value of `font-lock-keyword-face'.
421 :
422 : (\"fubar\" . fubar-face)
423 : Occurrences of \"fubar\" in the value of `fubar-face'.
424 :
425 : (\"foo\\\\|bar\" 0 foo-bar-face t)
426 : Occurrences of either \"foo\" or \"bar\" in the value of
427 : `foo-bar-face', even if already highlighted.
428 :
429 : (fubar-match 1 fubar-face)
430 : The first subexpression within all occurrences of whatever the
431 : function `fubar-match' finds and matches in the value of
432 : `fubar-face'.
433 :
434 : MATCH-ANCHORED should be of the form:
435 :
436 : (MATCHER PRE-MATCH-FORM POST-MATCH-FORM MATCH-HIGHLIGHT ...)
437 :
438 : where MATCHER is a regexp to search for or the function name to
439 : call to make the search, as for MATCH-HIGHLIGHT above, but with
440 : one exception; see below. PRE-MATCH-FORM and POST-MATCH-FORM are
441 : evaluated before the first, and after the last, instance
442 : MATCH-ANCHORED's MATCHER is used. Therefore they can be used to
443 : initialize before, and cleanup after, MATCHER is used.
444 : Typically, PRE-MATCH-FORM is used to move to some position
445 : relative to the original MATCHER, before starting with
446 : MATCH-ANCHORED's MATCHER. POST-MATCH-FORM might be used to move
447 : back, before resuming with MATCH-ANCHORED's parent's MATCHER.
448 :
449 : For example, an element of the form highlights (if not already
450 : highlighted):
451 :
452 : (\"\\\\\\=<anchor\\\\\\=>\" (0 anchor-face)
453 : (\"\\\\\\=<item\\\\\\=>\" nil nil (0 item-face)))
454 :
455 : Discrete occurrences of \"anchor\" in the value of
456 : `anchor-face', and subsequent discrete occurrences of
457 : \"item\" (on the same line) in the value of `item-face'.
458 : (Here PRE-MATCH-FORM and POST-MATCH-FORM are nil. Therefore
459 : \"item\" is initially searched for starting from the end of the
460 : match of \"anchor\", and searching for subsequent instances of
461 : \"anchor\" resumes from where searching for \"item\" concluded.)
462 :
463 : The above-mentioned exception is as follows. The limit of the
464 : MATCHER search defaults to the end of the line after
465 : PRE-MATCH-FORM is evaluated. However, if PRE-MATCH-FORM returns
466 : a position greater than the position after PRE-MATCH-FORM is
467 : evaluated, that position is used as the limit of the search. It
468 : is generally a bad idea to return a position greater than the end
469 : of the line, i.e., cause the MATCHER search to span lines.
470 :
471 : These regular expressions can match text which spans lines,
472 : although it is better to avoid it if possible since updating them
473 : while editing text is slower, and it is not guaranteed to be
474 : always correct when using support modes like jit-lock or
475 : lazy-lock.
476 :
477 : This variable is set by major modes via the variable
478 : `font-lock-defaults'. Be careful when composing regexps for this
479 : list; a poorly written pattern can dramatically slow things down!
480 :
481 : A compiled keywords list starts with t. It is produced
482 : internally by `font-lock-compile-keywords' from a user-level
483 : keywords list. Its second element is the user-level keywords
484 : list that was compiled. The remaining elements have the same
485 : form as user-level keywords, but normally their values have been
486 : optimized.")
487 :
488 : (defvar font-lock-keywords-alist nil
489 : "Alist of additional `font-lock-keywords' elements for major modes.
490 :
491 : Each element has the form (MODE KEYWORDS . HOW).
492 : Function `font-lock-set-defaults' adds the elements in the list KEYWORDS to
493 : `font-lock-keywords' when Font Lock is turned on in major mode MODE.
494 :
495 : If HOW is nil, KEYWORDS are added at the beginning of
496 : `font-lock-keywords'. If it is `set', they are used to replace the
497 : value of `font-lock-keywords'. If HOW is any other non-nil value,
498 : they are added at the end.
499 :
500 : This is normally set via `font-lock-add-keywords' and
501 : `font-lock-remove-keywords'.")
502 : (put 'font-lock-keywords-alist 'risky-local-variable t)
503 :
504 : (defvar font-lock-removed-keywords-alist nil
505 : "Alist of `font-lock-keywords' elements to be removed for major modes.
506 :
507 : Each element has the form (MODE . KEYWORDS). Function `font-lock-set-defaults'
508 : removes the elements in the list KEYWORDS from `font-lock-keywords'
509 : when Font Lock is turned on in major mode MODE.
510 :
511 : This is normally set via `font-lock-add-keywords' and
512 : `font-lock-remove-keywords'.")
513 :
514 : (defvar font-lock-keywords-only nil
515 : "Non-nil means Font Lock should not fontify comments or strings.
516 : This is normally set via `font-lock-defaults'.")
517 :
518 : (defvar font-lock-keywords-case-fold-search nil
519 : "Non-nil means the patterns in `font-lock-keywords' are case-insensitive.
520 : This is set via the function `font-lock-set-defaults', based on
521 : the CASE-FOLD argument of `font-lock-defaults'.")
522 : (make-variable-buffer-local 'font-lock-keywords-case-fold-search)
523 :
524 : (defvar font-lock-syntactically-fontified 0
525 : "Point up to which `font-lock-syntactic-keywords' has been applied.
526 : If nil, this is ignored, in which case the syntactic fontification may
527 : sometimes be slightly incorrect.")
528 : (make-variable-buffer-local 'font-lock-syntactically-fontified)
529 :
530 : (defvar font-lock-syntactic-face-function
531 : (lambda (state)
532 : (if (nth 3 state) font-lock-string-face font-lock-comment-face))
533 : "Function to determine which face to use when fontifying syntactically.
534 : The function is called with a single parameter (the state as returned by
535 : `parse-partial-sexp' at the beginning of the region to highlight) and
536 : should return a face. This is normally set via `font-lock-defaults'.")
537 :
538 : (defvar font-lock-syntactic-keywords nil
539 : "A list of the syntactic keywords to put syntax properties on.
540 : The value can be the list itself, or the name of a function or variable
541 : whose value is the list.
542 :
543 : See `font-lock-keywords' for a description of the form of this list;
544 : only the differences are stated here. MATCH-HIGHLIGHT should be of the form:
545 :
546 : (SUBEXP SYNTAX OVERRIDE LAXMATCH)
547 :
548 : where SYNTAX can be a string (as taken by `modify-syntax-entry'), a syntax
549 : table, a cons cell (as returned by `string-to-syntax') or an expression whose
550 : value is such a form. OVERRIDE cannot be `prepend' or `append'.
551 :
552 : Here are two examples of elements of `font-lock-syntactic-keywords'
553 : and what they do:
554 :
555 : (\"\\\\$\\\\(#\\\\)\" 1 \".\")
556 :
557 : gives a hash character punctuation syntax (\".\") when following a
558 : dollar-sign character. Hash characters in other contexts will still
559 : follow whatever the syntax table says about the hash character.
560 :
561 : (\"\\\\(\\='\\\\).\\\\(\\='\\\\)\"
562 : (1 \"\\\"\")
563 : (2 \"\\\"\"))
564 :
565 : gives a pair of apostrophes, which surround a single character, a
566 : SYNTAX of \"\\\"\" (meaning string quote syntax). Apostrophes in other
567 :
568 : contexts will not be affected.
569 :
570 : This is normally set via `font-lock-defaults'.")
571 : (make-obsolete-variable 'font-lock-syntactic-keywords
572 : 'syntax-propertize-function "24.1")
573 :
574 : (defvar font-lock-syntax-table nil
575 : "Non-nil means use this syntax table for fontifying.
576 : If this is nil, the major mode's syntax table is used.
577 : This is normally set via `font-lock-defaults'.")
578 :
579 : (defvar font-lock-mark-block-function nil
580 : "Non-nil means use this function to mark a block of text.
581 : When called with no args it should leave point at the beginning of any
582 : enclosing textual block and mark at the end.
583 : This is normally set via `font-lock-defaults'.")
584 :
585 : (defvar font-lock-fontify-buffer-function #'font-lock-default-fontify-buffer
586 : "Function to use for fontifying the buffer.
587 : This is normally set via `font-lock-defaults'.")
588 :
589 : (defvar font-lock-unfontify-buffer-function #'font-lock-default-unfontify-buffer
590 : "Function to use for unfontifying the buffer.
591 : This is used when turning off Font Lock mode.
592 : This is normally set via `font-lock-defaults'.")
593 :
594 : (defvar font-lock-fontify-region-function #'font-lock-default-fontify-region
595 : "Function to use for fontifying a region.
596 : It should take two args, the beginning and end of the region, and an optional
597 : third arg VERBOSE. If VERBOSE is non-nil, the function should print status
598 : messages. This is normally set via `font-lock-defaults'.
599 : If it fontifies a larger region, it should ideally return a list of the form
600 : \(jit-lock-bounds BEG . END) indicating the bounds of the region actually
601 : fontified.")
602 :
603 : (defvar font-lock-unfontify-region-function #'font-lock-default-unfontify-region
604 : "Function to use for unfontifying a region.
605 : It should take two args, the beginning and end of the region.
606 : This is normally set via `font-lock-defaults'.")
607 :
608 : (defvar font-lock-inhibit-thing-lock nil
609 : "List of Font Lock mode related modes that should not be turned on.
610 : Currently, valid mode names are `fast-lock-mode', `jit-lock-mode' and
611 : `lazy-lock-mode'. This is normally set via `font-lock-defaults'.")
612 : (make-obsolete-variable 'font-lock-inhibit-thing-lock nil "25.1")
613 :
614 : (defvar-local font-lock-multiline nil
615 : "Whether font-lock should cater to multiline keywords.
616 : If nil, don't try to handle multiline patterns.
617 : If t, always handle multiline patterns.
618 : If `undecided', don't try to handle multiline patterns until you see one.
619 : Major/minor modes can set this variable if they know which option applies.")
620 :
621 : (defvar-local font-lock-fontified nil) ; Whether we have fontified the buffer.
622 :
623 : ;; Font Lock mode.
624 :
625 : (eval-when-compile
626 : ;;
627 : ;; Borrowed from lazy-lock.el.
628 : ;; We use this to preserve or protect things when modifying text properties.
629 : (defmacro save-buffer-state (&rest body)
630 : "Bind variables according to VARLIST and eval BODY restoring buffer state."
631 : (declare (indent 0) (debug t))
632 : `(let ((inhibit-point-motion-hooks t))
633 : (with-silent-modifications
634 : ,@body)))
635 : ;;
636 : ;; Shut up the byte compiler.
637 : (defvar font-lock-face-attributes)) ; Obsolete but respected if set.
638 :
639 : (defvar-local font-lock-set-defaults nil) ; Whether we have set up defaults.
640 :
641 : (defun font-lock-specified-p (mode)
642 : "Return non-nil if the current buffer is ready for fontification.
643 : The MODE argument, if non-nil, means Font Lock mode is about to
644 : be enabled."
645 0 : (or font-lock-defaults
646 0 : (and (boundp 'font-lock-keywords)
647 0 : font-lock-keywords)
648 0 : (and mode
649 0 : font-lock-set-defaults
650 0 : font-lock-major-mode
651 0 : (not (eq font-lock-major-mode major-mode)))))
652 :
653 : (defun font-lock-initial-fontify ()
654 : ;; The first fontification after turning the mode on. This must
655 : ;; only be called after the mode hooks have been run.
656 0 : (when (and font-lock-mode
657 0 : (font-lock-specified-p t))
658 0 : (let ((max-size (font-lock-value-in-major-mode font-lock-maximum-size)))
659 0 : (cond (font-lock-fontified
660 : nil)
661 0 : ((or (null max-size) (> max-size (buffer-size)))
662 0 : (font-lock-fontify-buffer))
663 0 : (font-lock-verbose
664 0 : (message "Fontifying %s...buffer size greater than font-lock-maximum-size"
665 0 : (buffer-name)))))))
666 :
667 : (defun font-lock-mode-internal (arg)
668 : ;; Turn on Font Lock mode.
669 0 : (when arg
670 0 : (add-hook 'after-change-functions #'font-lock-after-change-function t t)
671 0 : (font-lock-set-defaults)
672 0 : (font-lock-turn-on-thing-lock))
673 : ;; Turn off Font Lock mode.
674 0 : (unless font-lock-mode
675 0 : (remove-hook 'after-change-functions #'font-lock-after-change-function t)
676 0 : (font-lock-unfontify-buffer)
677 0 : (font-lock-turn-off-thing-lock)))
678 :
679 : (defun font-lock-add-keywords (mode keywords &optional how)
680 : "Add highlighting KEYWORDS for MODE.
681 :
682 : MODE should be a symbol, the major mode command name, such as `c-mode'
683 : or nil. If nil, highlighting keywords are added for the current buffer.
684 : KEYWORDS should be a list; see the variable `font-lock-keywords'.
685 : By default they are added at the beginning of the current highlighting list.
686 : If optional argument HOW is `set', they are used to replace the current
687 : highlighting list. If HOW is any other non-nil value, they are added at the
688 : end of the current highlighting list.
689 :
690 : For example:
691 :
692 : (font-lock-add-keywords \\='c-mode
693 : \\='((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 \\='font-lock-warning-face prepend)
694 : (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" . \\='font-lock-keyword-face)))
695 :
696 : adds two fontification patterns for C mode, to fontify `FIXME:' words, even in
697 : comments, and to fontify `and', `or' and `not' words as keywords.
698 :
699 : The above procedure will only add the keywords for C mode, not
700 : for modes derived from C mode. To add them for derived modes too,
701 : pass nil for MODE and add the call to c-mode-hook.
702 :
703 : For example:
704 :
705 : (add-hook \\='c-mode-hook
706 : (lambda ()
707 : (font-lock-add-keywords nil
708 : \\='((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 \\='font-lock-warning-face prepend)
709 : (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" .
710 : \\='font-lock-keyword-face)))))
711 :
712 : The above procedure may fail to add keywords to derived modes if
713 : some involved major mode does not follow the standard conventions.
714 : File a bug report if this happens, so the major mode can be corrected.
715 :
716 : Note that some modes have specialized support for additional patterns, e.g.,
717 : see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types',
718 : `objc-font-lock-extra-types' and `java-font-lock-extra-types'."
719 236 : (cond (mode
720 : ;; If MODE is non-nil, add the KEYWORDS and HOW spec to
721 : ;; `font-lock-keywords-alist' so `font-lock-set-defaults' uses them.
722 12 : (let ((spec (cons keywords how)) cell)
723 12 : (if (setq cell (assq mode font-lock-keywords-alist))
724 11 : (if (eq how 'set)
725 0 : (setcdr cell (list spec))
726 11 : (setcdr cell (append (cdr cell) (list spec))))
727 12 : (push (list mode spec) font-lock-keywords-alist)))
728 : ;; Make sure that `font-lock-removed-keywords-alist' does not
729 : ;; contain the new keywords.
730 12 : (font-lock-update-removed-keyword-alist mode keywords how))
731 : (t
732 224 : (when (and font-lock-mode
733 224 : (not (or font-lock-keywords font-lock-defaults)))
734 : ;; The major mode has not set any keywords, so when we enabled
735 : ;; font-lock-mode it only enabled the font-core.el part, not the
736 : ;; font-lock-mode-internal. Try again.
737 0 : (font-lock-mode -1)
738 0 : (set (make-local-variable 'font-lock-defaults) '(nil t))
739 224 : (font-lock-mode 1))
740 : ;; Otherwise set or add the keywords now.
741 : ;; This is a no-op if it has been done already in this buffer
742 : ;; for the correct major mode.
743 224 : (font-lock-set-defaults)
744 224 : (let ((was-compiled (eq (car font-lock-keywords) t)))
745 : ;; Bring back the user-level (uncompiled) keywords.
746 224 : (if was-compiled
747 224 : (setq font-lock-keywords (cadr font-lock-keywords)))
748 : ;; Now modify or replace them.
749 224 : (if (eq how 'set)
750 0 : (setq font-lock-keywords keywords)
751 224 : (font-lock-remove-keywords nil keywords) ;to avoid duplicates
752 224 : (let ((old (if (eq (car-safe font-lock-keywords) t)
753 0 : (cdr font-lock-keywords)
754 224 : font-lock-keywords)))
755 224 : (setq font-lock-keywords (if how
756 0 : (append old keywords)
757 224 : (append keywords old)))))
758 : ;; If the keywords were compiled before, compile them again.
759 224 : (if was-compiled
760 36 : (setq font-lock-keywords
761 236 : (font-lock-compile-keywords font-lock-keywords)))))))
762 :
763 : (defun font-lock-update-removed-keyword-alist (mode keywords how)
764 : "Update `font-lock-removed-keywords-alist' when adding new KEYWORDS to MODE."
765 : ;; When font-lock is enabled first all keywords in the list
766 : ;; `font-lock-keywords-alist' are added, then all keywords in the
767 : ;; list `font-lock-removed-keywords-alist' are removed. If a
768 : ;; keyword was once added, removed, and then added again it must be
769 : ;; removed from the removed-keywords list. Otherwise the second add
770 : ;; will not take effect.
771 12 : (let ((cell (assq mode font-lock-removed-keywords-alist)))
772 12 : (if cell
773 0 : (if (eq how 'set)
774 : ;; A new set of keywords is defined. Forget all about
775 : ;; our old keywords that should be removed.
776 0 : (setq font-lock-removed-keywords-alist
777 0 : (delq cell font-lock-removed-keywords-alist))
778 : ;; Delete all previously removed keywords.
779 0 : (dolist (kword keywords)
780 0 : (setcdr cell (delete kword (cdr cell))))
781 : ;; Delete the mode cell if empty.
782 0 : (if (null (cdr cell))
783 0 : (setq font-lock-removed-keywords-alist
784 12 : (delq cell font-lock-removed-keywords-alist)))))))
785 :
786 : ;; Written by Anders Lindgren
787 : ;;
788 : ;; Case study:
789 : ;; (I) The keywords are removed from a major mode.
790 : ;; In this case the keyword could be local (i.e. added earlier by
791 : ;; `font-lock-add-keywords'), global, or both.
792 : ;;
793 : ;; (a) In the local case we remove the keywords from the variable
794 : ;; `font-lock-keywords-alist'.
795 : ;;
796 : ;; (b) The actual global keywords are not known at this time.
797 : ;; All keywords are added to `font-lock-removed-keywords-alist',
798 : ;; when font-lock is enabled those keywords are removed.
799 : ;;
800 : ;; Note that added keywords are taken out of the list of removed
801 : ;; keywords. This ensure correct operation when the same keyword
802 : ;; is added and removed several times.
803 : ;;
804 : ;; (II) The keywords are removed from the current buffer.
805 : (defun font-lock-remove-keywords (mode keywords)
806 : "Remove highlighting KEYWORDS for MODE.
807 :
808 : MODE should be a symbol, the major mode command name, such as
809 : `c-mode' or nil. If nil, highlighting keywords are removed for
810 : the current buffer.
811 :
812 : For a description of KEYWORDS, see `font-lock-add-keywords'.
813 :
814 : To make the removal apply to modes derived from MODE as well,
815 : pass nil for MODE and add the call to MODE-hook. This may fail
816 : for some derived modes if some involved major mode does not
817 : follow the standard conventions. File a bug report if this
818 : happens, so the major mode can be corrected."
819 224 : (cond (mode
820 : ;; Remove one keyword at the time.
821 0 : (dolist (keyword keywords)
822 0 : (let ((top-cell (assq mode font-lock-keywords-alist)))
823 : ;; If MODE is non-nil, remove the KEYWORD from
824 : ;; `font-lock-keywords-alist'.
825 0 : (when top-cell
826 0 : (dolist (keyword-list-how-pair (cdr top-cell))
827 : ;; `keywords-list-how-pair' is a cons with a list of
828 : ;; keywords in the car top-cell and the original how
829 : ;; argument in the cdr top-cell.
830 0 : (setcar keyword-list-how-pair
831 0 : (delete keyword (car keyword-list-how-pair))))
832 : ;; Remove keyword list/how pair when the keyword list
833 : ;; is empty and how doesn't specify `set'. (If it
834 : ;; should be deleted then previously deleted keywords
835 : ;; would appear again.)
836 0 : (let ((cell top-cell))
837 0 : (while (cdr cell)
838 0 : (if (and (null (car (car (cdr cell))))
839 0 : (not (eq (cdr (car (cdr cell))) 'set)))
840 0 : (setcdr cell (cdr (cdr cell)))
841 0 : (setq cell (cdr cell)))))
842 : ;; Final cleanup, remove major mode cell if last keyword
843 : ;; was deleted.
844 0 : (if (null (cdr top-cell))
845 0 : (setq font-lock-keywords-alist
846 0 : (delq top-cell font-lock-keywords-alist))))
847 : ;; Remember the keyword in case it is not local.
848 0 : (let ((cell (assq mode font-lock-removed-keywords-alist)))
849 0 : (if cell
850 0 : (unless (member keyword (cdr cell))
851 0 : (nconc cell (list keyword)))
852 0 : (push (cons mode (list keyword))
853 0 : font-lock-removed-keywords-alist))))))
854 : (t
855 : ;; Otherwise remove it immediately.
856 224 : (font-lock-set-defaults)
857 224 : (let ((was-compiled (eq (car font-lock-keywords) t)))
858 : ;; Bring back the user-level (uncompiled) keywords.
859 224 : (if was-compiled
860 224 : (setq font-lock-keywords (cadr font-lock-keywords)))
861 :
862 : ;; Edit them.
863 224 : (setq font-lock-keywords (copy-sequence font-lock-keywords))
864 224 : (dolist (keyword keywords)
865 224 : (setq font-lock-keywords
866 224 : (delete keyword font-lock-keywords)))
867 :
868 : ;; If the keywords were compiled before, compile them again.
869 224 : (if was-compiled
870 0 : (setq font-lock-keywords
871 224 : (font-lock-compile-keywords font-lock-keywords)))))))
872 :
873 : ;;; Font Lock Support mode.
874 :
875 : ;; This is the code used to interface font-lock.el with any of its add-on
876 : ;; packages, and provide the user interface. Packages that have their own
877 : ;; local buffer fontification functions (see below) may have to call
878 : ;; `font-lock-after-fontify-buffer' and/or `font-lock-after-unfontify-buffer'
879 : ;; themselves.
880 :
881 : (defcustom font-lock-support-mode 'jit-lock-mode
882 : "Support mode for Font Lock mode.
883 : Support modes speed up Font Lock mode by being choosy about when fontification
884 : occurs. The default support mode, Just-in-time Lock mode (symbol
885 : `jit-lock-mode'), is recommended.
886 :
887 : Other, older support modes are Fast Lock mode (symbol `fast-lock-mode') and
888 : Lazy Lock mode (symbol `lazy-lock-mode'). See those modes for more info.
889 : However, they are no longer recommended, as Just-in-time Lock mode is better.
890 :
891 : If nil, means support for Font Lock mode is never performed.
892 : If a symbol, use that support mode.
893 : If a list, each element should be of the form (MAJOR-MODE . SUPPORT-MODE),
894 : where MAJOR-MODE is a symbol or t (meaning the default). For example:
895 : ((c-mode . fast-lock-mode) (c++-mode . fast-lock-mode) (t . lazy-lock-mode))
896 : means that Fast Lock mode is used to support Font Lock mode for buffers in C or
897 : C++ modes, and Lazy Lock mode is used to support Font Lock mode otherwise.
898 :
899 : The value of this variable is used when Font Lock mode is turned on."
900 : :type '(choice (const :tag "none" nil)
901 : (const :tag "fast lock" fast-lock-mode)
902 : (const :tag "lazy lock" lazy-lock-mode)
903 : (const :tag "jit lock" jit-lock-mode)
904 : (repeat :menu-tag "mode specific" :tag "mode specific"
905 : :value ((t . jit-lock-mode))
906 : (cons :tag "Instance"
907 : (radio :tag "Mode"
908 : (const :tag "all" t)
909 : (symbol :tag "name"))
910 : (radio :tag "Support"
911 : (const :tag "none" nil)
912 : (const :tag "fast lock" fast-lock-mode)
913 : (const :tag "lazy lock" lazy-lock-mode)
914 : (const :tag "JIT lock" jit-lock-mode)))
915 : ))
916 : :version "21.1"
917 : :group 'font-lock)
918 :
919 : (defvar fast-lock-mode)
920 : (defvar lazy-lock-mode)
921 : (defvar jit-lock-mode)
922 :
923 : (declare-function fast-lock-after-fontify-buffer "fast-lock")
924 : (declare-function fast-lock-after-unfontify-buffer "fast-lock")
925 : (declare-function fast-lock-mode "fast-lock")
926 : (declare-function lazy-lock-after-fontify-buffer "lazy-lock")
927 : (declare-function lazy-lock-after-unfontify-buffer "lazy-lock")
928 : (declare-function lazy-lock-mode "lazy-lock")
929 :
930 : (defun font-lock-turn-on-thing-lock ()
931 0 : (pcase (font-lock-value-in-major-mode font-lock-support-mode)
932 0 : (`fast-lock-mode (fast-lock-mode t))
933 0 : (`lazy-lock-mode (lazy-lock-mode t))
934 : (`jit-lock-mode
935 : ;; Prepare for jit-lock
936 0 : (remove-hook 'after-change-functions
937 0 : #'font-lock-after-change-function t)
938 0 : (set (make-local-variable 'font-lock-flush-function)
939 0 : #'jit-lock-refontify)
940 0 : (set (make-local-variable 'font-lock-ensure-function)
941 0 : #'jit-lock-fontify-now)
942 : ;; Prevent font-lock-fontify-buffer from fontifying eagerly the whole
943 : ;; buffer. This is important for things like CWarn mode which
944 : ;; adds/removes a few keywords and does a refontify (which takes ages on
945 : ;; large files).
946 0 : (set (make-local-variable 'font-lock-fontify-buffer-function)
947 0 : #'jit-lock-refontify)
948 : ;; Don't fontify eagerly (and don't abort if the buffer is large).
949 0 : (set (make-local-variable 'font-lock-fontified) t)
950 : ;; Use jit-lock.
951 0 : (jit-lock-register #'font-lock-fontify-region
952 0 : (not font-lock-keywords-only))
953 : ;; Tell jit-lock how we extend the region to refontify.
954 0 : (add-hook 'jit-lock-after-change-extend-region-functions
955 0 : #'font-lock-extend-jit-lock-region-after-change
956 0 : nil t))))
957 :
958 : (defun font-lock-turn-off-thing-lock ()
959 0 : (cond ((bound-and-true-p fast-lock-mode)
960 0 : (fast-lock-mode -1))
961 0 : ((bound-and-true-p jit-lock-mode)
962 0 : (jit-lock-unregister 'font-lock-fontify-region)
963 : ;; Reset local vars to the non-jit-lock case.
964 0 : (kill-local-variable 'font-lock-fontify-buffer-function))
965 0 : ((bound-and-true-p lazy-lock-mode)
966 0 : (lazy-lock-mode -1))))
967 :
968 : (defun font-lock-after-fontify-buffer ()
969 0 : (cond ((bound-and-true-p fast-lock-mode)
970 0 : (fast-lock-after-fontify-buffer))
971 : ;; Useless now that jit-lock intercepts font-lock-fontify-buffer. -sm
972 : ;; (jit-lock-mode
973 : ;; (jit-lock-after-fontify-buffer))
974 0 : ((bound-and-true-p lazy-lock-mode)
975 0 : (lazy-lock-after-fontify-buffer))))
976 :
977 : (defun font-lock-after-unfontify-buffer ()
978 0 : (cond ((bound-and-true-p fast-lock-mode)
979 0 : (fast-lock-after-unfontify-buffer))
980 : ;; Useless as well. It's only called when:
981 : ;; - turning off font-lock: it does not matter if we leave spurious
982 : ;; `fontified' text props around since jit-lock-mode is also off.
983 : ;; - font-lock-default-fontify-buffer fails: this is not run
984 : ;; any more anyway. -sm
985 : ;;
986 : ;; (jit-lock-mode
987 : ;; (jit-lock-after-unfontify-buffer))
988 0 : ((bound-and-true-p lazy-lock-mode)
989 0 : (lazy-lock-after-unfontify-buffer))))
990 :
991 : ;;; End of Font Lock Support mode.
992 :
993 : ;;; Fontification functions.
994 :
995 : ;; Rather than the function, e.g., `font-lock-fontify-region' containing the
996 : ;; code to fontify a region, the function runs the function whose name is the
997 : ;; value of the variable, e.g., `font-lock-fontify-region-function'. Normally,
998 : ;; the value of this variable is, e.g., `font-lock-default-fontify-region'
999 : ;; which does contain the code to fontify a region. However, the value of the
1000 : ;; variable could be anything and thus, e.g., `font-lock-fontify-region' could
1001 : ;; do anything. The indirection of the fontification functions gives major
1002 : ;; modes the capability of modifying the way font-lock.el fontifies. Major
1003 : ;; modes can modify the values of, e.g., `font-lock-fontify-region-function',
1004 : ;; via the variable `font-lock-defaults'.
1005 : ;;
1006 : ;; For example, Rmail mode sets the variable `font-lock-defaults' so that
1007 : ;; font-lock.el uses its own function for buffer fontification. This function
1008 : ;; makes fontification be on a message-by-message basis and so visiting an
1009 : ;; RMAIL file is much faster. A clever implementation of the function might
1010 : ;; fontify the headers differently than the message body. (It should, and
1011 : ;; correspondingly for Mail mode, but I can't be bothered to do the work. Can
1012 : ;; you?) This hints at a more interesting use...
1013 : ;;
1014 : ;; Languages that contain text normally contained in different major modes
1015 : ;; could define their own fontification functions that treat text differently
1016 : ;; depending on its context. For example, Perl mode could arrange that here
1017 : ;; docs are fontified differently than Perl code. Or Yacc mode could fontify
1018 : ;; rules one way and C code another. Neat!
1019 : ;;
1020 : ;; A further reason to use the fontification indirection feature is when the
1021 : ;; default syntactic fontification, or the default fontification in general,
1022 : ;; is not flexible enough for a particular major mode. For example, perhaps
1023 : ;; comments are just too hairy for `font-lock-fontify-syntactically-region' to
1024 : ;; cope with. You need to write your own version of that function, e.g.,
1025 : ;; `hairy-fontify-syntactically-region', and make your own version of
1026 : ;; `hairy-fontify-region' call that function before calling
1027 : ;; `font-lock-fontify-keywords-region' for the normal regexp fontification
1028 : ;; pass. And Hairy mode would set `font-lock-defaults' so that font-lock.el
1029 : ;; would call your region fontification function instead of its own. For
1030 : ;; example, TeX modes could fontify {\foo ...} and \bar{...} etc. multi-line
1031 : ;; directives correctly and cleanly. (It is the same problem as fontifying
1032 : ;; multi-line strings and comments; regexps are not appropriate for the job.)
1033 :
1034 : (defvar font-lock-extend-after-change-region-function nil
1035 : "A function that determines the region to refontify after a change.
1036 :
1037 : This variable is either nil, or is a function that determines the
1038 : region to refontify after a change.
1039 : It is usually set by the major mode via `font-lock-defaults'.
1040 : Font-lock calls this function after each buffer change.
1041 :
1042 : The function is given three parameters, the standard BEG, END, and OLD-LEN
1043 : from `after-change-functions'. It should return either a cons of the beginning
1044 : and end buffer positions \(in that order) of the region to refontify, or nil
1045 : \(which directs the caller to fontify a default region).
1046 : This function should preserve the match-data.
1047 : The region it returns may start or end in the middle of a line.")
1048 : (make-variable-buffer-local 'font-lock-extend-after-change-region-function)
1049 :
1050 : (defun font-lock-fontify-buffer (&optional interactively)
1051 : "Fontify the current buffer the way the function `font-lock-mode' would."
1052 : (declare
1053 : ;; When called from Lisp, this function is a big mess. The caller usually
1054 : ;; expects one of the following behaviors:
1055 : ;; - refresh the highlighting (because the font-lock-keywords have been
1056 : ;; changed).
1057 : ;; - apply font-lock highlighting even if font-lock-mode is not enabled.
1058 : ;; - reset the highlighting rules because font-lock-defaults
1059 : ;; has been changed (and then rehighlight everything).
1060 : ;; Of course, this function doesn't do all of the above in all situations
1061 : ;; (e.g. depending on whether jit-lock is in use) and it can't guess what
1062 : ;; the caller wants.
1063 : (interactive-only "use `font-lock-ensure' or `font-lock-flush' instead."))
1064 : (interactive "p")
1065 0 : (font-lock-set-defaults)
1066 0 : (let ((font-lock-verbose (or font-lock-verbose interactively)))
1067 0 : (funcall font-lock-fontify-buffer-function)))
1068 :
1069 : (defun font-lock-unfontify-buffer ()
1070 0 : (funcall font-lock-unfontify-buffer-function))
1071 :
1072 : (defun font-lock-fontify-region (beg end &optional loudly)
1073 : "Fontify the text between BEG and END.
1074 : If LOUDLY is non-nil, print status messages while fontifying.
1075 : This works by calling `font-lock-fontify-region-function'."
1076 0 : (font-lock-set-defaults)
1077 0 : (funcall font-lock-fontify-region-function beg end loudly))
1078 :
1079 : (defun font-lock-unfontify-region (beg end)
1080 : "Unfontify the text between BEG and END.
1081 : This works by calling `font-lock-unfontify-region-function'."
1082 0 : (save-buffer-state
1083 0 : (funcall font-lock-unfontify-region-function beg end)))
1084 :
1085 : (defvar font-lock-flush-function #'font-lock-after-change-function
1086 : "Function to use to mark a region for refontification.
1087 : Called with two arguments BEG and END.")
1088 :
1089 : (defun font-lock-flush (&optional beg end)
1090 : "Declare the region BEG...END's fontification as out-of-date.
1091 : If the region is not specified, it defaults to the entire
1092 : accessible portion of the current buffer."
1093 8068 : (and font-lock-mode
1094 0 : font-lock-fontified
1095 0 : (funcall font-lock-flush-function
1096 8068 : (or beg (point-min)) (or end (point-max)))))
1097 :
1098 : (defvar font-lock-ensure-function
1099 : (lambda (_beg _end)
1100 : (unless font-lock-fontified
1101 : (font-lock-default-fontify-buffer)
1102 : (unless font-lock-mode
1103 : ;; If font-lock is not enabled, we don't have the hooks in place to
1104 : ;; track modifications, so a subsequent call to font-lock-ensure can't
1105 : ;; assume that the fontification is still valid.
1106 : (setq font-lock-fontified nil))))
1107 : "Function to make sure a region has been fontified.
1108 : Called with two arguments BEG and END.")
1109 :
1110 : (defun font-lock-ensure (&optional beg end)
1111 : "Make sure the region BEG...END has been fontified.
1112 : If the region is not specified, it defaults to the entire accessible
1113 : portion of the buffer."
1114 0 : (font-lock-set-defaults)
1115 0 : (funcall font-lock-ensure-function
1116 0 : (or beg (point-min)) (or end (point-max))))
1117 :
1118 : (defun font-lock-default-fontify-buffer ()
1119 : "Fontify the whole buffer using `font-lock-fontify-region-function'."
1120 0 : (let ((verbose (if (numberp font-lock-verbose)
1121 0 : (> (buffer-size) font-lock-verbose)
1122 0 : font-lock-verbose)))
1123 0 : (with-temp-message
1124 0 : (when verbose
1125 0 : (format "Fontifying %s..." (buffer-name)))
1126 : ;; Make sure we fontify etc. in the whole buffer.
1127 0 : (save-restriction
1128 0 : (unless font-lock-dont-widen (widen))
1129 0 : (condition-case nil
1130 0 : (save-excursion
1131 0 : (save-match-data
1132 0 : (font-lock-fontify-region (point-min) (point-max) verbose)
1133 0 : (font-lock-after-fontify-buffer)
1134 0 : (setq font-lock-fontified t)))
1135 : ;; We don't restore the old fontification, so it's best to unfontify.
1136 0 : (quit (font-lock-unfontify-buffer)))))))
1137 :
1138 : (defun font-lock-default-unfontify-buffer ()
1139 : "Unfontify the whole buffer using `font-lock-unfontify-region-function'."
1140 : ;; Make sure we unfontify etc. in the whole buffer.
1141 0 : (save-restriction
1142 0 : (widen)
1143 0 : (font-lock-unfontify-region (point-min) (point-max))
1144 0 : (font-lock-after-unfontify-buffer)
1145 0 : (setq font-lock-fontified nil)))
1146 :
1147 : (defvar font-lock-dont-widen nil
1148 : "If non-nil, font-lock will work on the non-widened buffer.
1149 : Useful for things like RMAIL and Info where the whole buffer is not
1150 : a very meaningful entity to highlight.")
1151 :
1152 :
1153 : (defvar font-lock-beg) (defvar font-lock-end)
1154 : (defvar font-lock-extend-region-functions
1155 : '(font-lock-extend-region-wholelines
1156 : ;; This use of font-lock-multiline property is unreliable but is just
1157 : ;; a handy heuristic: in case you don't have a function that does
1158 : ;; /identification/ of multiline elements, you may still occasionally
1159 : ;; discover them by accident (or you may /identify/ them but not in all
1160 : ;; cases), in which case the font-lock-multiline property can help make
1161 : ;; sure you will properly *re*identify them during refontification.
1162 : font-lock-extend-region-multiline)
1163 : "Special hook run just before proceeding to fontify a region.
1164 : This is used to allow major modes to help font-lock find safe buffer positions
1165 : as beginning and end of the fontified region. Its most common use is to solve
1166 : the problem of /identification/ of multiline elements by providing a function
1167 : that tries to find such elements and move the boundaries such that they do
1168 : not fall in the middle of one.
1169 : Each function is called with no argument; it is expected to adjust the
1170 : dynamically bound variables `font-lock-beg' and `font-lock-end'; and return
1171 : non-nil if it did make such an adjustment.
1172 : These functions are run in turn repeatedly until they all return nil.
1173 : Put first the functions more likely to cause a change and cheaper to compute.")
1174 : ;; Mark it as a special hook which doesn't use any global setting
1175 : ;; (i.e. doesn't obey the element t in the buffer-local value).
1176 : (make-variable-buffer-local 'font-lock-extend-region-functions)
1177 :
1178 : (defun font-lock-extend-region-multiline ()
1179 : "Move fontification boundaries away from any `font-lock-multiline' property."
1180 0 : (let ((changed nil))
1181 0 : (when (and (> font-lock-beg (point-min))
1182 0 : (get-text-property (1- font-lock-beg) 'font-lock-multiline))
1183 0 : (setq changed t)
1184 0 : (setq font-lock-beg (or (previous-single-property-change
1185 0 : font-lock-beg 'font-lock-multiline)
1186 0 : (point-min))))
1187 : ;;
1188 0 : (when (get-text-property font-lock-end 'font-lock-multiline)
1189 0 : (setq changed t)
1190 0 : (setq font-lock-end (or (text-property-any font-lock-end (point-max)
1191 0 : 'font-lock-multiline nil)
1192 0 : (point-max))))
1193 0 : changed))
1194 :
1195 : (defun font-lock-extend-region-wholelines ()
1196 : "Move fontification boundaries to beginning of lines."
1197 0 : (let ((changed nil))
1198 0 : (goto-char font-lock-beg)
1199 0 : (unless (bolp)
1200 0 : (setq changed t font-lock-beg
1201 0 : (let ((inhibit-field-text-motion t))
1202 0 : (line-beginning-position))))
1203 0 : (goto-char font-lock-end)
1204 0 : (unless (bolp)
1205 0 : (unless (eq font-lock-end
1206 0 : (setq font-lock-end (line-beginning-position 2)))
1207 0 : (setq changed t)))
1208 0 : changed))
1209 :
1210 : (defun font-lock-default-fontify-region (beg end loudly)
1211 : "Fontify the text between BEG and END.
1212 : If LOUDLY is non-nil, print status messages while fontifying.
1213 : This function is the default `font-lock-fontify-region-function'."
1214 0 : (save-buffer-state
1215 : ;; Use the fontification syntax table, if any.
1216 0 : (with-syntax-table (or font-lock-syntax-table (syntax-table))
1217 0 : (save-restriction
1218 0 : (unless font-lock-dont-widen (widen))
1219 : ;; Extend the region to fontify so that it starts and ends at
1220 : ;; safe places.
1221 0 : (let ((funs font-lock-extend-region-functions)
1222 0 : (font-lock-beg beg)
1223 0 : (font-lock-end end))
1224 0 : (while funs
1225 0 : (setq funs (if (or (not (funcall (car funs)))
1226 0 : (eq funs font-lock-extend-region-functions))
1227 0 : (cdr funs)
1228 : ;; If there's been a change, we should go through
1229 : ;; the list again since this new position may
1230 : ;; warrant a different answer from one of the fun
1231 : ;; we've already seen.
1232 0 : font-lock-extend-region-functions)))
1233 0 : (setq beg font-lock-beg end font-lock-end))
1234 : ;; Now do the fontification.
1235 0 : (font-lock-unfontify-region beg end)
1236 0 : (when (and font-lock-syntactic-keywords
1237 0 : (null syntax-propertize-function))
1238 : ;; Ensure the beginning of the file is properly syntactic-fontified.
1239 0 : (let ((start beg))
1240 0 : (when (< font-lock-syntactically-fontified start)
1241 0 : (setq start (max font-lock-syntactically-fontified (point-min)))
1242 0 : (setq font-lock-syntactically-fontified end))
1243 0 : (font-lock-fontify-syntactic-keywords-region start end)))
1244 0 : (unless font-lock-keywords-only
1245 0 : (font-lock-fontify-syntactically-region beg end loudly))
1246 0 : (font-lock-fontify-keywords-region beg end loudly)
1247 0 : `(jit-lock-bounds ,beg . ,end)))))
1248 :
1249 : ;; The following must be rethought, since keywords can override fontification.
1250 : ;; ;; Now scan for keywords, but not if we are inside a comment now.
1251 : ;; (or (and (not font-lock-keywords-only)
1252 : ;; (let ((state (parse-partial-sexp beg end nil nil
1253 : ;; font-lock-cache-state)))
1254 : ;; (or (nth 4 state) (nth 7 state))))
1255 : ;; (font-lock-fontify-keywords-region beg end))
1256 :
1257 : (defvar font-lock-extra-managed-props nil
1258 : "Additional text properties managed by font-lock.
1259 : This is used by `font-lock-default-unfontify-region' to decide
1260 : what properties to clear before refontifying a region.")
1261 :
1262 : (defun font-lock-default-unfontify-region (beg end)
1263 : "Unfontify the text between BEG and END.
1264 : This function is the default `font-lock-unfontify-region-function'."
1265 0 : (remove-list-of-text-properties
1266 0 : beg end (append
1267 0 : font-lock-extra-managed-props
1268 0 : (if font-lock-syntactic-keywords
1269 : '(syntax-table face font-lock-multiline)
1270 0 : '(face font-lock-multiline)))))
1271 :
1272 : ;; Called when any modification is made to buffer text.
1273 : (defun font-lock-after-change-function (beg end &optional old-len)
1274 0 : (save-excursion
1275 0 : (let ((inhibit-point-motion-hooks t)
1276 : (inhibit-quit t)
1277 0 : (region (if font-lock-extend-after-change-region-function
1278 0 : (funcall font-lock-extend-after-change-region-function
1279 0 : beg end old-len))))
1280 0 : (save-match-data
1281 0 : (if region
1282 : ;; Fontify the region the major mode has specified.
1283 0 : (setq beg (car region) end (cdr region))
1284 : ;; Fontify the whole lines which enclose the region.
1285 : ;; Actually, this is not needed because
1286 : ;; font-lock-default-fontify-region already rounds up to a whole
1287 : ;; number of lines.
1288 : ;; (setq beg (progn (goto-char beg) (line-beginning-position))
1289 : ;; end (progn (goto-char end) (line-beginning-position 2)))
1290 0 : (unless (eq end (point-max))
1291 : ;; Rounding up to a whole number of lines should include the
1292 : ;; line right after `end'. Typical case: the first char of
1293 : ;; the line was deleted. Or a \n was inserted in the middle
1294 : ;; of a line.
1295 0 : (setq end (1+ end))))
1296 0 : (font-lock-fontify-region beg end)))))
1297 :
1298 : (defvar jit-lock-start) (defvar jit-lock-end)
1299 : (defun font-lock-extend-jit-lock-region-after-change (beg end old-len)
1300 : "Function meant for `jit-lock-after-change-extend-region-functions'.
1301 : This function does 2 things:
1302 : - extend the region so that it not only includes the part that was modified
1303 : but also the surrounding text whose highlighting may change as a consequence.
1304 : - anticipate (part of) the region extension that will happen later in
1305 : `font-lock-default-fontify-region', in order to avoid the need for
1306 : double-redisplay in `jit-lock-fontify-now'."
1307 0 : (save-excursion
1308 : ;; First extend the region as font-lock-after-change-function would.
1309 0 : (let ((region (if font-lock-extend-after-change-region-function
1310 0 : (funcall font-lock-extend-after-change-region-function
1311 0 : beg end old-len))))
1312 0 : (if region
1313 0 : (setq beg (min jit-lock-start (car region))
1314 0 : end (max jit-lock-end (cdr region))))
1315 : ;; Then extend the region obeying font-lock-multiline properties,
1316 : ;; indicating which part of the buffer needs to be refontified.
1317 : ;; !!! This is the *main* user of font-lock-multiline property !!!
1318 : ;; font-lock-after-change-function could/should also do that, but it
1319 : ;; doesn't need to because font-lock-default-fontify-region does
1320 : ;; it anyway. Here OTOH we have no guarantee that
1321 : ;; font-lock-default-fontify-region will be executed on this region
1322 : ;; any time soon.
1323 : ;; Note: contrary to font-lock-default-fontify-region, we do not do
1324 : ;; any loop here because we are not looking for a safe spot: we just
1325 : ;; mark the text whose appearance may need to change as a result of
1326 : ;; the buffer modification.
1327 0 : (when (and (> beg (point-min))
1328 0 : (get-text-property (1- beg) 'font-lock-multiline))
1329 0 : (setq beg (or (previous-single-property-change
1330 0 : beg 'font-lock-multiline)
1331 0 : (point-min))))
1332 0 : (when (< end (point-max))
1333 0 : (setq end
1334 0 : (cond
1335 0 : ((get-text-property end 'font-lock-multiline)
1336 0 : (or (text-property-any end (point-max)
1337 0 : 'font-lock-multiline nil)
1338 0 : (point-max)))
1339 : ;; If `end' has been set by the function above, don't corrupt it.
1340 0 : (font-lock-extend-after-change-region-function end)
1341 : ;; Rounding up to a whole number of lines should include the
1342 : ;; line right after `end'. Typical case: the first char of
1343 : ;; the line was deleted. Or a \n was inserted in the middle
1344 : ;; of a line.
1345 0 : (t (1+ end)))))
1346 : ;; Finally, pre-enlarge the region to a whole number of lines, to try
1347 : ;; and anticipate what font-lock-default-fontify-region will do, so as to
1348 : ;; avoid double-redisplay.
1349 : ;; We could just run `font-lock-extend-region-functions', but since
1350 : ;; the only purpose is to avoid the double-redisplay, we prefer to
1351 : ;; do here only the part that is cheap and most likely to be useful.
1352 0 : (when (memq 'font-lock-extend-region-wholelines
1353 0 : font-lock-extend-region-functions)
1354 0 : (goto-char beg)
1355 0 : (setq beg (min jit-lock-start (line-beginning-position)))
1356 0 : (goto-char end)
1357 0 : (setq end
1358 0 : (max jit-lock-end
1359 0 : (if (bolp) (point) (line-beginning-position 2)))))
1360 0 : (setq jit-lock-start beg
1361 0 : jit-lock-end end))))
1362 :
1363 : (defun font-lock-fontify-block (&optional arg)
1364 : "Fontify some lines the way `font-lock-fontify-buffer' would.
1365 : The lines could be a function or paragraph, or a specified number of lines.
1366 : If ARG is given, fontify that many lines before and after point, or 16 lines if
1367 : no ARG is given and `font-lock-mark-block-function' is nil.
1368 : If `font-lock-mark-block-function' non-nil and no ARG is given, it is used to
1369 : delimit the region to fontify."
1370 : (interactive "P")
1371 0 : (let ((inhibit-point-motion-hooks t)
1372 : deactivate-mark)
1373 : ;; Make sure we have the right `font-lock-keywords' etc.
1374 0 : (if (not font-lock-mode) (font-lock-set-defaults))
1375 0 : (save-mark-and-excursion
1376 0 : (save-match-data
1377 0 : (condition-case error-data
1378 0 : (if (or arg (not font-lock-mark-block-function))
1379 0 : (let ((lines (if arg (prefix-numeric-value arg) 16)))
1380 0 : (font-lock-fontify-region
1381 0 : (save-excursion (forward-line (- lines)) (point))
1382 0 : (save-excursion (forward-line lines) (point))))
1383 0 : (funcall font-lock-mark-block-function)
1384 0 : (font-lock-fontify-region (point) (mark)))
1385 0 : ((error quit) (message "Fontifying block...%s" error-data)))))))
1386 :
1387 : ;;; End of Fontification functions.
1388 :
1389 : ;;; Additional text property functions.
1390 :
1391 : ;; The following text property functions should be builtins. This means they
1392 : ;; should be written in C and put with all the other text property functions.
1393 : ;; In the meantime, those that are used by font-lock.el are defined in Lisp
1394 : ;; below and given a `font-lock-' prefix. Those that are not used are defined
1395 : ;; in Lisp below and commented out. sm.
1396 :
1397 : (defun font-lock-prepend-text-property (start end prop value &optional object)
1398 : "Prepend to one property of the text from START to END.
1399 : Arguments PROP and VALUE specify the property and value to prepend to the value
1400 : already in place. The resulting property values are always lists.
1401 : Optional argument OBJECT is the string or buffer containing the text."
1402 28 : (let ((val (if (listp value) value (list value))) next prev)
1403 48 : (while (/= start end)
1404 20 : (setq next (next-single-property-change start prop object end)
1405 20 : prev (get-text-property start prop object))
1406 : ;; Canonicalize old forms of face property.
1407 20 : (and (memq prop '(face font-lock-face))
1408 20 : (listp prev)
1409 20 : (or (keywordp (car prev))
1410 20 : (memq (car prev) '(foreground-color background-color)))
1411 20 : (setq prev (list prev)))
1412 20 : (put-text-property start next prop
1413 20 : (append val (if (listp prev) prev (list prev)))
1414 20 : object)
1415 28 : (setq start next))))
1416 :
1417 : (defun font-lock-append-text-property (start end prop value &optional object)
1418 : "Append to one property of the text from START to END.
1419 : Arguments PROP and VALUE specify the property and value to append to the value
1420 : already in place. The resulting property values are always lists.
1421 : Optional argument OBJECT is the string or buffer containing the text."
1422 0 : (let ((val (if (listp value) value (list value))) next prev)
1423 0 : (while (/= start end)
1424 0 : (setq next (next-single-property-change start prop object end)
1425 0 : prev (get-text-property start prop object))
1426 : ;; Canonicalize old forms of face property.
1427 0 : (and (memq prop '(face font-lock-face))
1428 0 : (listp prev)
1429 0 : (or (keywordp (car prev))
1430 0 : (memq (car prev) '(foreground-color background-color)))
1431 0 : (setq prev (list prev)))
1432 0 : (put-text-property start next prop
1433 0 : (append (if (listp prev) prev (list prev)) val)
1434 0 : object)
1435 0 : (setq start next))))
1436 :
1437 : (defun font-lock-fillin-text-property (start end prop value &optional object)
1438 : "Fill in one property of the text from START to END.
1439 : Arguments PROP and VALUE specify the property and value to put where none are
1440 : already in place. Therefore existing property values are not overwritten.
1441 : Optional argument OBJECT is the string or buffer containing the text."
1442 0 : (let ((start (text-property-any start end prop nil object)) next)
1443 0 : (while start
1444 0 : (setq next (next-single-property-change start prop object end))
1445 0 : (put-text-property start next prop value object)
1446 0 : (setq start (text-property-any next end prop nil object)))))
1447 :
1448 : (defun font-lock--remove-face-from-text-property (start
1449 : end
1450 : prop value &optional object)
1451 : "Remove a specific property value from text from START to END.
1452 : Arguments PROP and VALUE specify the property and value to remove. The
1453 : resulting property values are not `eq' to VALUE nor lists containing VALUE.
1454 : Optional argument OBJECT is the string or buffer containing the text."
1455 18 : (let ((start (text-property-not-all start end prop nil object)) next prev)
1456 36 : (while start
1457 18 : (setq next (next-single-property-change start prop object end)
1458 18 : prev (get-text-property start prop object))
1459 18 : (cond ((or (atom prev)
1460 18 : (keywordp (car prev))
1461 18 : (eq (car prev) 'foreground-color)
1462 18 : (eq (car prev) 'background-color))
1463 0 : (when (eq value prev)
1464 0 : (remove-list-of-text-properties start next (list prop) object)))
1465 18 : ((memq value prev) ;Assume prev is not dotted.
1466 18 : (let ((new (remq value prev)))
1467 18 : (cond ((null new)
1468 18 : (remove-list-of-text-properties start next (list prop)
1469 18 : object))
1470 0 : ((= (length new) 1)
1471 0 : (put-text-property start next prop (car new) object))
1472 : (t
1473 18 : (put-text-property start next prop new object))))))
1474 18 : (setq start (text-property-not-all next end prop nil object)))))
1475 :
1476 : ;;; End of Additional text property functions.
1477 :
1478 : ;;; Syntactic regexp fontification functions.
1479 :
1480 : ;; These syntactic keyword pass functions are identical to those keyword pass
1481 : ;; functions below, with the following exceptions; (a) they operate on
1482 : ;; `font-lock-syntactic-keywords' of course, (b) they are all `defun' as speed
1483 : ;; is less of an issue, (c) eval of property value does not occur JIT as speed
1484 : ;; is less of an issue, (d) OVERRIDE cannot be `prepend' or `append' as it
1485 : ;; makes no sense for `syntax-table' property values, (e) they do not do it
1486 : ;; LOUDLY as it is not likely to be intensive.
1487 :
1488 : (defun font-lock-apply-syntactic-highlight (highlight)
1489 : "Apply HIGHLIGHT following a match.
1490 : HIGHLIGHT should be of the form MATCH-HIGHLIGHT,
1491 : see `font-lock-syntactic-keywords'."
1492 0 : (let* ((match (nth 0 highlight))
1493 0 : (start (match-beginning match)) (end (match-end match))
1494 0 : (value (nth 1 highlight))
1495 0 : (override (nth 2 highlight)))
1496 0 : (if (not start)
1497 : ;; No match but we might not signal an error.
1498 0 : (or (nth 3 highlight)
1499 0 : (error "No match %d in highlight %S" match highlight))
1500 0 : (when (and (consp value) (not (numberp (car value))))
1501 0 : (setq value (eval value)))
1502 0 : (when (stringp value) (setq value (string-to-syntax value)))
1503 : ;; Flush the syntax-cache. I believe this is not necessary for
1504 : ;; font-lock's use of syntax-ppss, but I'm not 100% sure and it can
1505 : ;; still be necessary for other users of syntax-ppss anyway.
1506 0 : (syntax-ppss-after-change-function start)
1507 0 : (cond
1508 0 : ((not override)
1509 : ;; Cannot override existing fontification.
1510 0 : (or (text-property-not-all start end 'syntax-table nil)
1511 0 : (put-text-property start end 'syntax-table value)))
1512 0 : ((eq override t)
1513 : ;; Override existing fontification.
1514 0 : (put-text-property start end 'syntax-table value))
1515 0 : ((eq override 'keep)
1516 : ;; Keep existing fontification.
1517 0 : (font-lock-fillin-text-property start end 'syntax-table value))))))
1518 :
1519 : (defun font-lock-fontify-syntactic-anchored-keywords (keywords limit)
1520 : "Fontify according to KEYWORDS until LIMIT.
1521 : KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords',
1522 : LIMIT can be modified by the value of its PRE-MATCH-FORM."
1523 0 : (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
1524 : ;; Evaluate PRE-MATCH-FORM.
1525 0 : (pre-match-value (eval (nth 1 keywords))))
1526 : ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
1527 0 : (if (and (numberp pre-match-value) (> pre-match-value (point)))
1528 0 : (setq limit pre-match-value)
1529 0 : (setq limit (line-end-position)))
1530 0 : (save-match-data
1531 : ;; Find an occurrence of `matcher' before `limit'.
1532 0 : (while (if (stringp matcher)
1533 0 : (re-search-forward matcher limit t)
1534 0 : (funcall matcher limit))
1535 : ;; Apply each highlight to this instance of `matcher'.
1536 0 : (setq highlights lowdarks)
1537 0 : (while highlights
1538 0 : (font-lock-apply-syntactic-highlight (car highlights))
1539 0 : (setq highlights (cdr highlights)))))
1540 : ;; Evaluate POST-MATCH-FORM.
1541 0 : (eval (nth 2 keywords))))
1542 :
1543 : (defun font-lock-fontify-syntactic-keywords-region (start end)
1544 : "Fontify according to `font-lock-syntactic-keywords' between START and END.
1545 : START should be at the beginning of a line."
1546 0 : (unless parse-sexp-lookup-properties
1547 : ;; We wouldn't go through so much trouble if we didn't intend to use those
1548 : ;; properties, would we?
1549 0 : (set (make-local-variable 'parse-sexp-lookup-properties) t))
1550 : ;; If `font-lock-syntactic-keywords' is a symbol, get the real keywords.
1551 0 : (when (symbolp font-lock-syntactic-keywords)
1552 0 : (setq font-lock-syntactic-keywords (font-lock-eval-keywords
1553 0 : font-lock-syntactic-keywords)))
1554 : ;; If `font-lock-syntactic-keywords' is not compiled, compile it.
1555 0 : (unless (eq (car font-lock-syntactic-keywords) t)
1556 0 : (setq font-lock-syntactic-keywords (font-lock-compile-keywords
1557 0 : font-lock-syntactic-keywords
1558 0 : t)))
1559 : ;; Get down to business.
1560 0 : (let ((case-fold-search font-lock-keywords-case-fold-search)
1561 0 : (keywords (cddr font-lock-syntactic-keywords))
1562 : keyword matcher highlights)
1563 0 : (while keywords
1564 : ;; Find an occurrence of `matcher' from `start' to `end'.
1565 0 : (setq keyword (car keywords) matcher (car keyword))
1566 0 : (goto-char start)
1567 0 : (while (and (< (point) end)
1568 0 : (if (stringp matcher)
1569 0 : (re-search-forward matcher end t)
1570 0 : (funcall matcher end)))
1571 : ;; Apply each highlight to this instance of `matcher', which may be
1572 : ;; specific highlights or more keywords anchored to `matcher'.
1573 0 : (setq highlights (cdr keyword))
1574 0 : (while highlights
1575 0 : (if (numberp (car (car highlights)))
1576 0 : (font-lock-apply-syntactic-highlight (car highlights))
1577 0 : (font-lock-fontify-syntactic-anchored-keywords (car highlights)
1578 0 : end))
1579 0 : (setq highlights (cdr highlights))))
1580 0 : (setq keywords (cdr keywords)))))
1581 :
1582 : ;;; End of Syntactic regexp fontification functions.
1583 :
1584 : ;;; Syntactic fontification functions.
1585 :
1586 : (defvar font-lock-comment-start-skip nil
1587 : "If non-nil, Font Lock mode uses this instead of `comment-start-skip'.")
1588 :
1589 : (defvar font-lock-comment-end-skip nil
1590 : "If non-nil, Font Lock mode uses this instead of `comment-end'.")
1591 :
1592 : (defun font-lock-fontify-syntactically-region (start end &optional loudly)
1593 : "Put proper face on each string and comment between START and END.
1594 : START should be at the beginning of a line."
1595 0 : (syntax-propertize end) ; Apply any needed syntax-table properties.
1596 0 : (with-syntax-table (or syntax-ppss-table (syntax-table))
1597 0 : (let ((comment-end-regexp
1598 0 : (or font-lock-comment-end-skip
1599 0 : (regexp-quote
1600 0 : (replace-regexp-in-string "^ *" "" comment-end))))
1601 : ;; Find the `start' state.
1602 0 : (state (syntax-ppss start))
1603 : face beg)
1604 0 : (if loudly (message "Fontifying %s... (syntactically...)" (buffer-name)))
1605 : ;;
1606 : ;; Find each interesting place between here and `end'.
1607 0 : (while
1608 0 : (progn
1609 0 : (when (or (nth 3 state) (nth 4 state))
1610 0 : (setq face (funcall font-lock-syntactic-face-function state))
1611 0 : (setq beg (max (nth 8 state) start))
1612 0 : (setq state (parse-partial-sexp (point) end nil nil state
1613 0 : 'syntax-table))
1614 0 : (when face (put-text-property beg (point) 'face face))
1615 0 : (when (and (eq face 'font-lock-comment-face)
1616 0 : (or font-lock-comment-start-skip
1617 0 : comment-start-skip))
1618 : ;; Find the comment delimiters
1619 : ;; and use font-lock-comment-delimiter-face for them.
1620 0 : (save-excursion
1621 0 : (goto-char beg)
1622 0 : (if (looking-at (or font-lock-comment-start-skip
1623 0 : comment-start-skip))
1624 0 : (put-text-property beg (match-end 0) 'face
1625 0 : font-lock-comment-delimiter-face)))
1626 0 : (if (looking-back comment-end-regexp (point-at-bol) t)
1627 0 : (put-text-property (match-beginning 0) (point) 'face
1628 0 : font-lock-comment-delimiter-face))))
1629 0 : (< (point) end))
1630 0 : (setq state (parse-partial-sexp (point) end nil nil state
1631 0 : 'syntax-table))))))
1632 :
1633 : ;;; End of Syntactic fontification functions.
1634 :
1635 : ;;; Keyword regexp fontification functions.
1636 :
1637 : (defsubst font-lock-apply-highlight (highlight)
1638 : "Apply HIGHLIGHT following a match.
1639 : HIGHLIGHT should be of the form MATCH-HIGHLIGHT, see `font-lock-keywords'."
1640 0 : (let* ((match (nth 0 highlight))
1641 0 : (start (match-beginning match)) (end (match-end match))
1642 0 : (override (nth 2 highlight)))
1643 0 : (if (not start)
1644 : ;; No match but we might not signal an error.
1645 0 : (or (nth 3 highlight)
1646 0 : (error "No match %d in highlight %S" match highlight))
1647 0 : (let ((val (eval (nth 1 highlight))))
1648 0 : (when (eq (car-safe val) 'face)
1649 0 : (add-text-properties start end (cddr val))
1650 0 : (setq val (cadr val)))
1651 0 : (cond
1652 0 : ((not (or val (eq override t)))
1653 : ;; If `val' is nil, don't do anything. It is important to do it
1654 : ;; explicitly, because when adding nil via things like
1655 : ;; font-lock-append-text-property, the property is actually
1656 : ;; changed from <face> to (<face>) which is undesirable. --Stef
1657 : nil)
1658 0 : ((not override)
1659 : ;; Cannot override existing fontification.
1660 0 : (or (text-property-not-all start end 'face nil)
1661 0 : (put-text-property start end 'face val)))
1662 0 : ((eq override t)
1663 : ;; Override existing fontification.
1664 0 : (put-text-property start end 'face val))
1665 0 : ((eq override 'prepend)
1666 : ;; Prepend to existing fontification.
1667 0 : (font-lock-prepend-text-property start end 'face val))
1668 0 : ((eq override 'append)
1669 : ;; Append to existing fontification.
1670 0 : (font-lock-append-text-property start end 'face val))
1671 0 : ((eq override 'keep)
1672 : ;; Keep existing fontification.
1673 0 : (font-lock-fillin-text-property start end 'face val)))))))
1674 :
1675 : (defsubst font-lock-fontify-anchored-keywords (keywords limit)
1676 : "Fontify according to KEYWORDS until LIMIT.
1677 : KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords',
1678 : LIMIT can be modified by the value of its PRE-MATCH-FORM."
1679 0 : (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
1680 0 : (lead-start (match-beginning 0))
1681 : ;; Evaluate PRE-MATCH-FORM.
1682 0 : (pre-match-value (eval (nth 1 keywords))))
1683 : ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
1684 0 : (if (not (and (numberp pre-match-value) (> pre-match-value (point))))
1685 0 : (setq limit (line-end-position))
1686 0 : (setq limit pre-match-value)
1687 0 : (when (and font-lock-multiline (>= limit (line-beginning-position 2)))
1688 : ;; this is a multiline anchored match
1689 : ;; (setq font-lock-multiline t)
1690 0 : (put-text-property (if (= limit (line-beginning-position 2))
1691 0 : (1- limit)
1692 0 : (min lead-start (point)))
1693 0 : limit
1694 0 : 'font-lock-multiline t)))
1695 0 : (save-match-data
1696 : ;; Find an occurrence of `matcher' before `limit'.
1697 0 : (while (and (< (point) limit)
1698 0 : (if (stringp matcher)
1699 0 : (re-search-forward matcher limit t)
1700 0 : (funcall matcher limit)))
1701 : ;; Apply each highlight to this instance of `matcher'.
1702 0 : (setq highlights lowdarks)
1703 0 : (while highlights
1704 0 : (font-lock-apply-highlight (car highlights))
1705 0 : (setq highlights (cdr highlights)))))
1706 : ;; Evaluate POST-MATCH-FORM.
1707 0 : (eval (nth 2 keywords))))
1708 :
1709 : (defun font-lock-fontify-keywords-region (start end &optional loudly)
1710 : "Fontify according to `font-lock-keywords' between START and END.
1711 : START should be at the beginning of a line.
1712 : LOUDLY, if non-nil, allows progress-meter bar."
1713 0 : (unless (eq (car font-lock-keywords) t)
1714 0 : (setq font-lock-keywords
1715 0 : (font-lock-compile-keywords font-lock-keywords)))
1716 0 : (let ((case-fold-search font-lock-keywords-case-fold-search)
1717 0 : (keywords (cddr font-lock-keywords))
1718 0 : (bufname (buffer-name)) (count 0)
1719 0 : (pos (make-marker))
1720 : keyword matcher highlights)
1721 : ;;
1722 : ;; Fontify each item in `font-lock-keywords' from `start' to `end'.
1723 0 : (while keywords
1724 0 : (if loudly (message "Fontifying %s... (regexps..%s)" bufname
1725 0 : (make-string (cl-incf count) ?.)))
1726 : ;;
1727 : ;; Find an occurrence of `matcher' from `start' to `end'.
1728 0 : (setq keyword (car keywords) matcher (car keyword))
1729 0 : (goto-char start)
1730 0 : (while (and (< (point) end)
1731 0 : (if (stringp matcher)
1732 0 : (re-search-forward matcher end t)
1733 0 : (funcall matcher end))
1734 : ;; Beware empty string matches since they will
1735 : ;; loop indefinitely.
1736 0 : (or (> (point) (match-beginning 0))
1737 0 : (progn (forward-char 1) t)))
1738 0 : (when (and font-lock-multiline
1739 0 : (>= (point)
1740 0 : (save-excursion (goto-char (match-beginning 0))
1741 0 : (forward-line 1) (point))))
1742 : ;; this is a multiline regexp match
1743 : ;; (setq font-lock-multiline t)
1744 0 : (put-text-property (if (= (point)
1745 0 : (save-excursion
1746 0 : (goto-char (match-beginning 0))
1747 0 : (forward-line 1) (point)))
1748 0 : (1- (point))
1749 0 : (match-beginning 0))
1750 0 : (point)
1751 0 : 'font-lock-multiline t))
1752 : ;; Apply each highlight to this instance of `matcher', which may be
1753 : ;; specific highlights or more keywords anchored to `matcher'.
1754 0 : (setq highlights (cdr keyword))
1755 0 : (while highlights
1756 0 : (if (numberp (car (car highlights)))
1757 0 : (font-lock-apply-highlight (car highlights))
1758 0 : (set-marker pos (point))
1759 0 : (font-lock-fontify-anchored-keywords (car highlights) end)
1760 : ;; Ensure forward progress. `pos' is a marker because anchored
1761 : ;; keyword may add/delete text (this happens e.g. in grep.el).
1762 0 : (if (< (point) pos) (goto-char pos)))
1763 0 : (setq highlights (cdr highlights))))
1764 0 : (setq keywords (cdr keywords)))
1765 0 : (set-marker pos nil)))
1766 :
1767 : ;;; End of Keyword regexp fontification functions.
1768 :
1769 : ;; Various functions.
1770 :
1771 : (defun font-lock-compile-keywords (keywords &optional syntactic-keywords)
1772 : "Compile KEYWORDS into the form (t KEYWORDS COMPILED...)
1773 : Here each COMPILED is of the form (MATCHER HIGHLIGHT ...) as shown in the
1774 : `font-lock-keywords' doc string.
1775 : If SYNTACTIC-KEYWORDS is non-nil, it means these keywords are used for
1776 : `font-lock-syntactic-keywords' rather than for `font-lock-keywords'."
1777 72 : (if (not font-lock-set-defaults)
1778 : ;; This should never happen. But some external packages sometimes
1779 : ;; call font-lock in unexpected and incorrect ways. It's important to
1780 : ;; stop processing at this point, otherwise we may end up changing the
1781 : ;; global value of font-lock-keywords and break highlighting in many
1782 : ;; other buffers.
1783 72 : (error "Font-lock trying to use keywords before setting them up"))
1784 72 : (if (eq (car-safe keywords) t)
1785 0 : keywords
1786 72 : (setq keywords
1787 72 : (cons t (cons keywords
1788 72 : (mapcar #'font-lock-compile-keyword keywords))))
1789 72 : (if (and (not syntactic-keywords)
1790 72 : (let ((beg-function syntax-begin-function))
1791 72 : (or (eq beg-function #'beginning-of-defun)
1792 72 : (if (symbolp beg-function)
1793 72 : (get beg-function 'font-lock-syntax-paren-check))))
1794 72 : (not beginning-of-defun-function))
1795 : ;; Try to detect when a string or comment contains something that
1796 : ;; looks like a defun and would thus confuse font-lock.
1797 0 : (nconc keywords
1798 0 : `((,(if defun-prompt-regexp
1799 0 : (concat "^\\(?:" defun-prompt-regexp "\\)?\\s(")
1800 0 : "^\\s(")
1801 : (0
1802 : (if (memq (get-text-property (match-beginning 0) 'face)
1803 : '(font-lock-string-face font-lock-doc-face
1804 : font-lock-comment-face))
1805 : (list 'face font-lock-warning-face
1806 : 'help-echo "Looks like a toplevel defun: escape the parenthesis"))
1807 72 : prepend)))))
1808 72 : keywords))
1809 :
1810 : (defun font-lock-compile-keyword (keyword)
1811 1166 : (cond ((or (functionp keyword) (nlistp keyword)) ; MATCHER
1812 194 : (list keyword '(0 font-lock-keyword-face)))
1813 972 : ((eq (car keyword) 'eval) ; (eval . FORM)
1814 0 : (font-lock-compile-keyword (eval (cdr keyword))))
1815 972 : ((eq (car-safe (cdr keyword)) 'quote) ; (MATCHER . 'FORM)
1816 : ;; If FORM is a FACENAME then quote it. Otherwise ignore the quote.
1817 0 : (if (symbolp (nth 2 keyword))
1818 0 : (list (car keyword) (list 0 (cdr keyword)))
1819 0 : (font-lock-compile-keyword (cons (car keyword) (nth 2 keyword)))))
1820 972 : ((numberp (cdr keyword)) ; (MATCHER . MATCH)
1821 72 : (list (car keyword) (list (cdr keyword) 'font-lock-keyword-face)))
1822 900 : ((symbolp (cdr keyword)) ; (MATCHER . FACENAME)
1823 72 : (list (car keyword) (list 0 (cdr keyword))))
1824 828 : ((nlistp (nth 1 keyword)) ; (MATCHER . HIGHLIGHT)
1825 144 : (list (car keyword) (cdr keyword)))
1826 : (t ; (MATCHER HIGHLIGHT ...)
1827 1166 : keyword)))
1828 :
1829 : (defun font-lock-eval-keywords (keywords)
1830 : "Evaluate KEYWORDS if a function (funcall) or variable (eval) name."
1831 72 : (if (listp keywords)
1832 36 : keywords
1833 36 : (font-lock-eval-keywords (if (fboundp keywords)
1834 0 : (funcall keywords)
1835 72 : (eval keywords)))))
1836 :
1837 : (defun font-lock-value-in-major-mode (values)
1838 : "If VALUES is an list, use `major-mode' as a key and return the `assq' value.
1839 : VALUES should then be an alist on the form ((MAJOR-MODE . VALUE) ...) where
1840 : MAJOR-MODE may be t.
1841 : If VALUES isn't a list, return VALUES."
1842 36 : (if (consp values)
1843 0 : (cdr (or (assq major-mode values) (assq t values)))
1844 36 : values))
1845 :
1846 : (defun font-lock-choose-keywords (keywords level)
1847 : "Return LEVELth element of KEYWORDS.
1848 : A LEVEL of nil is equal to a LEVEL of 0, a LEVEL of t is equal to
1849 : \(1- (length KEYWORDS))."
1850 36 : (cond ((not (and (listp keywords) (symbolp (car keywords))))
1851 0 : keywords)
1852 36 : ((numberp level)
1853 0 : (or (nth level keywords) (car (last keywords))))
1854 36 : ((eq level t)
1855 36 : (car (last keywords)))
1856 : (t
1857 36 : (car keywords))))
1858 :
1859 : (defun font-lock-refresh-defaults ()
1860 : "Restart fontification in current buffer after recomputing from defaults.
1861 : Recompute fontification variables using `font-lock-defaults' and
1862 : `font-lock-maximum-decoration'. Then restart fontification.
1863 :
1864 : Use this function when you have changed any of the above
1865 : variables directly.
1866 :
1867 : Note: This function will erase modifications done by
1868 : `font-lock-add-keywords' or `font-lock-remove-keywords', but will
1869 : preserve `hi-lock-mode' highlighting patterns."
1870 0 : (font-lock-mode -1)
1871 0 : (kill-local-variable 'font-lock-set-defaults)
1872 0 : (font-lock-mode 1))
1873 :
1874 : (defvar font-lock-major-mode nil
1875 : "Major mode for which the font-lock settings have been setup.")
1876 : (make-variable-buffer-local 'font-lock-major-mode)
1877 :
1878 : (defun font-lock-set-defaults ()
1879 : "Set fontification defaults appropriately for this mode.
1880 : Sets various variables using `font-lock-defaults' and
1881 : `font-lock-maximum-decoration'."
1882 : ;; Set fontification defaults if not previously set for correct major mode.
1883 448 : (unless (and font-lock-set-defaults
1884 448 : (eq font-lock-major-mode major-mode))
1885 36 : (setq font-lock-major-mode major-mode)
1886 36 : (setq font-lock-set-defaults t)
1887 36 : (let* ((defaults font-lock-defaults)
1888 : (keywords
1889 36 : (font-lock-choose-keywords (nth 0 defaults)
1890 36 : (font-lock-value-in-major-mode font-lock-maximum-decoration)))
1891 36 : (local (cdr (assq major-mode font-lock-keywords-alist)))
1892 : (removed-keywords
1893 36 : (cdr-safe (assq major-mode font-lock-removed-keywords-alist))))
1894 : ;; Syntactic fontification?
1895 36 : (if (nth 1 defaults)
1896 0 : (set (make-local-variable 'font-lock-keywords-only) t)
1897 36 : (kill-local-variable 'font-lock-keywords-only))
1898 : ;; Case fold during regexp fontification?
1899 36 : (if (nth 2 defaults)
1900 0 : (set (make-local-variable 'font-lock-keywords-case-fold-search) t)
1901 36 : (kill-local-variable 'font-lock-keywords-case-fold-search))
1902 : ;; Syntax table for regexp and syntactic fontification?
1903 36 : (if (null (nth 3 defaults))
1904 36 : (kill-local-variable 'font-lock-syntax-table)
1905 0 : (set (make-local-variable 'font-lock-syntax-table)
1906 0 : (copy-syntax-table (syntax-table)))
1907 0 : (dolist (selem (nth 3 defaults))
1908 : ;; The character to modify may be a single CHAR or a STRING.
1909 0 : (let ((syntax (cdr selem)))
1910 0 : (dolist (char (if (numberp (car selem))
1911 0 : (list (car selem))
1912 0 : (mapcar #'identity (car selem))))
1913 36 : (modify-syntax-entry char syntax font-lock-syntax-table)))))
1914 : ;; (nth 4 defaults) used to hold `font-lock-beginning-of-syntax-function',
1915 : ;; but that was removed in 25.1, so if it's a cons cell, we assume that
1916 : ;; it's part of the variable alist.
1917 : ;; Variable alist?
1918 36 : (dolist (x (nthcdr (if (consp (nth 4 defaults)) 4 5) defaults))
1919 108 : (set (make-local-variable (car x)) (cdr x)))
1920 : ;; Set up `font-lock-keywords' last because its value might depend
1921 : ;; on other settings.
1922 36 : (set (make-local-variable 'font-lock-keywords)
1923 36 : (font-lock-eval-keywords keywords))
1924 : ;; Local fontification?
1925 224 : (while local
1926 188 : (font-lock-add-keywords nil (car (car local)) (cdr (car local)))
1927 188 : (setq local (cdr local)))
1928 36 : (when removed-keywords
1929 36 : (font-lock-remove-keywords nil removed-keywords))
1930 : ;; Now compile the keywords.
1931 36 : (unless (eq (car font-lock-keywords) t)
1932 36 : (setq font-lock-keywords
1933 36 : (font-lock-compile-keywords font-lock-keywords))))
1934 448 : (font-lock-flush)))
1935 :
1936 : ;;; Color etc. support.
1937 :
1938 : ;; Note that `defface' will not overwrite any faces declared above via
1939 : ;; `custom-declare-face'.
1940 : (defface font-lock-comment-face
1941 : '((((class grayscale) (background light))
1942 : :foreground "DimGray" :weight bold :slant italic)
1943 : (((class grayscale) (background dark))
1944 : :foreground "LightGray" :weight bold :slant italic)
1945 : (((class color) (min-colors 88) (background light))
1946 : :foreground "Firebrick")
1947 : (((class color) (min-colors 88) (background dark))
1948 : :foreground "chocolate1")
1949 : (((class color) (min-colors 16) (background light))
1950 : :foreground "red")
1951 : (((class color) (min-colors 16) (background dark))
1952 : :foreground "red1")
1953 : (((class color) (min-colors 8) (background light))
1954 : :foreground "red")
1955 : (((class color) (min-colors 8) (background dark))
1956 : :foreground "yellow")
1957 : (t :weight bold :slant italic))
1958 : "Font Lock mode face used to highlight comments."
1959 : :group 'font-lock-faces)
1960 :
1961 : (defface font-lock-comment-delimiter-face
1962 : '((default :inherit font-lock-comment-face))
1963 : "Font Lock mode face used to highlight comment delimiters."
1964 : :group 'font-lock-faces)
1965 :
1966 : (defface font-lock-string-face
1967 : '((((class grayscale) (background light)) :foreground "DimGray" :slant italic)
1968 : (((class grayscale) (background dark)) :foreground "LightGray" :slant italic)
1969 : (((class color) (min-colors 88) (background light)) :foreground "VioletRed4")
1970 : (((class color) (min-colors 88) (background dark)) :foreground "LightSalmon")
1971 : (((class color) (min-colors 16) (background light)) :foreground "RosyBrown")
1972 : (((class color) (min-colors 16) (background dark)) :foreground "LightSalmon")
1973 : (((class color) (min-colors 8)) :foreground "green")
1974 : (t :slant italic))
1975 : "Font Lock mode face used to highlight strings."
1976 : :group 'font-lock-faces)
1977 :
1978 : (defface font-lock-doc-face
1979 : '((t :inherit font-lock-string-face))
1980 : "Font Lock mode face used to highlight documentation."
1981 : :group 'font-lock-faces)
1982 :
1983 : (defface font-lock-keyword-face
1984 : '((((class grayscale) (background light)) :foreground "LightGray" :weight bold)
1985 : (((class grayscale) (background dark)) :foreground "DimGray" :weight bold)
1986 : (((class color) (min-colors 88) (background light)) :foreground "Purple")
1987 : (((class color) (min-colors 88) (background dark)) :foreground "Cyan1")
1988 : (((class color) (min-colors 16) (background light)) :foreground "Purple")
1989 : (((class color) (min-colors 16) (background dark)) :foreground "Cyan")
1990 : (((class color) (min-colors 8)) :foreground "cyan" :weight bold)
1991 : (t :weight bold))
1992 : "Font Lock mode face used to highlight keywords."
1993 : :group 'font-lock-faces)
1994 :
1995 : (defface font-lock-builtin-face
1996 : '((((class grayscale) (background light)) :foreground "LightGray" :weight bold)
1997 : (((class grayscale) (background dark)) :foreground "DimGray" :weight bold)
1998 : (((class color) (min-colors 88) (background light)) :foreground "dark slate blue")
1999 : (((class color) (min-colors 88) (background dark)) :foreground "LightSteelBlue")
2000 : (((class color) (min-colors 16) (background light)) :foreground "Orchid")
2001 : (((class color) (min-colors 16) (background dark)) :foreground "LightSteelBlue")
2002 : (((class color) (min-colors 8)) :foreground "blue" :weight bold)
2003 : (t :weight bold))
2004 : "Font Lock mode face used to highlight builtins."
2005 : :group 'font-lock-faces)
2006 :
2007 : (defface font-lock-function-name-face
2008 : '((((class color) (min-colors 88) (background light)) :foreground "Blue1")
2009 : (((class color) (min-colors 88) (background dark)) :foreground "LightSkyBlue")
2010 : (((class color) (min-colors 16) (background light)) :foreground "Blue")
2011 : (((class color) (min-colors 16) (background dark)) :foreground "LightSkyBlue")
2012 : (((class color) (min-colors 8)) :foreground "blue" :weight bold)
2013 : (t :inverse-video t :weight bold))
2014 : "Font Lock mode face used to highlight function names."
2015 : :group 'font-lock-faces)
2016 :
2017 : (defface font-lock-variable-name-face
2018 : '((((class grayscale) (background light))
2019 : :foreground "Gray90" :weight bold :slant italic)
2020 : (((class grayscale) (background dark))
2021 : :foreground "DimGray" :weight bold :slant italic)
2022 : (((class color) (min-colors 88) (background light)) :foreground "sienna")
2023 : (((class color) (min-colors 88) (background dark)) :foreground "LightGoldenrod")
2024 : (((class color) (min-colors 16) (background light)) :foreground "DarkGoldenrod")
2025 : (((class color) (min-colors 16) (background dark)) :foreground "LightGoldenrod")
2026 : (((class color) (min-colors 8)) :foreground "yellow" :weight light)
2027 : (t :weight bold :slant italic))
2028 : "Font Lock mode face used to highlight variable names."
2029 : :group 'font-lock-faces)
2030 :
2031 : (defface font-lock-type-face
2032 : '((((class grayscale) (background light)) :foreground "Gray90" :weight bold)
2033 : (((class grayscale) (background dark)) :foreground "DimGray" :weight bold)
2034 : (((class color) (min-colors 88) (background light)) :foreground "ForestGreen")
2035 : (((class color) (min-colors 88) (background dark)) :foreground "PaleGreen")
2036 : (((class color) (min-colors 16) (background light)) :foreground "ForestGreen")
2037 : (((class color) (min-colors 16) (background dark)) :foreground "PaleGreen")
2038 : (((class color) (min-colors 8)) :foreground "green")
2039 : (t :weight bold :underline t))
2040 : "Font Lock mode face used to highlight type and classes."
2041 : :group 'font-lock-faces)
2042 :
2043 : (defface font-lock-constant-face
2044 : '((((class grayscale) (background light))
2045 : :foreground "LightGray" :weight bold :underline t)
2046 : (((class grayscale) (background dark))
2047 : :foreground "Gray50" :weight bold :underline t)
2048 : (((class color) (min-colors 88) (background light)) :foreground "dark cyan")
2049 : (((class color) (min-colors 88) (background dark)) :foreground "Aquamarine")
2050 : (((class color) (min-colors 16) (background light)) :foreground "CadetBlue")
2051 : (((class color) (min-colors 16) (background dark)) :foreground "Aquamarine")
2052 : (((class color) (min-colors 8)) :foreground "magenta")
2053 : (t :weight bold :underline t))
2054 : "Font Lock mode face used to highlight constants and labels."
2055 : :group 'font-lock-faces)
2056 :
2057 : (defface font-lock-warning-face
2058 : '((t :inherit error))
2059 : "Font Lock mode face used to highlight warnings."
2060 : :group 'font-lock-faces)
2061 :
2062 : (defface font-lock-negation-char-face
2063 : '((t nil))
2064 : "Font Lock mode face used to highlight easy to overlook negation."
2065 : :group 'font-lock-faces)
2066 :
2067 : (defface font-lock-preprocessor-face
2068 : '((t :inherit font-lock-builtin-face))
2069 : "Font Lock mode face used to highlight preprocessor directives."
2070 : :group 'font-lock-faces)
2071 :
2072 : (defface font-lock-regexp-grouping-backslash
2073 : '((t :inherit bold))
2074 : "Font Lock mode face for backslashes in Lisp regexp grouping constructs."
2075 : :group 'font-lock-faces)
2076 :
2077 : (defface font-lock-regexp-grouping-construct
2078 : '((t :inherit bold))
2079 : "Font Lock mode face used to highlight grouping constructs in Lisp regexps."
2080 : :group 'font-lock-faces)
2081 :
2082 : ;;; End of Color etc. support.
2083 :
2084 : ;;; Menu support.
2085 :
2086 : ;; This section of code is commented out because Emacs does not have real menu
2087 : ;; buttons. (We can mimic them by putting "( ) " or "(X) " at the beginning of
2088 : ;; the menu entry text, but with Xt it looks both ugly and embarrassingly
2089 : ;; amateur.) If/When Emacs gets real menus buttons, put in menu-bar.el after
2090 : ;; the entry for "Text Properties" something like:
2091 : ;;
2092 : ;; (define-key menu-bar-edit-menu [font-lock]
2093 : ;; (cons "Syntax Highlighting" font-lock-menu))
2094 : ;;
2095 : ;; and remove a single ";" from the beginning of each line in the rest of this
2096 : ;; section. Probably the mechanism for telling the menu code what are menu
2097 : ;; buttons and when they are on or off needs tweaking. I have assumed that the
2098 : ;; mechanism is via `menu-toggle' and `menu-selected' symbol properties. sm.
2099 :
2100 : ;;;;;###autoload
2101 : ;;(progn
2102 : ;; ;; Make the Font Lock menu.
2103 : ;; (defvar font-lock-menu (make-sparse-keymap "Syntax Highlighting"))
2104 : ;; ;; Add the menu items in reverse order.
2105 : ;; (define-key font-lock-menu [fontify-less]
2106 : ;; '("Less In Current Buffer" . font-lock-fontify-less))
2107 : ;; (define-key font-lock-menu [fontify-more]
2108 : ;; '("More In Current Buffer" . font-lock-fontify-more))
2109 : ;; (define-key font-lock-menu [font-lock-sep]
2110 : ;; '("--"))
2111 : ;; (define-key font-lock-menu [font-lock-mode]
2112 : ;; '("In Current Buffer" . font-lock-mode))
2113 : ;; (define-key font-lock-menu [global-font-lock-mode]
2114 : ;; '("In All Buffers" . global-font-lock-mode)))
2115 : ;;
2116 : ;;;;;###autoload
2117 : ;;(progn
2118 : ;; ;; We put the appropriate `menu-enable' etc. symbol property values on when
2119 : ;; ;; font-lock.el is loaded, so we don't need to autoload the three variables.
2120 : ;; (put 'global-font-lock-mode 'menu-toggle t)
2121 : ;; (put 'font-lock-mode 'menu-toggle t)
2122 : ;; (put 'font-lock-fontify-more 'menu-enable '(identity))
2123 : ;; (put 'font-lock-fontify-less 'menu-enable '(identity)))
2124 : ;;
2125 : ;; ;; Put the appropriate symbol property values on now. See above.
2126 : ;;(put 'global-font-lock-mode 'menu-selected 'global-font-lock-mode)
2127 : ;;(put 'font-lock-mode 'menu-selected 'font-lock-mode)
2128 : ;;(put 'font-lock-fontify-more 'menu-enable '(nth 2 font-lock-fontify-level))
2129 : ;;(put 'font-lock-fontify-less 'menu-enable '(nth 1 font-lock-fontify-level))
2130 : ;;
2131 : ;;(defvar font-lock-fontify-level nil) ; For less/more fontification.
2132 : ;;
2133 : ;;(defun font-lock-fontify-level (level)
2134 : ;; (let ((font-lock-maximum-decoration level))
2135 : ;; (when font-lock-mode
2136 : ;; (font-lock-mode))
2137 : ;; (font-lock-mode)
2138 : ;; (when font-lock-verbose
2139 : ;; (message "Fontifying %s... level %d" (buffer-name) level))))
2140 : ;;
2141 : ;;(defun font-lock-fontify-less ()
2142 : ;; "Fontify the current buffer with less decoration.
2143 : ;;See `font-lock-maximum-decoration'."
2144 : ;; (interactive)
2145 : ;; ;; Check in case we get called interactively.
2146 : ;; (if (nth 1 font-lock-fontify-level)
2147 : ;; (font-lock-fontify-level (1- (car font-lock-fontify-level)))
2148 : ;; (error "No less decoration")))
2149 : ;;
2150 : ;;(defun font-lock-fontify-more ()
2151 : ;; "Fontify the current buffer with more decoration.
2152 : ;;See `font-lock-maximum-decoration'."
2153 : ;; (interactive)
2154 : ;; ;; Check in case we get called interactively.
2155 : ;; (if (nth 2 font-lock-fontify-level)
2156 : ;; (font-lock-fontify-level (1+ (car font-lock-fontify-level)))
2157 : ;; (error "No more decoration")))
2158 : ;;
2159 : ;; ;; This should be called by `font-lock-set-defaults'.
2160 : ;;(defun font-lock-set-menu ()
2161 : ;; ;; Activate less/more fontification entries if there are multiple levels for
2162 : ;; ;; the current buffer. Sets `font-lock-fontify-level' to be of the form
2163 : ;; ;; (CURRENT-LEVEL IS-LOWER-LEVEL-P IS-HIGHER-LEVEL-P) for menu activation.
2164 : ;; (let ((keywords (nth 0 font-lock-defaults))
2165 : ;; (level (font-lock-value-in-major-mode font-lock-maximum-decoration)))
2166 : ;; (make-local-variable 'font-lock-fontify-level)
2167 : ;; (if (or (symbolp keywords) (= (length keywords) 1))
2168 : ;; (font-lock-unset-menu)
2169 : ;; (cond ((eq level t)
2170 : ;; (setq level (1- (length keywords))))
2171 : ;; ((or (null level) (zerop level))
2172 : ;; ;; The default level is usually, but not necessarily, level 1.
2173 : ;; (setq level (- (length keywords)
2174 : ;; (length (member (eval (car keywords))
2175 : ;; (mapcar #'eval (cdr keywords))))))))
2176 : ;; (setq font-lock-fontify-level (list level (> level 1)
2177 : ;; (< level (1- (length keywords))))))))
2178 : ;;
2179 : ;; ;; This should be called by `font-lock-unset-defaults'.
2180 : ;;(defun font-lock-unset-menu ()
2181 : ;; ;; Deactivate less/more fontification entries.
2182 : ;; (setq font-lock-fontify-level nil))
2183 :
2184 : ;;; End of Menu support.
2185 :
2186 : ;;; Various regexp information shared by several modes.
2187 : ;; ;; Information specific to a single mode should go in its load library.
2188 :
2189 : ;; Font Lock support for C, C++, Objective-C and Java modes is now in
2190 : ;; cc-fonts.el (and required by cc-mode.el). However, the below function
2191 : ;; should stay in font-lock.el, since it is used by other libraries. sm.
2192 :
2193 : (defun font-lock-match-c-style-declaration-item-and-skip-to-next (limit)
2194 : "Match, and move over, any declaration/definition item after point.
2195 : Matches after point, but ignores leading whitespace and `*' characters.
2196 : Does not move further than LIMIT.
2197 :
2198 : The expected syntax of a declaration/definition item is `word' (preceded by
2199 : optional whitespace and `*' characters and proceeded by optional whitespace)
2200 : optionally followed by a `('. Everything following the item (but belonging to
2201 : it) is expected to be skip-able by `scan-sexps', and items are expected to be
2202 : separated with a `,' and to be terminated with a `;'.
2203 :
2204 : Thus the regexp matches after point: word (
2205 : ^^^^ ^
2206 : Where the match subexpressions are: 1 2
2207 :
2208 : The item is delimited by (match-beginning 1) and (match-end 1).
2209 : If (match-beginning 2) is non-nil, the item is followed by a `('.
2210 :
2211 : This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item."
2212 0 : (when (looking-at "[ \n\t*]*\\(\\sw+\\)[ \t\n]*\\(((?\\)?")
2213 0 : (when (and (match-end 2) (> (- (match-end 2) (match-beginning 2)) 1))
2214 : ;; If `word' is followed by a double open-paren, it's probably
2215 : ;; a macro used for "int myfun P_ ((int arg1))". Let's go back one
2216 : ;; word to try and match `myfun' rather than `P_'.
2217 0 : (let ((pos (point)))
2218 0 : (skip-chars-backward " \t\n")
2219 0 : (skip-syntax-backward "w")
2220 0 : (unless (looking-at "\\(\\sw+\\)[ \t\n]*\\sw+[ \t\n]*\\(((?\\)?")
2221 : ;; Looks like it was something else, so go back to where we
2222 : ;; were and reset the match data by rematching.
2223 0 : (goto-char pos)
2224 0 : (looking-at "[ \n\t*]*\\(\\sw+\\)[ \t\n]*\\(((?\\)?"))))
2225 0 : (save-match-data
2226 0 : (condition-case nil
2227 0 : (save-restriction
2228 : ;; Restrict to the LIMIT.
2229 0 : (narrow-to-region (point-min) limit)
2230 0 : (goto-char (match-end 1))
2231 : ;; Move over any item value, etc., to the next item.
2232 0 : (while (not (looking-at "[ \t\n]*\\(\\(,\\)\\|;\\|\\'\\)"))
2233 0 : (goto-char (or (scan-sexps (point) 1) (point-max))))
2234 0 : (if (match-end 2)
2235 0 : (goto-char (match-end 2))))
2236 0 : (error t)))))
2237 :
2238 : ;; C preprocessor(cpp) is used outside of C, C++ and Objective-C source file.
2239 : ;; e.g. assembler code and GNU linker script in Linux kernel.
2240 : ;; `cpp-font-lock-keywords' is handy for modes for the files.
2241 : ;;
2242 : ;; Here we cannot use `regexp-opt' because because regex-opt is not preloaded
2243 : ;; while font-lock.el is preloaded to emacs. So values pre-calculated with
2244 : ;; regexp-opt are used here.
2245 :
2246 : ;; `cpp-font-lock-keywords-source-directives' is calculated from:
2247 : ;;
2248 : ;; (regexp-opt
2249 : ;; '("define" "elif" "else" "endif" "error" "file" "if" "ifdef"
2250 : ;; "ifndef" "import" "include" "line" "pragma" "undef" "warning"))
2251 : ;;
2252 : (defconst cpp-font-lock-keywords-source-directives
2253 : "define\\|e\\(?:l\\(?:if\\|se\\)\\|ndif\\|rror\\)\\|file\\|i\\(?:f\\(?:n?def\\)?\\|mport\\|nclude\\)\\|line\\|pragma\\|undef\\|warning"
2254 : "Regular expression used in `cpp-font-lock-keywords'.")
2255 :
2256 : ;; `cpp-font-lock-keywords-source-depth' is calculated from:
2257 : ;;
2258 : ;; (regexp-opt-depth (regexp-opt
2259 : ;; '("define" "elif" "else" "endif" "error" "file" "if" "ifdef"
2260 : ;; "ifndef" "import" "include" "line" "pragma" "undef" "warning")))
2261 : ;;
2262 : (defconst cpp-font-lock-keywords-source-depth 0
2263 : "An integer representing regular expression depth of `cpp-font-lock-keywords-source-directives'.
2264 : Used in `cpp-font-lock-keywords'.")
2265 :
2266 : (defconst cpp-font-lock-keywords
2267 : (let* ((directives cpp-font-lock-keywords-source-directives)
2268 : (directives-depth cpp-font-lock-keywords-source-depth))
2269 : (list
2270 : ;;
2271 : ;; Fontify error directives.
2272 : '("^#[ \t]*\\(?:error\\|warning\\)[ \t]+\\(.+\\)" 1 font-lock-warning-face prepend)
2273 : ;;
2274 : ;; Fontify filenames in #include <...> preprocessor directives as strings.
2275 : '("^#[ \t]*\\(?:import\\|include\\)[ \t]*\\(<[^>\"\n]*>?\\)"
2276 : 1 font-lock-string-face prepend)
2277 : ;;
2278 : ;; Fontify function macro names.
2279 : '("^#[ \t]*define[ \t]+\\([[:alpha:]_][[:alnum:]_$]*\\)("
2280 : (1 font-lock-function-name-face prepend)
2281 : ;;
2282 : ;; Macro arguments.
2283 : ((lambda (limit)
2284 : (re-search-forward
2285 : "\\(?:\\([[:alpha:]_][[:alnum:]_]*\\)[,]?\\)"
2286 : (or (save-excursion (re-search-forward ")" limit t))
2287 : limit)
2288 : t))
2289 : nil nil (1 font-lock-variable-name-face prepend)))
2290 : ;;
2291 : ;; Fontify symbol names in #elif or #if ... defined preprocessor directives.
2292 : '("^#[ \t]*\\(?:elif\\|if\\)\\>"
2293 : ("\\<\\(defined\\)\\>[ \t]*(?\\([[:alpha:]_][[:alnum:]_]*\\)?" nil nil
2294 : (1 font-lock-builtin-face prepend) (2 font-lock-variable-name-face prepend t)))
2295 : ;;
2296 : ;; Fontify otherwise as symbol names, and the preprocessor directive names.
2297 : (list
2298 : (concat "^\\(#[ \t]*\\(?:" directives
2299 : "\\)\\)\\>[ \t!]*\\([[:alpha:]_][[:alnum:]_]*\\)?")
2300 : '(1 font-lock-preprocessor-face prepend)
2301 : (list (+ 2 directives-depth)
2302 : 'font-lock-variable-name-face nil t))))
2303 : "Font lock keywords for C preprocessor directives.
2304 : `c-mode', `c++-mode' and `objc-mode' have their own font lock keywords
2305 : for C preprocessor directives. This definition is for the other modes
2306 : in which C preprocessor directives are used. e.g. `asm-mode' and
2307 : `ld-script-mode'.")
2308 :
2309 : (provide 'font-lock)
2310 :
2311 : ;;; font-lock.el ends here
|