Commit | Line | Data |
---|---|---|
d9e94c22 MS |
1 | ;;; cc-fonts.el --- font lock support for CC Mode |
2 | ||
ab422c4d | 3 | ;; Copyright (C) 2002-2013 Free Software Foundation, Inc. |
d9e94c22 MS |
4 | |
5 | ;; Authors: 2003- Alan Mackenzie | |
6 | ;; 2002- Martin Stjernholm | |
7 | ;; Maintainer: bug-cc-mode@gnu.org | |
8 | ;; Created: 07-Jan-2002 | |
bd78fa1d CY |
9 | ;; Keywords: c languages |
10 | ;; Package: cc-mode | |
d9e94c22 MS |
11 | |
12 | ;; This file is part of GNU Emacs. | |
13 | ||
b1fc2b50 | 14 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
d9e94c22 | 15 | ;; it under the terms of the GNU General Public License as published by |
b1fc2b50 GM |
16 | ;; the Free Software Foundation, either version 3 of the License, or |
17 | ;; (at your option) any later version. | |
d9e94c22 MS |
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 | |
b1fc2b50 | 25 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
d9e94c22 MS |
26 | |
27 | ;;; Commentary: | |
28 | ||
29 | ;; Some comments on the use of faces: | |
30 | ;; | |
0386b551 AM |
31 | ;; o `c-label-face-name' is either `font-lock-constant-face' (in |
32 | ;; Emacs), or `font-lock-reference-face'. | |
d9e94c22 MS |
33 | ;; |
34 | ;; o `c-constant-face-name', `c-reference-face-name' and | |
35 | ;; `c-doc-markup-face-name' are essentially set up like | |
36 | ;; `c-label-face-name'. | |
37 | ;; | |
38 | ;; o `c-preprocessor-face-name' is `font-lock-preprocessor-face' in | |
39 | ;; XEmacs and - in lack of a closer equivalent - | |
40 | ;; `font-lock-builtin-face' or `font-lock-reference-face' in Emacs. | |
41 | ;; | |
42 | ;; o `c-doc-face-name' is `font-lock-doc-string-face' in XEmacs, | |
43 | ;; `font-lock-doc-face' in Emacs 21 and later, or | |
44 | ;; `font-lock-comment-face' in older Emacs (that since source | |
45 | ;; documentation are actually comments in these languages, as opposed | |
46 | ;; to elisp). | |
47 | ;; | |
d9e94c22 MS |
48 | ;; TBD: We should probably provide real faces for the above uses and |
49 | ;; instead initialize them from the standard faces. | |
50 | ||
51 | ;;; Code: | |
52 | ||
53 | ;; The faces that already have been put onto the text is tested in | |
54 | ;; various places to direct further fontifications. For this to work, | |
55 | ;; the following assumptions regarding the faces must hold (apart from | |
56 | ;; the dependencies on the font locking order): | |
57 | ;; | |
58 | ;; o `font-lock-comment-face' and the face in `c-doc-face-name' is | |
59 | ;; not used in anything but comments. | |
60 | ;; o If any face (e.g. `c-doc-markup-face-name') but those above is | |
61 | ;; used in comments, it doesn't replace them. | |
62 | ;; o `font-lock-string-face' is not used in anything but string | |
63 | ;; literals (single or double quoted). | |
64 | ;; o `font-lock-keyword-face' and the face in `c-label-face-name' are | |
65 | ;; never overlaid with other faces. | |
66 | ||
67 | (eval-when-compile | |
68 | (let ((load-path | |
69 | (if (and (boundp 'byte-compile-dest-file) | |
70 | (stringp byte-compile-dest-file)) | |
71 | (cons (file-name-directory byte-compile-dest-file) load-path) | |
72 | load-path))) | |
73 | (load "cc-bytecomp" nil t))) | |
74 | ||
75 | (cc-require 'cc-defs) | |
76 | (cc-require-when-compile 'cc-langs) | |
77 | (cc-require 'cc-vars) | |
78 | (cc-require 'cc-engine) | |
79 | (cc-require-when-compile 'cc-awk) ; Change from cc-require, 2003/6/18 to | |
80 | ;; prevent cc-awk being loaded when it's not needed. There is now a (require | |
81 | ;; 'cc-awk) in (defun awk-mode ..). | |
82 | ||
83 | ;; Avoid repeated loading through the eval-after-load directive in | |
84 | ;; cc-mode.el. | |
85 | (provide 'cc-fonts) | |
86 | ||
87 | (cc-external-require 'font-lock) | |
88 | ||
89 | (cc-bytecomp-defvar parse-sexp-lookup-properties) ; Emacs only. | |
90 | ||
91 | ;; Need to declare these local symbols during compilation since | |
92 | ;; they're referenced from lambdas in `byte-compile' calls that are | |
93 | ;; executed at compile time. They don't need to have the proper | |
94 | ;; definitions, though, since the generated functions aren't called | |
95 | ;; during compilation. | |
96 | (cc-bytecomp-defvar c-preprocessor-face-name) | |
97 | (cc-bytecomp-defvar c-reference-face-name) | |
98 | (cc-bytecomp-defun c-fontify-recorded-types-and-refs) | |
99 | (cc-bytecomp-defun c-font-lock-declarators) | |
d9e94c22 MS |
100 | (cc-bytecomp-defun c-font-lock-objc-method) |
101 | (cc-bytecomp-defun c-font-lock-invalid-string) | |
102 | ||
d9e94c22 MS |
103 | \f |
104 | ;; Note that font-lock in XEmacs doesn't expand face names as | |
105 | ;; variables, so we have to use the (eval . FORM) in the font lock | |
106 | ;; matchers wherever we use these alias variables. | |
107 | ||
108 | (defconst c-preprocessor-face-name | |
109 | (cond ((c-face-name-p 'font-lock-preprocessor-face) | |
110 | ;; XEmacs has a font-lock-preprocessor-face. | |
111 | 'font-lock-preprocessor-face) | |
112 | ((c-face-name-p 'font-lock-builtin-face) | |
0386b551 AM |
113 | ;; In Emacs font-lock-builtin-face has traditionally been |
114 | ;; used for preprocessor directives. | |
d9e94c22 MS |
115 | 'font-lock-builtin-face) |
116 | (t | |
117 | 'font-lock-reference-face))) | |
118 | ||
119 | (cc-bytecomp-defvar font-lock-constant-face) | |
120 | ||
121 | (defconst c-label-face-name | |
122 | (cond ((c-face-name-p 'font-lock-label-face) | |
123 | ;; If it happens to occur in the future. (Well, the more | |
124 | ;; pragmatic reason is to get unique faces for the test | |
125 | ;; suite.) | |
126 | 'font-lock-label-face) | |
127 | ((and (c-face-name-p 'font-lock-constant-face) | |
128 | (eq font-lock-constant-face 'font-lock-constant-face)) | |
129 | ;; Test both if font-lock-constant-face exists and that it's | |
130 | ;; not an alias for something else. This is important since | |
131 | ;; we compare already set faces in various places. | |
132 | 'font-lock-constant-face) | |
133 | (t | |
134 | 'font-lock-reference-face))) | |
135 | ||
136 | (defconst c-constant-face-name | |
137 | (if (and (c-face-name-p 'font-lock-constant-face) | |
138 | (eq font-lock-constant-face 'font-lock-constant-face)) | |
0386b551 | 139 | ;; This doesn't exist in some earlier versions of XEmacs 21. |
d9e94c22 MS |
140 | 'font-lock-constant-face |
141 | c-label-face-name)) | |
142 | ||
143 | (defconst c-reference-face-name | |
0386b551 AM |
144 | (with-no-warnings |
145 | (if (and (c-face-name-p 'font-lock-reference-face) | |
146 | (eq font-lock-reference-face 'font-lock-reference-face)) | |
147 | ;; This is considered obsolete in Emacs, but it still maps well | |
148 | ;; to this use. (Another reason to do this is to get unique | |
149 | ;; faces for the test suite.) | |
150 | 'font-lock-reference-face | |
151 | c-label-face-name))) | |
d9e94c22 MS |
152 | |
153 | ;; This should not mapped to a face that also is used to fontify things | |
154 | ;; that aren't comments or string literals. | |
155 | (defconst c-doc-face-name | |
156 | (cond ((c-face-name-p 'font-lock-doc-string-face) | |
157 | ;; XEmacs. | |
158 | 'font-lock-doc-string-face) | |
159 | ((c-face-name-p 'font-lock-doc-face) | |
160 | ;; Emacs 21 and later. | |
161 | 'font-lock-doc-face) | |
162 | (t | |
163 | 'font-lock-comment-face))) | |
164 | ||
165 | (defconst c-doc-markup-face-name | |
166 | (if (c-face-name-p 'font-lock-doc-markup-face) | |
167 | ;; If it happens to occur in the future. (Well, the more | |
168 | ;; pragmatic reason is to get unique faces for the test | |
169 | ;; suite.) | |
170 | 'font-lock-doc-markup-face | |
171 | c-label-face-name)) | |
172 | ||
0386b551 AM |
173 | (defconst c-negation-char-face-name |
174 | (if (c-face-name-p 'font-lock-negation-char-face) | |
175 | ;; Emacs 22 has a special face for negation chars. | |
176 | 'font-lock-negation-char-face)) | |
d9e94c22 MS |
177 | |
178 | (cc-bytecomp-defun face-inverse-video-p) ; Only in Emacs. | |
179 | (cc-bytecomp-defun face-property-instance) ; Only in XEmacs. | |
180 | ||
181 | (defun c-make-inverse-face (oldface newface) | |
182 | ;; Emacs and XEmacs have completely different face manipulation | |
183 | ;; routines. :P | |
d9e94c22 MS |
184 | (copy-face oldface newface) |
185 | (cond ((fboundp 'face-inverse-video-p) | |
0386b551 AM |
186 | ;; Emacs. This only looks at the inverse flag in the current |
187 | ;; frame. Other display configurations might be different, | |
188 | ;; but it can only show if the same Emacs has frames on | |
189 | ;; e.g. a color and a monochrome display simultaneously. | |
d9e94c22 MS |
190 | (unless (face-inverse-video-p oldface) |
191 | (invert-face newface))) | |
192 | ((fboundp 'face-property-instance) | |
193 | ;; XEmacs. Same pitfall here. | |
194 | (unless (face-property-instance oldface 'reverse) | |
0386b551 | 195 | (invert-face newface))))) |
d9e94c22 | 196 | |
28d3917c CY |
197 | (defvar c-annotation-face 'c-annotation-face) |
198 | ||
199 | (defface c-annotation-face | |
200 | '((default :inherit font-lock-constant-face)) | |
201 | "Face for highlighting annotations in Java mode and similar modes." | |
202 | :version "24.1" | |
203 | :group 'c) | |
452ea855 | 204 | |
d9e94c22 | 205 | (eval-and-compile |
b128268e AM |
206 | ;; We need the following definitions during compilation since they're |
207 | ;; used when the `c-lang-defconst' initializers are evaluated. Define | |
208 | ;; them at runtime too for the sake of derived modes. | |
209 | ||
210 | ;; This indicates the "font locking context", and is set just before | |
211 | ;; fontification is done. If non-nil, it says, e.g., point starts | |
212 | ;; from within a #if preprocessor construct. | |
213 | (defvar c-font-lock-context nil) | |
214 | (make-variable-buffer-local 'c-font-lock-context) | |
7d0ee75c | 215 | |
d9e94c22 MS |
216 | (defmacro c-put-font-lock-face (from to face) |
217 | ;; Put a face on a region (overriding any existing face) in the way | |
218 | ;; font-lock would do it. In XEmacs that means putting an | |
219 | ;; additional font-lock property, or else the font-lock package | |
220 | ;; won't recognize it as fontified and might override it | |
221 | ;; incorrectly. | |
0386b551 AM |
222 | ;; |
223 | ;; This function does a hidden buffer change. | |
d9e94c22 MS |
224 | (if (fboundp 'font-lock-set-face) |
225 | ;; Note: This function has no docstring in XEmacs so it might be | |
226 | ;; considered internal. | |
227 | `(font-lock-set-face ,from ,to ,face) | |
228 | `(put-text-property ,from ,to 'face ,face))) | |
229 | ||
230 | (defmacro c-remove-font-lock-face (from to) | |
231 | ;; This is the inverse of `c-put-font-lock-face'. | |
0386b551 AM |
232 | ;; |
233 | ;; This function does a hidden buffer change. | |
d9e94c22 MS |
234 | (if (fboundp 'font-lock-remove-face) |
235 | `(font-lock-remove-face ,from ,to) | |
236 | `(remove-text-properties ,from ,to '(face nil)))) | |
237 | ||
238 | (defmacro c-put-font-lock-string-face (from to) | |
239 | ;; Put `font-lock-string-face' on a string. The surrounding | |
240 | ;; quotes are included in Emacs but not in XEmacs. The passed | |
241 | ;; region should include them. | |
0386b551 AM |
242 | ;; |
243 | ;; This function does a hidden buffer change. | |
d9e94c22 MS |
244 | (if (featurep 'xemacs) |
245 | `(c-put-font-lock-face (1+ ,from) (1- ,to) 'font-lock-string-face) | |
246 | `(c-put-font-lock-face ,from ,to 'font-lock-string-face))) | |
247 | ||
248 | (defmacro c-fontify-types-and-refs (varlist &rest body) | |
249 | ;; Like `let', but additionally activates `c-record-type-identifiers' | |
250 | ;; and `c-record-ref-identifiers', and fontifies the recorded ranges | |
251 | ;; accordingly on exit. | |
0386b551 AM |
252 | ;; |
253 | ;; This function does hidden buffer changes. | |
d9e94c22 MS |
254 | `(let ((c-record-type-identifiers t) |
255 | c-record-ref-identifiers | |
256 | ,@varlist) | |
257 | (prog1 (progn ,@body) | |
258 | (c-fontify-recorded-types-and-refs)))) | |
259 | (put 'c-fontify-types-and-refs 'lisp-indent-function 1) | |
d9e94c22 MS |
260 | |
261 | (defun c-skip-comments-and-strings (limit) | |
262 | ;; If the point is within a region fontified as a comment or | |
263 | ;; string literal skip to the end of it or to LIMIT, whichever | |
264 | ;; comes first, and return t. Otherwise return nil. The match | |
265 | ;; data is not clobbered. | |
0386b551 AM |
266 | ;; |
267 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
268 | (when (c-got-face-at (point) c-literal-faces) |
269 | (while (progn | |
270 | (goto-char (next-single-property-change | |
271 | (point) 'face nil limit)) | |
272 | (and (< (point) limit) | |
273 | (c-got-face-at (point) c-literal-faces)))) | |
274 | t)) | |
275 | ||
0386b551 AM |
276 | (defun c-make-syntactic-matcher (regexp) |
277 | ;; Returns a byte compiled function suitable for use in place of a | |
278 | ;; regexp string in a `font-lock-keywords' matcher, except that | |
279 | ;; only matches outside comments and string literals count. | |
280 | ;; | |
281 | ;; This function does not do any hidden buffer changes, but the | |
282 | ;; generated functions will. (They are however used in places | |
283 | ;; covered by the font-lock context.) | |
284 | (byte-compile | |
285 | `(lambda (limit) | |
286 | (let (res) | |
287 | (while (and (setq res (re-search-forward ,regexp limit t)) | |
288 | (progn | |
289 | (goto-char (match-beginning 0)) | |
290 | (or (c-skip-comments-and-strings limit) | |
291 | (progn | |
292 | (goto-char (match-end 0)) | |
293 | nil))))) | |
294 | res)))) | |
295 | ||
b128268e | 296 | (defun c-make-font-lock-search-form (regexp highlights) |
8d5ed899 | 297 | ;; Return a lisp form which will fontify every occurrence of REGEXP |
b128268e AM |
298 | ;; (a regular expression, NOT a function) between POINT and `limit' |
299 | ;; with HIGHLIGHTS, a list of highlighters as specified on page | |
300 | ;; "Search-based Fontification" in the elisp manual. | |
301 | `(while (re-search-forward ,regexp limit t) | |
302 | (unless (progn | |
303 | (goto-char (match-beginning 0)) | |
304 | (c-skip-comments-and-strings limit)) | |
305 | (goto-char (match-end 0)) | |
306 | ,@(mapcar | |
307 | (lambda (highlight) | |
308 | (if (integerp (car highlight)) | |
309 | ;; e.g. highlight is (1 font-lock-type-face t) | |
310 | (progn | |
311 | (unless (eq (nth 2 highlight) t) | |
312 | (error | |
313 | "The override flag must currently be t in %s" | |
314 | highlight)) | |
315 | (when (nth 3 highlight) | |
316 | (error | |
317 | "The laxmatch flag may currently not be set in %s" | |
318 | highlight)) | |
319 | `(save-match-data | |
320 | (c-put-font-lock-face | |
321 | (match-beginning ,(car highlight)) | |
322 | (match-end ,(car highlight)) | |
323 | ,(elt highlight 1)))) | |
f6b1b0a8 | 324 | ;; highlight is an "ANCHORED HIGHLIGHTER" of the form |
b128268e AM |
325 | ;; (ANCHORED-MATCHER PRE-FORM POST-FORM SUBEXP-HIGHLIGHTERS...) |
326 | (when (nth 3 highlight) | |
327 | (error "Match highlights currently not supported in %s" | |
328 | highlight)) | |
329 | `(progn | |
330 | ,(nth 1 highlight) | |
331 | (save-match-data ,(car highlight)) | |
332 | ,(nth 2 highlight)))) | |
333 | highlights)))) | |
334 | ||
d9e94c22 MS |
335 | (defun c-make-font-lock-search-function (regexp &rest highlights) |
336 | ;; This function makes a byte compiled function that works much like | |
337 | ;; a matcher element in `font-lock-keywords'. It cuts out a little | |
338 | ;; bit of the overhead compared to a real matcher. The main reason | |
339 | ;; is however to pass the real search limit to the anchored | |
340 | ;; matcher(s), since most (if not all) font-lock implementations | |
e15f8aaa | 341 | ;; arbitrarily limit anchored matchers to the same line, and also |
d9e94c22 MS |
342 | ;; to insulate against various other irritating differences between |
343 | ;; the different (X)Emacs font-lock packages. | |
344 | ;; | |
345 | ;; REGEXP is the matcher, which must be a regexp. Only matches | |
346 | ;; where the beginning is outside any comment or string literal are | |
347 | ;; significant. | |
348 | ;; | |
349 | ;; HIGHLIGHTS is a list of highlight specs, just like in | |
350 | ;; `font-lock-keywords', with these limitations: The face is always | |
351 | ;; overridden (no big disadvantage, since hits in comments etc are | |
352 | ;; filtered anyway), there is no "laxmatch", and an anchored matcher | |
353 | ;; is always a form which must do all the fontification directly. | |
354 | ;; `limit' is a variable bound to the real limit in the context of | |
355 | ;; the anchored matcher forms. | |
356 | ;; | |
357 | ;; This function does not do any hidden buffer changes, but the | |
0386b551 AM |
358 | ;; generated functions will. (They are however used in places |
359 | ;; covered by the font-lock context.) | |
d9e94c22 MS |
360 | |
361 | ;; Note: Replace `byte-compile' with `eval' to debug the generated | |
e15f8aaa | 362 | ;; lambda more easily. |
d9e94c22 MS |
363 | (byte-compile |
364 | `(lambda (limit) | |
b128268e | 365 | (let ( ;; The font-lock package in Emacs is known to clobber |
d9e94c22 MS |
366 | ;; `parse-sexp-lookup-properties' (when it exists). |
367 | (parse-sexp-lookup-properties | |
368 | (cc-eval-when-compile | |
369 | (boundp 'parse-sexp-lookup-properties)))) | |
b128268e AM |
370 | |
371 | ;; (while (re-search-forward ,regexp limit t) | |
372 | ;; (unless (progn | |
373 | ;; (goto-char (match-beginning 0)) | |
374 | ;; (c-skip-comments-and-strings limit)) | |
375 | ;; (goto-char (match-end 0)) | |
376 | ;; ,@(mapcar | |
377 | ;; (lambda (highlight) | |
378 | ;; (if (integerp (car highlight)) | |
379 | ;; (progn | |
380 | ;; (unless (eq (nth 2 highlight) t) | |
381 | ;; (error | |
382 | ;; "The override flag must currently be t in %s" | |
383 | ;; highlight)) | |
384 | ;; (when (nth 3 highlight) | |
385 | ;; (error | |
386 | ;; "The laxmatch flag may currently not be set in %s" | |
387 | ;; highlight)) | |
388 | ;; `(save-match-data | |
389 | ;; (c-put-font-lock-face | |
390 | ;; (match-beginning ,(car highlight)) | |
391 | ;; (match-end ,(car highlight)) | |
392 | ;; ,(elt highlight 1)))) | |
393 | ;; (when (nth 3 highlight) | |
394 | ;; (error "Match highlights currently not supported in %s" | |
395 | ;; highlight)) | |
396 | ;; `(progn | |
397 | ;; ,(nth 1 highlight) | |
398 | ;; (save-match-data ,(car highlight)) | |
399 | ;; ,(nth 2 highlight)))) | |
400 | ;; highlights))) | |
401 | ,(c-make-font-lock-search-form regexp highlights)) | |
402 | ||
0386b551 AM |
403 | nil))) |
404 | ||
ef8cdf8c AM |
405 | (defun c-make-font-lock-BO-decl-search-function (regexp &rest highlights) |
406 | ;; This function makes a byte compiled function that first moves back | |
407 | ;; to the beginning of the current declaration (if any), then searches | |
408 | ;; forward for matcher elements (as in `font-lock-keywords') and | |
409 | ;; fontifies them. | |
410 | ;; | |
411 | ;; The motivation for moving back to the declaration start is to | |
412 | ;; establish a context for the current text when, e.g., a character | |
413 | ;; is typed on a C++ inheritance continuation line, or a jit-lock | |
414 | ;; chunk starts there. | |
7d0ee75c | 415 | ;; |
ef8cdf8c AM |
416 | ;; The new function works much like a matcher element in |
417 | ;; `font-lock-keywords'. It cuts out a little bit of the overhead | |
418 | ;; compared to a real matcher. The main reason is however to pass the | |
419 | ;; real search limit to the anchored matcher(s), since most (if not | |
420 | ;; all) font-lock implementations arbitrarily limit anchored matchers | |
421 | ;; to the same line, and also to insulate against various other | |
422 | ;; irritating differences between the different (X)Emacs font-lock | |
423 | ;; packages. | |
424 | ;; | |
425 | ;; REGEXP is the matcher, which must be a regexp. Only matches | |
426 | ;; where the beginning is outside any comment or string literal are | |
427 | ;; significant. | |
428 | ;; | |
429 | ;; HIGHLIGHTS is a list of highlight specs, just like in | |
430 | ;; `font-lock-keywords', with these limitations: The face is always | |
431 | ;; overridden (no big disadvantage, since hits in comments etc are | |
432 | ;; filtered anyway), there is no "laxmatch", and an anchored matcher | |
433 | ;; is always a form which must do all the fontification directly. | |
434 | ;; `limit' is a variable bound to the real limit in the context of | |
435 | ;; the anchored matcher forms. | |
436 | ;; | |
437 | ;; This function does not do any hidden buffer changes, but the | |
438 | ;; generated functions will. (They are however used in places | |
439 | ;; covered by the font-lock context.) | |
440 | ||
441 | ;; Note: Replace `byte-compile' with `eval' to debug the generated | |
442 | ;; lambda more easily. | |
443 | (byte-compile | |
444 | `(lambda (limit) | |
445 | (let ( ;; The font-lock package in Emacs is known to clobber | |
446 | ;; `parse-sexp-lookup-properties' (when it exists). | |
447 | (parse-sexp-lookup-properties | |
448 | (cc-eval-when-compile | |
9657183b AM |
449 | (boundp 'parse-sexp-lookup-properties))) |
450 | (BOD-limit | |
451 | (c-determine-limit 1000))) | |
ef8cdf8c AM |
452 | (goto-char |
453 | (let ((here (point))) | |
9657183b | 454 | (if (eq (car (c-beginning-of-decl-1 BOD-limit)) 'same) |
ef8cdf8c AM |
455 | (point) |
456 | here))) | |
457 | ,(c-make-font-lock-search-form regexp highlights)) | |
458 | nil))) | |
459 | ||
b128268e AM |
460 | (defun c-make-font-lock-context-search-function (normal &rest state-stanzas) |
461 | ;; This function makes a byte compiled function that works much like | |
462 | ;; a matcher element in `font-lock-keywords', with the following | |
463 | ;; enhancement: the generated function will test for particular "font | |
464 | ;; lock contexts" at the start of the region, i.e. is this point in | |
465 | ;; the middle of some particular construct? if so the generated | |
466 | ;; function will first fontify the tail of the construct, before | |
467 | ;; going into the main loop and fontify full constructs up to limit. | |
468 | ;; | |
469 | ;; The generated function takes one parameter called `limit', and | |
470 | ;; will fontify the region between POINT and LIMIT. | |
471 | ;; | |
472 | ;; NORMAL is a list of the form (REGEXP HIGHLIGHTS .....), and is | |
473 | ;; used to fontify the "regular" bit of the region. | |
474 | ;; STATE-STANZAS is list of elements of the form (STATE LIM REGEXP | |
475 | ;; HIGHLIGHTS), each element coding one possible font lock context. | |
476 | ||
477 | ;; o - REGEXP is a font-lock regular expression (NOT a function), | |
478 | ;; o - HIGHLIGHTS is a list of zero or more highlighters as defined | |
479 | ;; on page "Search-based Fontification" in the elisp manual. As | |
480 | ;; yet (2009-06), they must have OVERRIDE set, and may not have | |
481 | ;; LAXMATCH set. | |
482 | ;; | |
483 | ;; o - STATE is the "font lock context" (e.g. in-cpp-expr) and is | |
484 | ;; not quoted. | |
485 | ;; o - LIM is a lisp form whose evaluation will yield the limit | |
486 | ;; position in the buffer for fontification by this stanza. | |
487 | ;; | |
488 | ;; This function does not do any hidden buffer changes, but the | |
489 | ;; generated functions will. (They are however used in places | |
490 | ;; covered by the font-lock context.) | |
7d0ee75c | 491 | ;; |
b128268e AM |
492 | ;; Note: Replace `byte-compile' with `eval' to debug the generated |
493 | ;; lambda more easily. | |
494 | (byte-compile | |
495 | `(lambda (limit) | |
496 | (let ( ;; The font-lock package in Emacs is known to clobber | |
497 | ;; `parse-sexp-lookup-properties' (when it exists). | |
498 | (parse-sexp-lookup-properties | |
499 | (cc-eval-when-compile | |
500 | (boundp 'parse-sexp-lookup-properties)))) | |
501 | ,@(mapcar | |
502 | (lambda (stanza) | |
503 | (let ((state (car stanza)) | |
504 | (lim (nth 1 stanza)) | |
505 | (regexp (nth 2 stanza)) | |
506 | (highlights (cdr (cddr stanza)))) | |
507 | `(if (eq c-font-lock-context ',state) | |
508 | (let ((limit ,lim)) | |
509 | ,(c-make-font-lock-search-form | |
510 | regexp highlights))))) | |
511 | state-stanzas) | |
512 | ,(c-make-font-lock-search-form (car normal) (cdr normal)) | |
513 | nil)))) | |
514 | ||
3c0ab532 AM |
515 | ; (eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el. |
516 | ; '(progn | |
517 | (def-edebug-spec c-fontify-types-and-refs let*) | |
518 | (def-edebug-spec c-make-syntactic-matcher t) | |
519 | ;; If there are literal quoted or backquoted highlight specs in | |
520 | ;; the call to `c-make-font-lock-search-function' then let's | |
521 | ;; instrument the forms in them. | |
522 | (def-edebug-spec c-make-font-lock-search-function | |
523 | (form &rest &or ("quote" (&rest form)) ("`" (&rest form)) form)));)) | |
d9e94c22 MS |
524 | |
525 | (defun c-fontify-recorded-types-and-refs () | |
0386b551 | 526 | ;; Convert the ranges recorded on `c-record-type-identifiers' and |
d9e94c22 | 527 | ;; `c-record-ref-identifiers' to fontification. |
0386b551 AM |
528 | ;; |
529 | ;; This function does hidden buffer changes. | |
d9e94c22 MS |
530 | (let (elem) |
531 | (while (consp c-record-type-identifiers) | |
532 | (setq elem (car c-record-type-identifiers) | |
533 | c-record-type-identifiers (cdr c-record-type-identifiers)) | |
534 | (c-put-font-lock-face (car elem) (cdr elem) | |
535 | 'font-lock-type-face)) | |
536 | (while c-record-ref-identifiers | |
537 | (setq elem (car c-record-ref-identifiers) | |
538 | c-record-ref-identifiers (cdr c-record-ref-identifiers)) | |
539 | ;; Note that the reference face is a variable that is | |
540 | ;; dereferenced, since it's an alias in Emacs. | |
541 | (c-put-font-lock-face (car elem) (cdr elem) | |
542 | c-reference-face-name)))) | |
543 | ||
544 | (c-lang-defconst c-cpp-matchers | |
545 | "Font lock matchers for preprocessor directives and purely lexical | |
546 | stuff. Used on level 1 and higher." | |
547 | ||
548 | ;; Note: `c-font-lock-declarations' assumes that no matcher here | |
549 | ;; sets `font-lock-type-face' in languages where | |
550 | ;; `c-recognize-<>-arglists' is set. | |
551 | ||
552 | t `(,@(when (c-lang-const c-opt-cpp-prefix) | |
553 | (let* ((noncontinued-line-end "\\(\\=\\|\\(\\=\\|[^\\]\\)[\n\r]\\)") | |
0386b551 AM |
554 | (ncle-depth (regexp-opt-depth noncontinued-line-end)) |
555 | (sws-depth (c-lang-const c-syntactic-ws-depth)) | |
556 | (nsws-depth (c-lang-const c-nonempty-syntactic-ws-depth))) | |
557 | ||
d9e94c22 MS |
558 | `(;; The stuff after #error and #warning is a message, so |
559 | ;; fontify it as a string. | |
0386b551 | 560 | ,@(when (c-lang-const c-cpp-message-directives) |
2ae6c6b5 | 561 | (let* ((re (c-make-keywords-re 'appendable ; nil |
0386b551 AM |
562 | (c-lang-const c-cpp-message-directives))) |
563 | (re-depth (regexp-opt-depth re))) | |
564 | `((,(concat noncontinued-line-end | |
565 | (c-lang-const c-opt-cpp-prefix) | |
566 | re | |
567 | "\\s +\\(.*\\)$") | |
2ae6c6b5 | 568 | ,(+ ncle-depth re-depth 1) font-lock-string-face t)))) |
d9e94c22 MS |
569 | |
570 | ;; Fontify filenames in #include <...> as strings. | |
0386b551 AM |
571 | ,@(when (c-lang-const c-cpp-include-directives) |
572 | (let* ((re (c-make-keywords-re nil | |
573 | (c-lang-const c-cpp-include-directives))) | |
574 | (re-depth (regexp-opt-depth re))) | |
575 | `((,(concat noncontinued-line-end | |
576 | (c-lang-const c-opt-cpp-prefix) | |
577 | re | |
578 | (c-lang-const c-syntactic-ws) | |
579 | "\\(<[^>\n\r]*>?\\)") | |
580 | (,(+ ncle-depth re-depth sws-depth 1) | |
581 | font-lock-string-face) | |
582 | ||
583 | ;; Use an anchored matcher to put paren syntax | |
584 | ;; on the brackets. | |
585 | (,(byte-compile | |
586 | `(lambda (limit) | |
587 | (let ((beg (match-beginning | |
588 | ,(+ ncle-depth re-depth sws-depth 1))) | |
589 | (end (1- (match-end ,(+ ncle-depth re-depth | |
590 | sws-depth 1))))) | |
591 | (if (eq (char-after end) ?>) | |
592 | (progn | |
593 | (c-mark-<-as-paren beg) | |
594 | (c-mark->-as-paren end)) | |
0ec1d2c5 AM |
595 | ;; (c-clear-char-property beg 'syntax-table) |
596 | (c-clear-char-property beg 'category))) | |
0386b551 | 597 | nil))))))) |
d9e94c22 MS |
598 | |
599 | ;; #define. | |
0386b551 AM |
600 | ,@(when (c-lang-const c-opt-cpp-macro-define) |
601 | `((,(c-make-font-lock-search-function | |
602 | (concat | |
603 | noncontinued-line-end | |
604 | (c-lang-const c-opt-cpp-prefix) | |
605 | (c-lang-const c-opt-cpp-macro-define) | |
606 | (c-lang-const c-nonempty-syntactic-ws) | |
607 | "\\(" (c-lang-const ; 1 + ncle + nsws | |
608 | c-symbol-key) "\\)" | |
609 | (concat "\\(" ; 2 + ncle + nsws + c-sym-key | |
610 | ;; Macro with arguments - a "function". | |
611 | "\\(\(\\)" ; 3 + ncle + nsws + c-sym-key | |
612 | "\\|" | |
613 | ;; Macro without arguments - a "variable". | |
614 | "\\([^\(]\\|$\\)" | |
615 | "\\)")) | |
616 | `((if (match-beginning | |
617 | ,(+ 3 ncle-depth nsws-depth | |
618 | (c-lang-const c-symbol-key-depth))) | |
619 | ||
620 | ;; "Function". Fontify the name and the arguments. | |
621 | (save-restriction | |
622 | (c-put-font-lock-face | |
623 | (match-beginning ,(+ 1 ncle-depth nsws-depth)) | |
624 | (match-end ,(+ 1 ncle-depth nsws-depth)) | |
625 | 'font-lock-function-name-face) | |
626 | (goto-char | |
627 | (match-end | |
628 | ,(+ 3 ncle-depth nsws-depth | |
629 | (c-lang-const c-symbol-key-depth)))) | |
630 | ||
631 | (narrow-to-region (point-min) limit) | |
632 | (while (and | |
633 | (progn | |
634 | (c-forward-syntactic-ws) | |
635 | (looking-at c-symbol-key)) | |
636 | (progn | |
637 | (c-put-font-lock-face | |
638 | (match-beginning 0) (match-end 0) | |
639 | 'font-lock-variable-name-face) | |
640 | (goto-char (match-end 0)) | |
641 | (c-forward-syntactic-ws) | |
642 | (eq (char-after) ?,))) | |
643 | (forward-char))) | |
644 | ||
645 | ;; "Variable". | |
646 | (c-put-font-lock-face | |
647 | (match-beginning ,(+ 1 ncle-depth nsws-depth)) | |
648 | (match-end ,(+ 1 ncle-depth nsws-depth)) | |
649 | 'font-lock-variable-name-face))))))) | |
d9e94c22 MS |
650 | |
651 | ;; Fontify cpp function names in preprocessor | |
652 | ;; expressions in #if and #elif. | |
0386b551 AM |
653 | ,@(when (and (c-lang-const c-cpp-expr-directives) |
654 | (c-lang-const c-cpp-expr-functions)) | |
655 | (let ((ced-re (c-make-keywords-re t | |
656 | (c-lang-const c-cpp-expr-directives))) | |
657 | (cef-re (c-make-keywords-re t | |
658 | (c-lang-const c-cpp-expr-functions)))) | |
b128268e AM |
659 | |
660 | `((,(c-make-font-lock-context-search-function | |
661 | `(,(concat noncontinued-line-end | |
662 | (c-lang-const c-opt-cpp-prefix) | |
663 | ced-re ; 1 + ncle-depth | |
664 | ;; Match the whole logical line to look | |
665 | ;; for the functions in. | |
666 | "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*") | |
667 | ((let ((limit (match-end 0))) | |
668 | (while (re-search-forward ,cef-re limit 'move) | |
669 | (c-put-font-lock-face (match-beginning 1) | |
670 | (match-end 1) | |
671 | c-preprocessor-face-name))) | |
672 | (goto-char (match-end ,(1+ ncle-depth))))) | |
673 | `(in-cpp-expr | |
674 | (save-excursion (c-end-of-macro) (point)) | |
675 | ,cef-re | |
676 | (1 c-preprocessor-face-name t))))))) | |
d9e94c22 MS |
677 | |
678 | ;; Fontify the directive names. | |
679 | (,(c-make-font-lock-search-function | |
680 | (concat noncontinued-line-end | |
681 | "\\(" | |
682 | (c-lang-const c-opt-cpp-prefix) | |
683 | "[" (c-lang-const c-symbol-chars) "]+" | |
684 | "\\)") | |
685 | `(,(1+ ncle-depth) c-preprocessor-face-name t))) | |
bd8cf505 | 686 | |
0386b551 AM |
687 | (eval . (list ,(c-make-syntactic-matcher |
688 | (concat noncontinued-line-end | |
689 | (c-lang-const c-opt-cpp-prefix) | |
690 | "if\\(n\\)def\\>")) | |
691 | ,(+ ncle-depth 1) | |
692 | c-negation-char-face-name | |
693 | 'append)) | |
d9e94c22 MS |
694 | ))) |
695 | ||
696 | ,@(when (c-major-mode-is 'pike-mode) | |
0386b551 | 697 | ;; Recognize hashbangs in Pike. |
d9e94c22 MS |
698 | `((eval . (list "\\`#![^\n\r]*" |
699 | 0 c-preprocessor-face-name)))) | |
700 | ||
0386b551 | 701 | ;; Make hard spaces visible through an inverted `font-lock-warning-face'. |
d9e94c22 MS |
702 | (eval . (list |
703 | "\240" | |
704 | 0 (progn | |
0386b551 AM |
705 | (unless (c-face-name-p 'c-nonbreakable-space-face) |
706 | (c-make-inverse-face 'font-lock-warning-face | |
707 | 'c-nonbreakable-space-face)) | |
708 | ''c-nonbreakable-space-face))) | |
d9e94c22 MS |
709 | )) |
710 | ||
711 | (defun c-font-lock-invalid-string () | |
712 | ;; Assuming the point is after the opening character of a string, | |
0386b551 | 713 | ;; fontify that char with `font-lock-warning-face' if the string |
a6782a6e | 714 | ;; decidedly isn't terminated properly. |
0386b551 AM |
715 | ;; |
716 | ;; This function does hidden buffer changes. | |
a6782a6e MS |
717 | (let ((start (1- (point)))) |
718 | (save-excursion | |
0386b551 AM |
719 | (and (eq (elt (parse-partial-sexp start (c-point 'eol)) 8) start) |
720 | (if (integerp c-multiline-string-start-char) | |
721 | ;; There's no multiline string start char before the | |
722 | ;; string, so newlines aren't allowed. | |
723 | (not (eq (char-before start) c-multiline-string-start-char)) | |
724 | ;; Multiline strings are allowed anywhere if | |
725 | ;; c-multiline-string-start-char is t. | |
726 | (not c-multiline-string-start-char)) | |
727 | (if c-string-escaped-newlines | |
a6782a6e MS |
728 | ;; There's no \ before the newline. |
729 | (not (eq (char-before (point)) ?\\)) | |
0386b551 | 730 | ;; Escaped newlines aren't supported. |
a6782a6e | 731 | t) |
0386b551 | 732 | (c-put-font-lock-face start (1+ start) 'font-lock-warning-face))))) |
d9e94c22 MS |
733 | |
734 | (c-lang-defconst c-basic-matchers-before | |
735 | "Font lock matchers for basic keywords, labels, references and various | |
736 | other easily recognizable things that should be fontified before generic | |
737 | casts and declarations are fontified. Used on level 2 and higher." | |
738 | ||
739 | ;; Note: `c-font-lock-declarations' assumes that no matcher here | |
740 | ;; sets `font-lock-type-face' in languages where | |
741 | ;; `c-recognize-<>-arglists' is set. | |
742 | ||
743 | t `(;; Put a warning face on the opener of unclosed strings that | |
744 | ;; can't span lines. Later font | |
745 | ;; lock packages have a `font-lock-syntactic-face-function' for | |
746 | ;; this, but it doesn't give the control we want since any | |
747 | ;; fontification done inside the function will be | |
748 | ;; unconditionally overridden. | |
749 | ,(c-make-font-lock-search-function | |
750 | ;; Match a char before the string starter to make | |
751 | ;; `c-skip-comments-and-strings' work correctly. | |
752 | (concat ".\\(" c-string-limit-regexp "\\)") | |
753 | '((c-font-lock-invalid-string))) | |
754 | ||
755 | ;; Fontify keyword constants. | |
756 | ,@(when (c-lang-const c-constant-kwds) | |
757 | (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds)))) | |
758 | (if (c-major-mode-is 'pike-mode) | |
759 | ;; No symbol is a keyword after "->" in Pike. | |
0386b551 | 760 | `((eval . (list ,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)" |
d9e94c22 | 761 | "\\<\\(" re "\\)\\>") |
0386b551 | 762 | 2 c-constant-face-name))) |
d9e94c22 MS |
763 | `((eval . (list ,(concat "\\<\\(" re "\\)\\>") |
764 | 1 c-constant-face-name)))))) | |
765 | ||
766 | ;; Fontify all keywords except the primitive types. | |
767 | ,(if (c-major-mode-is 'pike-mode) | |
768 | ;; No symbol is a keyword after "->" in Pike. | |
0386b551 | 769 | `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)" |
d9e94c22 | 770 | "\\<" (c-lang-const c-regular-keywords-regexp)) |
0386b551 | 771 | 2 font-lock-keyword-face) |
d9e94c22 MS |
772 | `(,(concat "\\<" (c-lang-const c-regular-keywords-regexp)) |
773 | 1 font-lock-keyword-face)) | |
774 | ||
775 | ;; Fontify leading identifiers in fully qualified names like | |
776 | ;; "foo::bar" in languages that supports such things. | |
777 | ,@(when (c-lang-const c-opt-identifier-concat-key) | |
2a15eb73 MS |
778 | (if (c-major-mode-is 'java-mode) |
779 | ;; Java needs special treatment since "." is used both to | |
780 | ;; qualify names and in normal indexing. Here we look for | |
781 | ;; capital characters at the beginning of an identifier to | |
782 | ;; recognize the class. "*" is also recognized to cover | |
783 | ;; wildcard import declarations. All preceding dot separated | |
784 | ;; identifiers are taken as package names and therefore | |
785 | ;; fontified as references. | |
786 | `(,(c-make-font-lock-search-function | |
787 | ;; Search for class identifiers preceded by ".". The | |
788 | ;; anchored matcher takes it from there. | |
789 | (concat (c-lang-const c-opt-identifier-concat-key) | |
0386b551 | 790 | (c-lang-const c-simple-ws) "*" |
2a15eb73 | 791 | (concat "\\(" |
0386b551 AM |
792 | "[" c-upper "]" |
793 | "[" (c-lang-const c-symbol-chars) "]*" | |
2a15eb73 MS |
794 | "\\|" |
795 | "\\*" | |
796 | "\\)")) | |
797 | `((let (id-end) | |
798 | (goto-char (1+ (match-beginning 0))) | |
799 | (while (and (eq (char-before) ?.) | |
800 | (progn | |
801 | (backward-char) | |
802 | (c-backward-syntactic-ws) | |
803 | (setq id-end (point)) | |
804 | (< (skip-chars-backward | |
805 | ,(c-lang-const c-symbol-chars)) 0)) | |
806 | (not (get-text-property (point) 'face))) | |
0386b551 AM |
807 | (c-put-font-lock-face (point) id-end |
808 | c-reference-face-name) | |
2a15eb73 MS |
809 | (c-backward-syntactic-ws))) |
810 | nil | |
811 | (goto-char (match-end 0))))) | |
812 | ||
813 | `((,(byte-compile | |
0386b551 AM |
814 | ;; Must use a function here since we match longer than |
815 | ;; we want to move before doing a new search. This is | |
816 | ;; not necessary for XEmacs since it restarts the | |
817 | ;; search from the end of the first highlighted | |
818 | ;; submatch (something that causes problems in other | |
819 | ;; places). | |
2a15eb73 MS |
820 | `(lambda (limit) |
821 | (while (re-search-forward | |
822 | ,(concat "\\(\\<" ; 1 | |
823 | "\\(" (c-lang-const c-symbol-key) "\\)" ; 2 | |
0386b551 | 824 | (c-lang-const c-simple-ws) "*" |
2a15eb73 | 825 | (c-lang-const c-opt-identifier-concat-key) |
0386b551 | 826 | (c-lang-const c-simple-ws) "*" |
2a15eb73 MS |
827 | "\\)" |
828 | "\\(" | |
829 | (c-lang-const c-opt-after-id-concat-key) | |
830 | "\\)") | |
831 | limit t) | |
832 | (unless (progn | |
833 | (goto-char (match-beginning 0)) | |
834 | (c-skip-comments-and-strings limit)) | |
835 | (or (get-text-property (match-beginning 2) 'face) | |
836 | (c-put-font-lock-face (match-beginning 2) | |
837 | (match-end 2) | |
838 | c-reference-face-name)) | |
839 | (goto-char (match-end 1)))))))))) | |
d9e94c22 MS |
840 | |
841 | ;; Fontify the special declarations in Objective-C. | |
842 | ,@(when (c-major-mode-is 'objc-mode) | |
843 | `(;; Fontify class names in the beginning of message expressions. | |
844 | ,(c-make-font-lock-search-function | |
845 | "\\[" | |
846 | '((c-fontify-types-and-refs () | |
847 | (c-forward-syntactic-ws limit) | |
848 | (let ((start (point))) | |
849 | ;; In this case we accept both primitive and known types. | |
850 | (when (eq (c-forward-type) 'known) | |
851 | (goto-char start) | |
852 | (let ((c-promote-possible-types t)) | |
853 | (c-forward-type)))) | |
854 | (if (> (point) limit) (goto-char limit))))) | |
855 | ||
856 | ;; The @interface/@implementation/@protocol directives. | |
0386b551 AM |
857 | ,(c-make-font-lock-search-function |
858 | (concat "\\<" | |
859 | (regexp-opt | |
d9e94c22 MS |
860 | '("@interface" "@implementation" "@protocol") |
861 | t) | |
862 | "\\>") | |
0386b551 AM |
863 | '((c-fontify-types-and-refs |
864 | (;; The font-lock package in Emacs is known to clobber | |
865 | ;; `parse-sexp-lookup-properties' (when it exists). | |
866 | (parse-sexp-lookup-properties | |
867 | (cc-eval-when-compile | |
868 | (boundp 'parse-sexp-lookup-properties)))) | |
869 | (c-forward-objc-directive) | |
870 | nil) | |
871 | (goto-char (match-beginning 0)))))) | |
872 | ||
873 | (eval . (list "\\(!\\)[^=]" 1 c-negation-char-face-name)) | |
d9e94c22 MS |
874 | )) |
875 | ||
876 | (defun c-font-lock-complex-decl-prepare (limit) | |
1379f2c5 AM |
877 | ;; This function will be called from font-lock for a region bounded by POINT |
878 | ;; and LIMIT, as though it were to identify a keyword for | |
879 | ;; font-lock-keyword-face. It always returns NIL to inhibit this and | |
880 | ;; prevent a repeat invocation. See elisp/lispref page "Search-based | |
881 | ;; Fontification". | |
882 | ;; | |
d9e94c22 | 883 | ;; Called before any of the matchers in `c-complex-decl-matchers'. |
0386b551 AM |
884 | ;; |
885 | ;; This function does hidden buffer changes. | |
d9e94c22 MS |
886 | |
887 | ;;(message "c-font-lock-complex-decl-prepare %s %s" (point) limit) | |
888 | ||
889 | ;; Clear the list of found types if we start from the start of the | |
890 | ;; buffer, to make it easier to get rid of misspelled types and | |
e15f8aaa | 891 | ;; variables that have gotten recognized as types in malformed code. |
d9e94c22 MS |
892 | (when (bobp) |
893 | (c-clear-found-types)) | |
894 | ||
e15f8aaa AM |
895 | ;; Clear the c-type char properties which mark the region, to recalculate |
896 | ;; them properly. The most interesting properties are those put on the | |
897 | ;; closest token before the region. | |
898 | (save-excursion | |
899 | (let ((pos (point))) | |
900 | (c-backward-syntactic-ws) | |
901 | (c-clear-char-properties | |
902 | (if (and (not (bobp)) | |
903 | (memq (c-get-char-property (1- (point)) 'c-type) | |
904 | '(c-decl-arg-start | |
905 | c-decl-end | |
906 | c-decl-id-start | |
907 | c-decl-type-start))) | |
908 | (1- (point)) | |
909 | pos) | |
910 | limit 'c-type))) | |
d9e94c22 MS |
911 | |
912 | ;; Update `c-state-cache' to the beginning of the region. This will | |
913 | ;; make `c-beginning-of-syntax' go faster when it's used later on, | |
914 | ;; and it's near the point most of the time. | |
915 | (c-parse-state) | |
916 | ||
917 | ;; Check if the fontified region starts inside a declarator list so | |
918 | ;; that `c-font-lock-declarators' should be called at the start. | |
e15f8aaa AM |
919 | ;; The declared identifiers are font-locked correctly as types, if |
920 | ;; that is what they are. | |
d9e94c22 MS |
921 | (let ((prop (save-excursion |
922 | (c-backward-syntactic-ws) | |
923 | (unless (bobp) | |
924 | (c-get-char-property (1- (point)) 'c-type))))) | |
925 | (when (memq prop '(c-decl-id-start c-decl-type-start)) | |
926 | (c-forward-syntactic-ws limit) | |
927 | (c-font-lock-declarators limit t (eq prop 'c-decl-type-start)))) | |
928 | ||
b128268e AM |
929 | (setq c-font-lock-context ;; (c-guess-font-lock-context) |
930 | (save-excursion | |
931 | (if (and c-cpp-expr-intro-re | |
932 | (c-beginning-of-macro) | |
933 | (looking-at c-cpp-expr-intro-re)) | |
934 | 'in-cpp-expr))) | |
d9e94c22 MS |
935 | nil) |
936 | ||
937 | (defun c-font-lock-<>-arglists (limit) | |
1379f2c5 AM |
938 | ;; This function will be called from font-lock for a region bounded by POINT |
939 | ;; and LIMIT, as though it were to identify a keyword for | |
940 | ;; font-lock-keyword-face. It always returns NIL to inhibit this and | |
941 | ;; prevent a repeat invocation. See elisp/lispref page "Search-based | |
942 | ;; Fontification". | |
943 | ;; | |
d9e94c22 | 944 | ;; Fontify types and references in names containing angle bracket |
0386b551 | 945 | ;; arglists from the point to LIMIT. Note that |
1379f2c5 | 946 | ;; `c-font-lock-declarations' already has handled many of them. |
0386b551 AM |
947 | ;; |
948 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
949 | |
950 | (let (;; The font-lock package in Emacs is known to clobber | |
951 | ;; `parse-sexp-lookup-properties' (when it exists). | |
952 | (parse-sexp-lookup-properties | |
953 | (cc-eval-when-compile | |
954 | (boundp 'parse-sexp-lookup-properties))) | |
0386b551 AM |
955 | (c-parse-and-markup-<>-arglists t) |
956 | c-restricted-<>-arglists | |
957 | id-start id-end id-face pos kwd-sym) | |
d9e94c22 MS |
958 | |
959 | (while (and (< (point) limit) | |
960 | (re-search-forward c-opt-<>-arglist-start limit t)) | |
961 | ||
962 | (setq id-start (match-beginning 1) | |
963 | id-end (match-end 1) | |
964 | pos (point)) | |
965 | ||
966 | (goto-char id-start) | |
967 | (unless (c-skip-comments-and-strings limit) | |
0386b551 AM |
968 | (setq kwd-sym nil |
969 | c-restricted-<>-arglists nil | |
970 | id-face (get-text-property id-start 'face)) | |
971 | ||
972 | (if (cond | |
973 | ((eq id-face 'font-lock-type-face) | |
974 | ;; The identifier got the type face so it has already been | |
975 | ;; handled in `c-font-lock-declarations'. | |
976 | nil) | |
977 | ||
978 | ((eq id-face 'font-lock-keyword-face) | |
979 | (when (looking-at c-opt-<>-sexp-key) | |
980 | ;; There's a special keyword before the "<" that tells | |
981 | ;; that it's an angle bracket arglist. | |
982 | (setq kwd-sym (c-keyword-sym (match-string 1))))) | |
983 | ||
984 | (t | |
985 | ;; There's a normal identifier before the "<". If we're not in | |
986 | ;; a declaration context then we set `c-restricted-<>-arglists' | |
987 | ;; to avoid recognizing templates in function calls like "foo (a | |
988 | ;; < b, c > d)". | |
989 | (c-backward-syntactic-ws) | |
990 | (when (and (memq (char-before) '(?\( ?,)) | |
991 | (not (eq (get-text-property (1- (point)) 'c-type) | |
992 | 'c-decl-arg-start))) | |
993 | (setq c-restricted-<>-arglists t)) | |
994 | t)) | |
995 | ||
d9e94c22 MS |
996 | (progn |
997 | (goto-char (1- pos)) | |
998 | ;; Check for comment/string both at the identifier and | |
999 | ;; at the "<". | |
1000 | (unless (c-skip-comments-and-strings limit) | |
1001 | ||
0386b551 AM |
1002 | (c-fontify-types-and-refs () |
1003 | (when (c-forward-<>-arglist (c-keyword-member | |
1004 | kwd-sym 'c-<>-type-kwds)) | |
1005 | (when (and c-opt-identifier-concat-key | |
1006 | (not (get-text-property id-start 'face))) | |
1007 | (c-forward-syntactic-ws) | |
1008 | (if (looking-at c-opt-identifier-concat-key) | |
1009 | (c-put-font-lock-face id-start id-end | |
1010 | c-reference-face-name) | |
d9e94c22 | 1011 | (c-put-font-lock-face id-start id-end |
0386b551 | 1012 | 'font-lock-type-face))))) |
d9e94c22 MS |
1013 | |
1014 | (goto-char pos))) | |
1015 | (goto-char pos))))) | |
1016 | nil) | |
1017 | ||
1018 | (defun c-font-lock-declarators (limit list types) | |
e15f8aaa AM |
1019 | ;; Assuming the point is at the start of a declarator in a declaration, |
1020 | ;; fontify the identifier it declares. (If TYPES is set, it does this via | |
1021 | ;; the macro `c-fontify-types-and-refs'.) | |
1022 | ;; | |
1023 | ;; If LIST is non-nil, also fontify the ids in any following declarators in | |
1024 | ;; a comma separated list (e.g. "foo" and "*bar" in "int foo = 17, *bar;"); | |
1025 | ;; additionally, mark the commas with c-type property 'c-decl-id-start or | |
1026 | ;; 'c-decl-type-start (according to TYPES). Stop at LIMIT. | |
1027 | ;; | |
1028 | ;; If TYPES is non-nil, fontify all identifiers as types. | |
1029 | ;; | |
1030 | ;; Nil is always returned. The function leaves point at the delimiter after | |
1031 | ;; the last declarator it processes. | |
0386b551 AM |
1032 | ;; |
1033 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
1034 | |
1035 | ;;(message "c-font-lock-declarators from %s to %s" (point) limit) | |
1036 | (c-fontify-types-and-refs | |
1037 | ((pos (point)) next-pos id-start id-end | |
1038 | paren-depth | |
1039 | id-face got-init | |
1040 | c-last-identifier-range | |
1041 | (separator-prop (if types 'c-decl-type-start 'c-decl-id-start))) | |
1042 | ||
e15f8aaa AM |
1043 | ;; The following `while' fontifies a single declarator id each time round. |
1044 | ;; It loops only when LIST is non-nil. | |
1045 | (while | |
1046 | ;; Inside the following "condition form", we move forward over the | |
1047 | ;; declarator's identifier up as far as any opening bracket (for array | |
1048 | ;; size) or paren (for parameters of function-type) or brace (for | |
e1dbe924 | 1049 | ;; array/struct initialization) or "=" or terminating delimiter |
e15f8aaa AM |
1050 | ;; (e.g. "," or ";" or "}"). |
1051 | (and | |
d9e94c22 MS |
1052 | pos |
1053 | (< (point) limit) | |
1054 | ||
e15f8aaa AM |
1055 | ;; The following form moves forward over the declarator's |
1056 | ;; identifier (and what precedes it), returning t. If there | |
1057 | ;; wasn't one, it returns nil, terminating the `while'. | |
d9e94c22 MS |
1058 | (let (got-identifier) |
1059 | (setq paren-depth 0) | |
e15f8aaa AM |
1060 | ;; Skip over type decl prefix operators, one for each iteration |
1061 | ;; of the while. These are, e.g. "*" in "int *foo" or "(" and | |
1062 | ;; "*" in "int (*foo) (void)" (Note similar code in | |
1063 | ;; `c-forward-decl-or-cast-1'.) | |
d9e94c22 MS |
1064 | (while (and (looking-at c-type-decl-prefix-key) |
1065 | (if (and (c-major-mode-is 'c++-mode) | |
e15f8aaa AM |
1066 | (match-beginning 3)) |
1067 | ;; If the third submatch matches in C++ then | |
d9e94c22 MS |
1068 | ;; we're looking at an identifier that's a |
1069 | ;; prefix only if it specifies a member pointer. | |
1070 | (progn | |
1071 | (setq id-start (point)) | |
1072 | (c-forward-name) | |
1073 | (if (looking-at "\\(::\\)") | |
1074 | ;; We only check for a trailing "::" and | |
1075 | ;; let the "*" that should follow be | |
1076 | ;; matched in the next round. | |
1077 | t | |
1078 | ;; It turned out to be the real identifier, | |
1079 | ;; so flag that and stop. | |
1080 | (setq got-identifier t) | |
1081 | nil)) | |
1082 | t)) | |
1083 | (if (eq (char-after) ?\() | |
1084 | (progn | |
1085 | (setq paren-depth (1+ paren-depth)) | |
1086 | (forward-char)) | |
1087 | (goto-char (match-end 1))) | |
1088 | (c-forward-syntactic-ws)) | |
1089 | ||
e15f8aaa | 1090 | ;; If we haven't passed the identifier already, do it now. |
d9e94c22 MS |
1091 | (unless got-identifier |
1092 | (setq id-start (point)) | |
1093 | (c-forward-name)) | |
1094 | (setq id-end (point)) | |
1095 | ||
1096 | (/= id-end pos)) | |
1097 | ||
e15f8aaa AM |
1098 | ;; Skip out of the parens surrounding the identifier. If closing |
1099 | ;; parens are missing, this form returns nil. | |
d9e94c22 MS |
1100 | (or (= paren-depth 0) |
1101 | (c-safe (goto-char (scan-lists (point) 1 paren-depth)))) | |
1102 | ||
1103 | (<= (point) limit) | |
1104 | ||
e15f8aaa | 1105 | ;; Skip over any trailing bit, such as "__attribute__". |
0386b551 AM |
1106 | (progn |
1107 | (when (looking-at c-decl-hangon-key) | |
1108 | (c-forward-keyword-clause 1)) | |
1109 | (<= (point) limit)) | |
1110 | ||
d9e94c22 | 1111 | ;; Search syntactically to the end of the declarator (";", |
da6062e6 | 1112 | ;; ",", a closing paren, eob etc) or to the beginning of an |
2a15eb73 MS |
1113 | ;; initializer or function prototype ("=" or "\\s\("). |
1114 | ;; Note that the open paren will match array specs in | |
1115 | ;; square brackets, and we treat them as initializers too. | |
d9e94c22 | 1116 | (c-syntactic-re-search-forward |
2a15eb73 | 1117 | "[;,]\\|\\s)\\|\\'\\|\\(=\\|\\s(\\)" limit t t)) |
d9e94c22 MS |
1118 | |
1119 | (setq next-pos (match-beginning 0) | |
39f7186c CY |
1120 | id-face (if (and (eq (char-after next-pos) ?\() |
1121 | (let (c-last-identifier-range) | |
1122 | (save-excursion | |
1123 | (goto-char next-pos) | |
1124 | (c-at-toplevel-p)))) | |
d9e94c22 MS |
1125 | 'font-lock-function-name-face |
1126 | 'font-lock-variable-name-face) | |
2a15eb73 MS |
1127 | got-init (and (match-beginning 1) |
1128 | (char-after (match-beginning 1)))) | |
d9e94c22 MS |
1129 | |
1130 | (if types | |
53964682 | 1131 | ;; Register and fontify the identifier as a type. |
d9e94c22 MS |
1132 | (let ((c-promote-possible-types t)) |
1133 | (goto-char id-start) | |
1134 | (c-forward-type)) | |
1135 | ;; Fontify the last symbol in the identifier if it isn't fontified | |
1136 | ;; already. The check is necessary only in certain cases where this | |
1137 | ;; function is used "sloppily", e.g. in `c-simple-decl-matchers'. | |
1138 | (when (and c-last-identifier-range | |
1139 | (not (get-text-property (car c-last-identifier-range) | |
1140 | 'face))) | |
1141 | (c-put-font-lock-face (car c-last-identifier-range) | |
1142 | (cdr c-last-identifier-range) | |
1143 | id-face))) | |
1144 | ||
1145 | (goto-char next-pos) | |
e15f8aaa | 1146 | (setq pos nil) ; So as to terminate the enclosing `while' form. |
d9e94c22 MS |
1147 | (when list |
1148 | ;; Jump past any initializer or function prototype to see if | |
1149 | ;; there's a ',' to continue at. | |
1150 | ||
1151 | (cond ((eq id-face 'font-lock-function-name-face) | |
1152 | ;; Skip a parenthesized initializer (C++) or a function | |
1153 | ;; prototype. | |
e15f8aaa | 1154 | (if (c-safe (c-forward-sexp 1) t) ; over the parameter list. |
d9e94c22 | 1155 | (c-forward-syntactic-ws limit) |
e15f8aaa | 1156 | (goto-char limit))) ; unbalanced parens |
d9e94c22 | 1157 | |
e15f8aaa | 1158 | (got-init ; "=" sign OR opening "(", "[", or "{" |
2a15eb73 MS |
1159 | ;; Skip an initializer expression. If we're at a '=' |
1160 | ;; then accept a brace list directly after it to cope | |
1161 | ;; with array initializers. Otherwise stop at braces | |
1162 | ;; to avoid going past full function and class blocks. | |
1163 | (and (if (and (eq got-init ?=) | |
3efc2cd7 | 1164 | (= (c-forward-token-2 1 nil limit) 0) |
2a15eb73 | 1165 | (looking-at "{")) |
e15f8aaa | 1166 | (c-safe (c-forward-sexp) t) ; over { .... } |
2a15eb73 | 1167 | t) |
0386b551 AM |
1168 | ;; FIXME: Should look for c-decl-end markers here; |
1169 | ;; we might go far into the following declarations | |
1170 | ;; in e.g. ObjC mode (see e.g. methods-4.m). | |
2a15eb73 MS |
1171 | (c-syntactic-re-search-forward "[;,{]" limit 'move t) |
1172 | (backward-char))) | |
d9e94c22 MS |
1173 | |
1174 | (t (c-forward-syntactic-ws limit))) | |
1175 | ||
1176 | ;; If a ',' is found we set pos to the next declarator and iterate. | |
1177 | (when (and (< (point) limit) (looking-at ",")) | |
1178 | (c-put-char-property (point) 'c-type separator-prop) | |
1179 | (forward-char) | |
1180 | (c-forward-syntactic-ws limit) | |
e15f8aaa | 1181 | (setq pos (point)))))) ; acts to make the `while' form continue. |
d9e94c22 MS |
1182 | nil) |
1183 | ||
1184 | (defconst c-font-lock-maybe-decl-faces | |
1185 | ;; List of faces that might be put at the start of a type when | |
1186 | ;; `c-font-lock-declarations' runs. This needs to be evaluated to | |
1187 | ;; ensure that face name aliases in Emacs are resolved. | |
1188 | (list nil | |
1189 | font-lock-type-face | |
1190 | c-reference-face-name | |
1191 | font-lock-keyword-face)) | |
1192 | ||
d9e94c22 | 1193 | (defun c-font-lock-declarations (limit) |
e15f8aaa AM |
1194 | ;; Fontify all the declarations, casts and labels from the point to LIMIT. |
1195 | ;; Assumes that strings and comments have been fontified already. | |
1196 | ;; | |
1379f2c5 AM |
1197 | ;; This function will be called from font-lock for a region bounded by POINT |
1198 | ;; and LIMIT, as though it were to identify a keyword for | |
1199 | ;; font-lock-keyword-face. It always returns NIL to inhibit this and | |
1200 | ;; prevent a repeat invocation. See elisp/lispref page "Search-based | |
1201 | ;; Fontification". | |
1202 | ;; | |
0386b551 | 1203 | ;; This function might do hidden buffer changes. |
d9e94c22 MS |
1204 | |
1205 | ;;(message "c-font-lock-declarations search from %s to %s" (point) limit) | |
1206 | ||
1207 | (save-restriction | |
e15f8aaa | 1208 | (let (;; The position where `c-find-decl-spots' last stopped. |
0386b551 | 1209 | start-pos |
e15f8aaa AM |
1210 | ;; o - 'decl if we're in an arglist containing declarations |
1211 | ;; (but if `c-recognize-paren-inits' is set it might also be | |
1212 | ;; an initializer arglist); | |
1213 | ;; o - '<> if the arglist is of angle bracket type; | |
1214 | ;; o - 'arglist if it's some other arglist; | |
1215 | ;; o - nil, if not in an arglist at all. This includes the | |
333f9019 | 1216 | ;; parenthesized condition which follows "if", "while", etc. |
0386b551 AM |
1217 | context |
1218 | ;; The position of the next token after the closing paren of | |
1219 | ;; the last detected cast. | |
d9e94c22 | 1220 | last-cast-end |
0386b551 AM |
1221 | ;; The result from `c-forward-decl-or-cast-1'. |
1222 | decl-or-cast | |
1223 | ;; The maximum of the end positions of all the checked type | |
1224 | ;; decl expressions in the successfully identified | |
1225 | ;; declarations. The position might be either before or | |
1226 | ;; after the syntactic whitespace following the last token | |
1227 | ;; in the type decl expression. | |
d9e94c22 MS |
1228 | (max-type-decl-end 0) |
1229 | ;; Same as `max-type-decl-*', but used when we're before | |
1230 | ;; `token-pos'. | |
1231 | (max-type-decl-end-before-token 0) | |
0386b551 AM |
1232 | ;; Set according to the context to direct the heuristics for |
1233 | ;; recognizing C++ templates. | |
1234 | c-restricted-<>-arglists | |
1235 | ;; Turn on recording of identifier ranges in | |
1236 | ;; `c-forward-decl-or-cast-1' and `c-forward-label' for | |
1237 | ;; later fontification. | |
1238 | (c-record-type-identifiers t) | |
1379f2c5 | 1239 | label-type |
d9e94c22 | 1240 | c-record-ref-identifiers |
0386b551 AM |
1241 | ;; Make `c-forward-type' calls mark up template arglists if |
1242 | ;; it finds any. That's necessary so that we later will | |
1243 | ;; stop inside them to fontify types there. | |
1244 | (c-parse-and-markup-<>-arglists t) | |
9657183b | 1245 | lbrace ; position of some {. |
d9e94c22 MS |
1246 | ;; The font-lock package in Emacs is known to clobber |
1247 | ;; `parse-sexp-lookup-properties' (when it exists). | |
1248 | (parse-sexp-lookup-properties | |
1249 | (cc-eval-when-compile | |
1250 | (boundp 'parse-sexp-lookup-properties)))) | |
1251 | ||
1252 | ;; Below we fontify a whole declaration even when it crosses the limit, | |
abfc152b | 1253 | ;; to avoid gaps when jit/lazy-lock fontifies the file a block at a |
d9e94c22 MS |
1254 | ;; time. That is however annoying during editing, e.g. the following is |
1255 | ;; a common situation while the first line is being written: | |
1256 | ;; | |
1257 | ;; my_variable | |
1258 | ;; some_other_variable = 0; | |
1259 | ;; | |
1260 | ;; font-lock will put the limit at the beginning of the second line | |
1261 | ;; here, and if we go past it we'll fontify "my_variable" as a type and | |
1262 | ;; "some_other_variable" as an identifier, and the latter will not | |
1263 | ;; correct itself until the second line is changed. To avoid that we | |
1264 | ;; narrow to the limit if the region to fontify is a single line. | |
abfc152b AM |
1265 | (if (<= limit (c-point 'bonl)) |
1266 | (narrow-to-region | |
1267 | (point-min) | |
0386b551 AM |
1268 | (save-excursion |
1269 | ;; Narrow after any operator chars following the limit though, | |
1270 | ;; since those characters can be useful in recognizing a | |
1271 | ;; declaration (in particular the '{' that opens a function body | |
1272 | ;; after the header). | |
1273 | (goto-char limit) | |
1274 | (skip-chars-forward c-nonsymbol-chars) | |
abfc152b | 1275 | (point)))) |
d9e94c22 MS |
1276 | |
1277 | (c-find-decl-spots | |
1278 | limit | |
0386b551 | 1279 | c-decl-start-re |
d9e94c22 MS |
1280 | c-font-lock-maybe-decl-faces |
1281 | ||
1282 | (lambda (match-pos inside-macro) | |
0386b551 AM |
1283 | (setq start-pos (point)) |
1284 | (when | |
1285 | ;; The result of the form below is true when we don't recognize a | |
1286 | ;; declaration or cast. | |
536610a4 AM |
1287 | (if (or (and (eq (get-text-property (point) 'face) |
1288 | 'font-lock-keyword-face) | |
1289 | (looking-at c-not-decl-init-keywords)) | |
1290 | (and c-macro-with-semi-re | |
1291 | (looking-at c-macro-with-semi-re))) ; 2008-11-04 | |
0386b551 AM |
1292 | ;; Don't do anything more if we're looking at a keyword that |
1293 | ;; can't start a declaration. | |
1294 | t | |
1295 | ||
e15f8aaa AM |
1296 | ;; Set `context' and `c-restricted-<>-arglists'. Look for |
1297 | ;; "<" for the sake of C++-style template arglists. | |
1298 | ;; Ignore "(" when it's part of a control flow construct | |
1299 | ;; (e.g. "for ("). | |
1300 | (let ((type (and (> match-pos (point-min)) | |
1301 | (c-get-char-property (1- match-pos) 'c-type)))) | |
1302 | (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?<))) | |
1303 | (setq context nil | |
1304 | c-restricted-<>-arglists nil)) | |
1305 | ;; A control flow expression | |
1306 | ((and (eq (char-before match-pos) ?\() | |
1307 | (save-excursion | |
1308 | (goto-char match-pos) | |
1309 | (backward-char) | |
1310 | (c-backward-token-2) | |
1311 | (looking-at c-block-stmt-2-key))) | |
1312 | (setq context nil | |
1313 | c-restricted-<>-arglists t)) | |
1314 | ;; Near BOB. | |
1315 | ((<= match-pos (point-min)) | |
1316 | (setq context 'arglist | |
1317 | c-restricted-<>-arglists t)) | |
1318 | ;; Got a cached hit in a declaration arglist. | |
1319 | ((eq type 'c-decl-arg-start) | |
1320 | (setq context 'decl | |
1321 | c-restricted-<>-arglists nil)) | |
1322 | ;; Inside an angle bracket arglist. | |
1323 | ((or (eq type 'c-<>-arg-sep) | |
1324 | (eq (char-before match-pos) ?<)) | |
1325 | (setq context '<> | |
1326 | c-restricted-<>-arglists nil)) | |
1327 | ;; Got a cached hit in some other type of arglist. | |
1328 | (type | |
1329 | (setq context 'arglist | |
1330 | c-restricted-<>-arglists t)) | |
1331 | ((if inside-macro | |
1332 | (< match-pos max-type-decl-end-before-token) | |
1333 | (< match-pos max-type-decl-end)) | |
1334 | ;; The point is within the range of a previously | |
1335 | ;; encountered type decl expression, so the arglist | |
1336 | ;; is probably one that contains declarations. | |
1337 | ;; However, if `c-recognize-paren-inits' is set it | |
1338 | ;; might also be an initializer arglist. | |
1339 | (setq context 'decl | |
1340 | c-restricted-<>-arglists nil) | |
1341 | ;; The result of this check is cached with a char | |
1342 | ;; property on the match token, so that we can look | |
1343 | ;; it up again when refontifying single lines in a | |
1344 | ;; multiline declaration. | |
1345 | (c-put-char-property (1- match-pos) | |
1346 | 'c-type 'c-decl-arg-start)) | |
1347 | (t (setq context 'arglist | |
1348 | c-restricted-<>-arglists t)))) | |
1349 | ||
1350 | ;; Check we haven't missed a preceding "typedef". | |
1351 | (when (not (looking-at c-typedef-key)) | |
1352 | (c-backward-syntactic-ws) | |
1353 | (c-backward-token-2) | |
1354 | (or (looking-at c-typedef-key) | |
1355 | (goto-char start-pos))) | |
1356 | ||
b248a85d AM |
1357 | ;; In QT, "more" is an irritating keyword that expands to nothing. |
1358 | ;; We skip over it to prevent recognition of "more slots: <symbol>" | |
1359 | ;; as a bitfield declaration. | |
1360 | (when (and (c-major-mode-is 'c++-mode) | |
1361 | (looking-at | |
1362 | (concat "\\(more\\)\\([^" c-symbol-chars "]\\|$\\)"))) | |
1363 | (goto-char (match-end 1)) | |
1364 | (c-forward-syntactic-ws)) | |
9657183b AM |
1365 | |
1366 | ;; Now analyze the construct. | |
e15f8aaa | 1367 | (setq decl-or-cast (c-forward-decl-or-cast-1 |
0386b551 AM |
1368 | match-pos context last-cast-end)) |
1369 | ||
8c0e3589 AM |
1370 | (cond |
1371 | ((eq decl-or-cast 'cast) | |
1372 | ;; Save the position after the previous cast so we can feed | |
1373 | ;; it to `c-forward-decl-or-cast-1' in the next round. That | |
1374 | ;; helps it discover cast chains like "(a) (b) c". | |
1375 | (setq last-cast-end (point)) | |
1376 | (c-fontify-recorded-types-and-refs) | |
1377 | nil) | |
10f5e3e6 | 1378 | |
8c0e3589 AM |
1379 | (decl-or-cast |
1380 | ;; We've found a declaration. | |
1381 | ||
1382 | ;; Set `max-type-decl-end' or `max-type-decl-end-before-token' | |
1383 | ;; under the assumption that we're after the first type decl | |
1384 | ;; expression in the declaration now. That's not really true; | |
1385 | ;; we could also be after a parenthesized initializer | |
1386 | ;; expression in C++, but this is only used as a last resort | |
1387 | ;; to slant ambiguous expression/declarations, and overall | |
1388 | ;; it's worth the risk to occasionally fontify an expression | |
1389 | ;; as a declaration in an initializer expression compared to | |
1390 | ;; getting ambiguous things in normal function prototypes | |
1391 | ;; fontified as expressions. | |
1392 | (if inside-macro | |
1393 | (when (> (point) max-type-decl-end-before-token) | |
1394 | (setq max-type-decl-end-before-token (point))) | |
1395 | (when (> (point) max-type-decl-end) | |
1396 | (setq max-type-decl-end (point)))) | |
1397 | ||
1398 | ;; Back up to the type to fontify the declarator(s). | |
1399 | (goto-char (car decl-or-cast)) | |
1400 | ||
1401 | (let ((decl-list | |
1402 | (if context | |
1403 | ;; Should normally not fontify a list of | |
1404 | ;; declarators inside an arglist, but the first | |
1405 | ;; argument in the ';' separated list of a "for" | |
1406 | ;; statement is an exception. | |
1407 | (when (eq (char-before match-pos) ?\() | |
1408 | (save-excursion | |
1409 | (goto-char (1- match-pos)) | |
1410 | (c-backward-syntactic-ws) | |
1411 | (and (c-simple-skip-symbol-backward) | |
1412 | (looking-at c-paren-stmt-key)))) | |
1413 | t))) | |
1414 | ||
1415 | ;; Fix the `c-decl-id-start' or `c-decl-type-start' property | |
1416 | ;; before the first declarator if it's a list. | |
1417 | ;; `c-font-lock-declarators' handles the rest. | |
1418 | (when decl-list | |
e15f8aaa | 1419 | (save-excursion |
8c0e3589 AM |
1420 | (c-backward-syntactic-ws) |
1421 | (unless (bobp) | |
1422 | (c-put-char-property (1- (point)) 'c-type | |
1423 | (if (cdr decl-or-cast) | |
1424 | 'c-decl-type-start | |
1425 | 'c-decl-id-start))))) | |
1426 | ||
1427 | (c-font-lock-declarators | |
1428 | (point-max) decl-list (cdr decl-or-cast))) | |
1429 | ||
1430 | ;; A declaration has been successfully identified, so do all the | |
1431 | ;; fontification of types and refs that've been recorded. | |
0386b551 | 1432 | (c-fontify-recorded-types-and-refs) |
8c0e3589 AM |
1433 | nil) |
1434 | ||
9657183b AM |
1435 | ;; Restore point, since at this point in the code it has been |
1436 | ;; left undefined by c-forward-decl-or-cast-1 above. | |
1437 | ((progn (goto-char start-pos) nil)) | |
1438 | ||
1439 | ;; If point is inside a bracelist, there's no point checking it | |
1440 | ;; being at a declarator. | |
1441 | ((let ((paren-state (c-parse-state))) | |
1442 | (setq lbrace (c-cheap-inside-bracelist-p paren-state))) | |
1443 | ;; Move past this bracelist to prevent an endless loop. | |
1444 | (goto-char lbrace) | |
1445 | (unless (c-safe (progn (forward-list) t)) | |
1446 | (goto-char start-pos) | |
1447 | (c-forward-token-2)) | |
1448 | nil) | |
1449 | ||
1450 | ;; If point is just after a ")" which is followed by an | |
1451 | ;; identifier which isn't a label, or at the matching "(", we're | |
1452 | ;; at either a macro invocation, a cast, or a | |
1453 | ;; for/while/etc. statement. The cast case is handled above. | |
1454 | ;; None of these cases can contain a declarator. | |
1455 | ((or (and (eq (char-before match-pos) ?\)) | |
1456 | (c-on-identifier) | |
1457 | (save-excursion (not (c-forward-label)))) | |
1458 | (and (eq (char-after) ?\() | |
1459 | (save-excursion | |
1460 | (and | |
1461 | (progn (c-backward-token-2) (c-on-identifier)) | |
1462 | (save-excursion (not (c-forward-label))) | |
1463 | (progn (c-backward-token-2) | |
1464 | (eq (char-after) ?\()))))) | |
1465 | (c-forward-token-2) ; Must prevent looping. | |
1466 | nil) | |
1467 | ||
9d5a8f0b | 1468 | ((and (not c-enums-contain-decls) |
27e428e7 | 1469 | ;; An optimization quickly to eliminate scans of long enum |
9d5a8f0b AM |
1470 | ;; declarations in the next cond arm. |
1471 | (let ((paren-state (c-parse-state))) | |
1472 | (and | |
1473 | (numberp (car paren-state)) | |
1474 | (save-excursion | |
1475 | (goto-char (car paren-state)) | |
1476 | (c-backward-token-2) | |
1477 | (or (looking-at c-brace-list-key) | |
1478 | (progn | |
1479 | (c-backward-token-2) | |
1480 | (looking-at c-brace-list-key))))))) | |
9657183b AM |
1481 | (c-forward-token-2) |
1482 | nil) | |
9d5a8f0b | 1483 | |
8c0e3589 AM |
1484 | (t |
1485 | ;; Are we at a declarator? Try to go back to the declaration | |
1486 | ;; to check this. If we get there, check whether a "typedef" | |
1487 | ;; is there, then fontify the declarators accordingly. | |
9657183b | 1488 | (let ((decl-search-lim (c-determine-limit 1000)) |
7d0ee75c | 1489 | paren-state bod-res encl-pos is-typedef |
8c0e3589 AM |
1490 | c-recognize-knr-p) ; Strictly speaking, bogus, but it |
1491 | ; speeds up lisp.h tremendously. | |
1492 | (save-excursion | |
1493 | (setq bod-res (car (c-beginning-of-decl-1 decl-search-lim))) | |
1494 | (if (and (eq bod-res 'same) | |
1495 | (progn | |
1496 | (c-backward-syntactic-ws) | |
1497 | (eq (char-before) ?\}))) | |
1498 | (c-beginning-of-decl-1 decl-search-lim)) | |
1499 | ||
1500 | ;; We're now putatively at the declaration. | |
1501 | (setq paren-state (c-parse-state)) | |
1502 | ;; At top level or inside a "{"? | |
1503 | (if (or (not (setq encl-pos | |
1504 | (c-most-enclosing-brace paren-state))) | |
1505 | (eq (char-after encl-pos) ?\{)) | |
1506 | (progn | |
1507 | (when (looking-at c-typedef-key) ; "typedef" | |
1508 | (setq is-typedef t) | |
1509 | (goto-char (match-end 0)) | |
1510 | (c-forward-syntactic-ws)) | |
1511 | ;; At a real declaration? | |
1512 | (if (memq (c-forward-type t) '(t known found)) | |
1513 | (progn | |
1514 | (c-font-lock-declarators limit t is-typedef) | |
1515 | nil) | |
1516 | ;; False alarm. Return t to go on to the next check. | |
1517 | (goto-char start-pos) | |
1518 | t)) | |
1519 | t)))))) | |
0386b551 | 1520 | |
1379f2c5 AM |
1521 | ;; It was a false alarm. Check if we're in a label (or other |
1522 | ;; construct with `:' except bitfield) instead. | |
0386b551 | 1523 | (goto-char start-pos) |
1379f2c5 AM |
1524 | (when (setq label-type (c-forward-label t match-pos nil)) |
1525 | ;; Can't use `c-fontify-types-and-refs' here since we | |
1526 | ;; use the label face at times. | |
1527 | (cond ((eq label-type 'goto-target) | |
1528 | (c-put-font-lock-face (caar c-record-ref-identifiers) | |
1529 | (cdar c-record-ref-identifiers) | |
1530 | c-label-face-name)) | |
1531 | ((eq label-type 'qt-1kwd-colon) | |
1532 | (c-put-font-lock-face (caar c-record-ref-identifiers) | |
1533 | (cdar c-record-ref-identifiers) | |
1534 | 'font-lock-keyword-face)) | |
1535 | ((eq label-type 'qt-2kwds-colon) | |
1536 | (mapc | |
1537 | (lambda (kwd) | |
1538 | (c-put-font-lock-face (car kwd) (cdr kwd) | |
1539 | 'font-lock-keyword-face)) | |
1540 | c-record-ref-identifiers))) | |
1541 | (setq c-record-ref-identifiers nil) | |
1542 | ;; `c-forward-label' has probably added a `c-decl-end' | |
1543 | ;; marker, so return t to `c-find-decl-spots' to signal | |
1544 | ;; that. | |
1545 | t)))) | |
d9e94c22 MS |
1546 | |
1547 | nil))) | |
1548 | ||
4f9e41e4 AM |
1549 | (defun c-font-lock-enum-tail (limit) |
1550 | ;; Fontify an enum's identifiers when POINT is within the enum's brace | |
1551 | ;; block. | |
1552 | ;; | |
1553 | ;; This function will be called from font-lock for a region bounded by POINT | |
1554 | ;; and LIMIT, as though it were to identify a keyword for | |
1555 | ;; font-lock-keyword-face. It always returns NIL to inhibit this and | |
1556 | ;; prevent a repeat invocation. See elisp/lispref page "Search-based | |
1557 | ;; Fontification". | |
1558 | ;; | |
1559 | ;; Note that this function won't attempt to fontify beyond the end of the | |
1560 | ;; current enum block, if any. | |
1561 | (let* ((paren-state (c-parse-state)) | |
1562 | (encl-pos (c-most-enclosing-brace paren-state)) | |
1563 | (start (point)) | |
1564 | ) | |
1565 | (when (and | |
1566 | encl-pos | |
1567 | (eq (char-after encl-pos) ?\{) | |
1568 | (save-excursion | |
1569 | (goto-char encl-pos) | |
1570 | (c-backward-syntactic-ws) | |
1571 | (c-simple-skip-symbol-backward) | |
1572 | (or (looking-at c-brace-list-key) ; "enum" | |
1573 | (progn (c-backward-syntactic-ws) | |
1574 | (c-simple-skip-symbol-backward) | |
1575 | (looking-at c-brace-list-key))))) | |
1576 | (c-syntactic-skip-backward "^{," nil t) | |
1577 | (c-put-char-property (1- (point)) 'c-type 'c-decl-id-start) | |
1578 | ||
1579 | (c-forward-syntactic-ws) | |
1580 | (c-font-lock-declarators limit t nil))) | |
1581 | nil) | |
1582 | ||
bf2c1571 AM |
1583 | (defun c-font-lock-enclosing-decls (limit) |
1584 | ;; Fontify the declarators of (nested) declarations we're in the middle of. | |
1585 | ;; This is mainly for when a jit-lock etc. chunk starts inside the brace | |
1586 | ;; block of a struct/union/class, etc. | |
7d0ee75c | 1587 | ;; |
bf2c1571 AM |
1588 | ;; This function will be called from font-lock for a region bounded by POINT |
1589 | ;; and LIMIT, as though it were to identify a keyword for | |
1590 | ;; font-lock-keyword-face. It always returns NIL to inhibit this and | |
1591 | ;; prevent a repeat invocation. See elisp/lispref page "Search-based | |
1592 | ;; Fontification". | |
1593 | (let* ((paren-state (c-parse-state)) | |
3f6b93cd | 1594 | (decl-search-lim (c-determine-limit 1000)) |
cb5e207c AM |
1595 | decl-context in-typedef ps-elt) |
1596 | ;; Are we in any nested struct/union/class/etc. braces? | |
bf2c1571 AM |
1597 | (while paren-state |
1598 | (setq ps-elt (car paren-state) | |
1599 | paren-state (cdr paren-state)) | |
1600 | (when (and (atom ps-elt) | |
1601 | (eq (char-after ps-elt) ?\{)) | |
1602 | (goto-char ps-elt) | |
3f6b93cd | 1603 | (setq decl-context (c-beginning-of-decl-1 decl-search-lim) |
bf2c1571 AM |
1604 | in-typedef (looking-at c-typedef-key)) |
1605 | (if in-typedef (c-forward-token-2)) | |
ff7271b9 OT |
1606 | (when (and c-opt-block-decls-with-vars-key |
1607 | (looking-at c-opt-block-decls-with-vars-key)) | |
bf2c1571 AM |
1608 | (goto-char ps-elt) |
1609 | (when (c-safe (c-forward-sexp)) | |
1610 | (c-forward-syntactic-ws) | |
1611 | (c-font-lock-declarators limit t in-typedef))))))) | |
7d0ee75c | 1612 | |
d9e94c22 MS |
1613 | (c-lang-defconst c-simple-decl-matchers |
1614 | "Simple font lock matchers for types and declarations. These are used | |
1615 | on level 2 only and so aren't combined with `c-complex-decl-matchers'." | |
1616 | ||
1617 | t `(;; Objective-C methods. | |
1618 | ,@(when (c-major-mode-is 'objc-mode) | |
1619 | `((,(c-lang-const c-opt-method-key) | |
1620 | (,(byte-compile | |
1621 | (lambda (limit) | |
1622 | (let (;; The font-lock package in Emacs is known to clobber | |
1623 | ;; `parse-sexp-lookup-properties' (when it exists). | |
1624 | (parse-sexp-lookup-properties | |
1625 | (cc-eval-when-compile | |
1626 | (boundp 'parse-sexp-lookup-properties)))) | |
1627 | (save-restriction | |
1628 | (narrow-to-region (point-min) limit) | |
1629 | (c-font-lock-objc-method))) | |
1630 | nil)) | |
1631 | (goto-char (match-end 1)))))) | |
1632 | ||
1633 | ;; Fontify all type names and the identifiers in the | |
1634 | ;; declarations they might start. Use eval here since | |
1635 | ;; `c-known-type-key' gets its value from | |
1636 | ;; `*-font-lock-extra-types' on mode init. | |
1637 | (eval . (list ,(c-make-font-lock-search-function | |
1638 | 'c-known-type-key | |
1639 | '(1 'font-lock-type-face t) | |
1640 | '((c-font-lock-declarators limit t nil) | |
1641 | (save-match-data | |
1642 | (goto-char (match-end 1)) | |
1643 | (c-forward-syntactic-ws)) | |
1644 | (goto-char (match-end 1)))))) | |
1645 | ||
1646 | ;; Fontify types preceded by `c-type-prefix-kwds' and the | |
1647 | ;; identifiers in the declarations they might start. | |
1648 | ,@(when (c-lang-const c-type-prefix-kwds) | |
0386b551 AM |
1649 | (let* ((prefix-re (c-make-keywords-re nil |
1650 | (c-lang-const c-type-prefix-kwds))) | |
1651 | (type-match (+ 2 | |
1652 | (regexp-opt-depth prefix-re) | |
1653 | (c-lang-const c-simple-ws-depth)))) | |
d9e94c22 | 1654 | `((,(c-make-font-lock-search-function |
0386b551 AM |
1655 | (concat "\\<\\(" prefix-re "\\)" ; 1 |
1656 | (c-lang-const c-simple-ws) "+" | |
1657 | (concat "\\(" ; 2 + prefix-re + c-simple-ws | |
1658 | (c-lang-const c-symbol-key) | |
1659 | "\\)")) | |
1660 | `(,type-match | |
d9e94c22 | 1661 | 'font-lock-type-face t) |
0386b551 | 1662 | `((c-font-lock-declarators limit t nil) |
d9e94c22 | 1663 | (save-match-data |
0386b551 | 1664 | (goto-char (match-end ,type-match)) |
d9e94c22 | 1665 | (c-forward-syntactic-ws)) |
0386b551 | 1666 | (goto-char (match-end ,type-match)))))))) |
d9e94c22 MS |
1667 | |
1668 | ;; Fontify special declarations that lacks a type. | |
1669 | ,@(when (c-lang-const c-typeless-decl-kwds) | |
1670 | `((,(c-make-font-lock-search-function | |
1671 | (concat "\\<\\(" | |
0386b551 | 1672 | (regexp-opt (c-lang-const c-typeless-decl-kwds)) |
d9e94c22 MS |
1673 | "\\)\\>") |
1674 | '((c-font-lock-declarators limit t nil) | |
1675 | (save-match-data | |
1676 | (goto-char (match-end 1)) | |
1677 | (c-forward-syntactic-ws)) | |
1678 | (goto-char (match-end 1))))))) | |
0386b551 AM |
1679 | |
1680 | ;; Fontify generic colon labels in languages that support them. | |
1681 | ,@(when (c-lang-const c-recognize-colon-labels) | |
1682 | `(c-font-lock-labels)))) | |
d9e94c22 MS |
1683 | |
1684 | (c-lang-defconst c-complex-decl-matchers | |
1685 | "Complex font lock matchers for types and declarations. Used on level | |
1686 | 3 and higher." | |
1687 | ||
e15f8aaa | 1688 | ;; Note: This code in this form dumps a number of functions into the |
1379f2c5 AM |
1689 | ;; resulting constant, `c-matchers-3'. At run time, font lock will call |
1690 | ;; each of them as a "FUNCTION" (see Elisp page "Search-based | |
1691 | ;; Fontification"). The font lock region is delimited by POINT and the | |
1692 | ;; single parameter, LIMIT. Each of these functions returns NIL (thus | |
1693 | ;; inhibiting spurious font-lock-keyword-face highlighting and another | |
1694 | ;; call). | |
1695 | ||
d9e94c22 MS |
1696 | t `(;; Initialize some things before the search functions below. |
1697 | c-font-lock-complex-decl-prepare | |
1698 | ||
d9e94c22 MS |
1699 | ,@(if (c-major-mode-is 'objc-mode) |
1700 | ;; Fontify method declarations in Objective-C, but first | |
1701 | ;; we have to put the `c-decl-end' `c-type' property on | |
1702 | ;; all the @-style directives that haven't been handled in | |
1703 | ;; `c-basic-matchers-before'. | |
1704 | `(,(c-make-font-lock-search-function | |
1705 | (c-make-keywords-re t | |
1706 | ;; Exclude "@class" since that directive ends with a | |
1707 | ;; semicolon anyway. | |
1708 | (delete "@class" | |
1709 | (append (c-lang-const c-protection-kwds) | |
1710 | (c-lang-const c-other-decl-kwds) | |
1711 | nil))) | |
1712 | '((c-put-char-property (1- (match-end 1)) | |
1713 | 'c-type 'c-decl-end))) | |
0386b551 | 1714 | c-font-lock-objc-methods)) |
d9e94c22 | 1715 | |
0386b551 | 1716 | ;; Fontify all declarations, casts and normal labels. |
d9e94c22 MS |
1717 | c-font-lock-declarations |
1718 | ||
bf2c1571 AM |
1719 | ;; Fontify declarators when POINT is within their declaration. |
1720 | c-font-lock-enclosing-decls | |
1721 | ||
0386b551 AM |
1722 | ;; Fontify angle bracket arglists like templates in C++. |
1723 | ,@(when (c-lang-const c-recognize-<>-arglists) | |
1724 | `(c-font-lock-<>-arglists)) | |
1725 | ||
5a89f0a7 | 1726 | ;; The first two rules here mostly find occurrences that |
d9e94c22 MS |
1727 | ;; `c-font-lock-declarations' has found already, but not |
1728 | ;; declarations containing blocks in the type (see note below). | |
1729 | ;; It's also useful to fontify these everywhere to show e.g. when | |
1730 | ;; a type keyword is accidentally used as an identifier. | |
1731 | ||
1732 | ;; Fontify basic types. | |
1733 | ,(let ((re (c-make-keywords-re nil | |
1734 | (c-lang-const c-primitive-type-kwds)))) | |
1735 | (if (c-major-mode-is 'pike-mode) | |
1736 | ;; No symbol is a keyword after "->" in Pike. | |
0386b551 | 1737 | `(,(concat "\\(\\=.?\\|[^>]\\|[^-]>\\)" |
d9e94c22 | 1738 | "\\<\\(" re "\\)\\>") |
0386b551 | 1739 | 2 font-lock-type-face) |
d9e94c22 MS |
1740 | `(,(concat "\\<\\(" re "\\)\\>") |
1741 | 1 'font-lock-type-face))) | |
1742 | ||
e15f8aaa | 1743 | ;; Fontify types preceded by `c-type-prefix-kwds' (e.g. "struct"). |
d9e94c22 MS |
1744 | ,@(when (c-lang-const c-type-prefix-kwds) |
1745 | `((,(byte-compile | |
1746 | `(lambda (limit) | |
1747 | (c-fontify-types-and-refs | |
1748 | ((c-promote-possible-types t) | |
1749 | ;; The font-lock package in Emacs is known to clobber | |
1750 | ;; `parse-sexp-lookup-properties' (when it exists). | |
1751 | (parse-sexp-lookup-properties | |
1752 | (cc-eval-when-compile | |
1753 | (boundp 'parse-sexp-lookup-properties)))) | |
1754 | (save-restriction | |
1755 | ;; Narrow to avoid going past the limit in | |
1756 | ;; `c-forward-type'. | |
1757 | (narrow-to-region (point) limit) | |
1758 | (while (re-search-forward | |
1759 | ,(concat "\\<\\(" | |
1760 | (c-make-keywords-re nil | |
1761 | (c-lang-const c-type-prefix-kwds)) | |
1762 | "\\)\\>") | |
1763 | limit t) | |
1764 | (unless (c-skip-comments-and-strings limit) | |
1765 | (c-forward-syntactic-ws) | |
1766 | ;; Handle prefix declaration specifiers. | |
e3715033 AM |
1767 | (when (or (looking-at c-prefix-spec-kwds-re) |
1768 | (and (c-major-mode-is 'java-mode) | |
1769 | (looking-at "@[A-Za-z0-9]+"))) | |
0386b551 | 1770 | (c-forward-keyword-clause 1)) |
d9e94c22 MS |
1771 | ,(if (c-major-mode-is 'c++-mode) |
1772 | `(when (and (c-forward-type) | |
1773 | (eq (char-after) ?=)) | |
1774 | ;; In C++ we additionally check for a "class | |
1775 | ;; X = Y" construct which is used in | |
1776 | ;; templates, to fontify Y as a type. | |
1777 | (forward-char) | |
1778 | (c-forward-syntactic-ws) | |
1779 | (c-forward-type)) | |
1780 | `(c-forward-type)) | |
1781 | ))))))))) | |
1782 | ||
1783 | ;; Fontify symbols after closing braces as declaration | |
1784 | ;; identifiers under the assumption that they are part of | |
1785 | ;; declarations like "class Foo { ... } foo;". It's too | |
1786 | ;; expensive to check this accurately by skipping past the | |
1787 | ;; brace block, so we use the heuristic that it's such a | |
1788 | ;; declaration if the first identifier is on the same line as | |
1789 | ;; the closing brace. `c-font-lock-declarations' will later | |
1790 | ;; override it if it turns out to be an new declaration, but | |
1791 | ;; it will be wrong if it's an expression (see the test | |
1792 | ;; decls-8.cc). | |
e15f8aaa AM |
1793 | ;; ,@(when (c-lang-const c-opt-block-decls-with-vars-key) |
1794 | ;; `((,(c-make-font-lock-search-function | |
1795 | ;; (concat "}" | |
1796 | ;; (c-lang-const c-single-line-syntactic-ws) | |
1797 | ;; "\\(" ; 1 + c-single-line-syntactic-ws-depth | |
1798 | ;; (c-lang-const c-type-decl-prefix-key) | |
1799 | ;; "\\|" | |
1800 | ;; (c-lang-const c-symbol-key) | |
1801 | ;; "\\)") | |
1802 | ;; `((c-font-lock-declarators limit t nil) ; That `nil' says use `font-lock-variable-name-face'; | |
1803 | ;; ; `t' would mean `font-lock-function-name-face'. | |
1804 | ;; (progn | |
1805 | ;; (c-put-char-property (match-beginning 0) 'c-type | |
1806 | ;; 'c-decl-id-start) | |
1807 | ;; ; 'c-decl-type-start) | |
1808 | ;; (goto-char (match-beginning | |
1809 | ;; ,(1+ (c-lang-const | |
1810 | ;; c-single-line-syntactic-ws-depth))))) | |
1811 | ;; (goto-char (match-end 0))))))) | |
d9e94c22 MS |
1812 | |
1813 | ;; Fontify the type in C++ "new" expressions. | |
1814 | ,@(when (c-major-mode-is 'c++-mode) | |
1379f2c5 AM |
1815 | ;; This pattern is a probably a "(MATCHER . ANCHORED-HIGHLIGHTER)" |
1816 | ;; (see Elisp page "Search-based Fontification"). | |
d9e94c22 MS |
1817 | `(("\\<new\\>" |
1818 | (c-font-lock-c++-new)))) | |
1819 | )) | |
1820 | ||
1821 | (defun c-font-lock-labels (limit) | |
0386b551 | 1822 | ;; Fontify all statement labels from the point to LIMIT. Assumes |
d9e94c22 MS |
1823 | ;; that strings and comments have been fontified already. Nil is |
1824 | ;; always returned. | |
1825 | ;; | |
0386b551 AM |
1826 | ;; Note: This function is only used on decoration level 2; this is |
1827 | ;; taken care of directly by the gargantuan | |
1828 | ;; `c-font-lock-declarations' on higher levels. | |
1829 | ;; | |
1830 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
1831 | |
1832 | (let (continue-pos id-start | |
1833 | ;; The font-lock package in Emacs is known to clobber | |
1834 | ;; `parse-sexp-lookup-properties' (when it exists). | |
1835 | (parse-sexp-lookup-properties | |
1836 | (cc-eval-when-compile | |
1837 | (boundp 'parse-sexp-lookup-properties)))) | |
1838 | ||
1839 | (while (re-search-forward ":[^:]" limit t) | |
1840 | (setq continue-pos (point)) | |
1841 | (goto-char (match-beginning 0)) | |
1842 | (unless (c-skip-comments-and-strings limit) | |
1843 | ||
1844 | (c-backward-syntactic-ws) | |
1845 | (and (setq id-start (c-on-identifier)) | |
1846 | ||
1847 | (not (get-text-property id-start 'face)) | |
1848 | ||
1849 | (progn | |
1850 | (goto-char id-start) | |
1851 | (c-backward-syntactic-ws) | |
1852 | (or | |
1853 | ;; Check for a char that precedes a statement. | |
1854 | (memq (char-before) '(?\} ?\{ ?\;)) | |
1855 | ;; Check for a preceding label. We exploit the font | |
1856 | ;; locking made earlier by this function. | |
1857 | (and (eq (char-before) ?:) | |
1858 | (progn | |
1859 | (backward-char) | |
1860 | (c-backward-syntactic-ws) | |
1861 | (not (bobp))) | |
1862 | (eq (get-text-property (1- (point)) 'face) | |
1863 | c-label-face-name)) | |
1864 | ;; Check for a keyword that precedes a statement. | |
1865 | (c-after-conditional))) | |
1866 | ||
1867 | (progn | |
1868 | ;; Got a label. | |
1869 | (goto-char id-start) | |
1870 | (looking-at c-symbol-key) | |
1871 | (c-put-font-lock-face (match-beginning 0) (match-end 0) | |
1872 | c-label-face-name))) | |
1873 | ||
1874 | (goto-char continue-pos)))) | |
1875 | nil) | |
1876 | ||
1877 | (c-lang-defconst c-basic-matchers-after | |
1878 | "Font lock matchers for various things that should be fontified after | |
1879 | generic casts and declarations are fontified. Used on level 2 and | |
1880 | higher." | |
1881 | ||
4f9e41e4 AM |
1882 | t `(,@(when (c-lang-const c-brace-id-list-kwds) |
1883 | ;; Fontify the remaining identifiers inside an enum list when we start | |
1884 | ;; inside it. | |
1885 | `(c-font-lock-enum-tail | |
1886 | ;; Fontify the identifiers inside enum lists. (The enum type | |
d9e94c22 MS |
1887 | ;; name is handled by `c-simple-decl-matchers' or |
1888 | ;; `c-complex-decl-matchers' below. | |
4f9e41e4 | 1889 | (,(c-make-font-lock-search-function |
d9e94c22 MS |
1890 | (concat |
1891 | "\\<\\(" | |
1892 | (c-make-keywords-re nil (c-lang-const c-brace-id-list-kwds)) | |
1893 | "\\)\\>" | |
1894 | ;; Disallow various common punctuation chars that can't come | |
1895 | ;; before the '{' of the enum list, to avoid searching too far. | |
1896 | "[^\]\[{}();,/#=]*" | |
1897 | "{") | |
1898 | '((c-font-lock-declarators limit t nil) | |
1899 | (save-match-data | |
1900 | (goto-char (match-end 0)) | |
1901 | (c-put-char-property (1- (point)) 'c-type | |
1902 | 'c-decl-id-start) | |
1903 | (c-forward-syntactic-ws)) | |
1904 | (goto-char (match-end 0))))))) | |
1905 | ||
0386b551 AM |
1906 | ;; Fontify labels after goto etc. |
1907 | ,@(when (c-lang-const c-before-label-kwds) | |
1908 | `(;; (Got three different interpretation levels here, | |
d9e94c22 MS |
1909 | ;; which makes it a bit complicated: 1) The backquote |
1910 | ;; stuff is expanded when compiled or loaded, 2) the | |
1911 | ;; eval form is evaluated at font-lock setup (to | |
1912 | ;; substitute c-label-face-name correctly), and 3) the | |
1913 | ;; resulting structure is interpreted during | |
1914 | ;; fontification.) | |
1915 | (eval | |
1916 | . ,(let* ((c-before-label-re | |
1917 | (c-make-keywords-re nil | |
1918 | (c-lang-const c-before-label-kwds)))) | |
1919 | `(list | |
1920 | ,(concat "\\<\\(" c-before-label-re "\\)\\>" | |
1921 | "\\s *" | |
1922 | "\\(" ; identifier-offset | |
1923 | (c-lang-const c-symbol-key) | |
1924 | "\\)") | |
0386b551 AM |
1925 | (list ,(+ (regexp-opt-depth c-before-label-re) 2) |
1926 | c-label-face-name nil t)))))) | |
d9e94c22 MS |
1927 | |
1928 | ;; Fontify the clauses after various keywords. | |
ef8cdf8c AM |
1929 | ,@(when (or (c-lang-const c-type-list-kwds) |
1930 | (c-lang-const c-ref-list-kwds) | |
1931 | (c-lang-const c-colon-type-list-kwds)) | |
1932 | `((,(c-make-font-lock-BO-decl-search-function | |
1933 | (concat "\\<\\(" | |
1934 | (c-make-keywords-re nil | |
1935 | (append (c-lang-const c-type-list-kwds) | |
1936 | (c-lang-const c-ref-list-kwds) | |
1937 | (c-lang-const c-colon-type-list-kwds))) | |
1938 | "\\)\\>") | |
1939 | '((c-fontify-types-and-refs ((c-promote-possible-types t)) | |
1940 | (c-forward-keyword-clause 1) | |
1941 | (if (> (point) limit) (goto-char limit)))))))) | |
1942 | ||
1943 | ,@(when (c-lang-const c-paren-type-kwds) | |
1944 | `((,(c-make-font-lock-search-function | |
1945 | (concat "\\<\\(" | |
1946 | (c-make-keywords-re nil | |
1947 | (c-lang-const c-paren-type-kwds)) | |
1948 | "\\)\\>") | |
1949 | '((c-fontify-types-and-refs ((c-promote-possible-types t)) | |
1950 | (c-forward-keyword-clause 1) | |
1951 | (if (> (point) limit) (goto-char limit)))))))) | |
1952 | ||
1953 | ,@(when (c-major-mode-is 'java-mode) | |
1954 | `((eval . (list "\\<\\(@[a-zA-Z0-9]+\\)\\>" 1 c-annotation-face)))) | |
d9e94c22 MS |
1955 | )) |
1956 | ||
1957 | (c-lang-defconst c-matchers-1 | |
1958 | t (c-lang-const c-cpp-matchers)) | |
1959 | ||
1960 | (c-lang-defconst c-matchers-2 | |
1961 | t (append (c-lang-const c-matchers-1) | |
1962 | (c-lang-const c-basic-matchers-before) | |
1963 | (c-lang-const c-simple-decl-matchers) | |
1964 | (c-lang-const c-basic-matchers-after))) | |
1965 | ||
1966 | (c-lang-defconst c-matchers-3 | |
1967 | t (append (c-lang-const c-matchers-1) | |
1968 | (c-lang-const c-basic-matchers-before) | |
1969 | (c-lang-const c-complex-decl-matchers) | |
1970 | (c-lang-const c-basic-matchers-after))) | |
1971 | ||
1972 | (defun c-compose-keywords-list (base-list) | |
1973 | ;; Incorporate the font lock keyword lists according to | |
1974 | ;; `c-doc-comment-style' on the given keyword list and return it. | |
1975 | ;; This is used in the function bindings of the | |
1976 | ;; `*-font-lock-keywords-*' symbols since we have to build the list | |
1977 | ;; when font-lock is initialized. | |
1978 | ||
1979 | (unless (memq c-doc-face-name c-literal-faces) | |
1980 | (setq c-literal-faces (cons c-doc-face-name c-literal-faces))) | |
1981 | ||
1982 | (let* ((doc-keywords | |
1983 | (if (consp (car-safe c-doc-comment-style)) | |
1984 | (cdr-safe (or (assq c-buffer-is-cc-mode c-doc-comment-style) | |
1985 | (assq 'other c-doc-comment-style))) | |
1986 | c-doc-comment-style)) | |
1987 | (list (nconc (apply 'nconc | |
1988 | (mapcar | |
1989 | (lambda (doc-style) | |
1990 | (let ((sym (intern | |
1991 | (concat (symbol-name doc-style) | |
1992 | "-font-lock-keywords")))) | |
1993 | (cond ((fboundp sym) | |
1994 | (funcall sym)) | |
1995 | ((boundp sym) | |
1996 | (append (eval sym) nil))))) | |
1997 | (if (listp doc-keywords) | |
1998 | doc-keywords | |
1999 | (list doc-keywords)))) | |
2000 | base-list))) | |
2001 | ||
2002 | ;; Kludge: If `c-font-lock-complex-decl-prepare' is on the list we | |
2003 | ;; move it first since the doc comment font lockers might add | |
7bfc3fdb | 2004 | ;; `c-type' text properties, so they have to be cleared before that. |
d9e94c22 MS |
2005 | (when (memq 'c-font-lock-complex-decl-prepare list) |
2006 | (setq list (cons 'c-font-lock-complex-decl-prepare | |
2007 | (delq 'c-font-lock-complex-decl-prepare | |
2008 | (append list nil))))) | |
2009 | ||
2010 | list)) | |
2011 | ||
2012 | (defun c-override-default-keywords (def-var) | |
2013 | ;; This is used to override the value on a `*-font-lock-keywords' | |
2014 | ;; variable only if it's nil or has the same value as one of the | |
2015 | ;; `*-font-lock-keywords-*' variables. Older font-lock packages | |
2016 | ;; define a default value for `*-font-lock-keywords' which we want | |
2017 | ;; to override, but we should otoh avoid clobbering a user setting. | |
2018 | ;; This heuristic for that isn't perfect, but I can't think of any | |
2019 | ;; better. /mast | |
d9e94c22 MS |
2020 | (when (and (boundp def-var) |
2021 | (memq (symbol-value def-var) | |
2022 | (cons nil | |
2023 | (mapcar | |
2024 | (lambda (suffix) | |
2025 | (let ((sym (intern (concat (symbol-name def-var) | |
2026 | suffix)))) | |
2027 | (and (boundp sym) (symbol-value sym)))) | |
2028 | '("-1" "-2" "-3"))))) | |
2029 | ;; The overriding is done by unbinding the variable so that the normal | |
2030 | ;; defvar will install its default value later on. | |
2031 | (makunbound def-var))) | |
2032 | ||
2033 | \f | |
2034 | ;;; C. | |
2035 | ||
2036 | (c-override-default-keywords 'c-font-lock-keywords) | |
2037 | ||
2038 | (defconst c-font-lock-keywords-1 (c-lang-const c-matchers-1 c) | |
2039 | "Minimal font locking for C mode. | |
2040 | Fontifies only preprocessor directives (in addition to the syntactic | |
2041 | fontification of strings and comments).") | |
2042 | ||
2043 | (defconst c-font-lock-keywords-2 (c-lang-const c-matchers-2 c) | |
2044 | "Fast normal font locking for C mode. | |
2045 | In addition to `c-font-lock-keywords-1', this adds fontification of | |
2046 | keywords, simple types, declarations that are easy to recognize, the | |
2047 | user defined types on `c-font-lock-extra-types', and the doc comment | |
2048 | styles specified by `c-doc-comment-style'.") | |
2049 | ||
2050 | (defconst c-font-lock-keywords-3 (c-lang-const c-matchers-3 c) | |
2051 | "Accurate normal font locking for C mode. | |
9fc9a531 | 2052 | Like the variable `c-font-lock-keywords-2' but detects declarations in a more |
d9e94c22 MS |
2053 | accurate way that works in most cases for arbitrary types without the |
2054 | need for `c-font-lock-extra-types'.") | |
2055 | ||
2056 | (defvar c-font-lock-keywords c-font-lock-keywords-3 | |
2057 | "Default expressions to highlight in C mode.") | |
2058 | ||
2059 | (defun c-font-lock-keywords-2 () | |
2060 | (c-compose-keywords-list c-font-lock-keywords-2)) | |
2061 | (defun c-font-lock-keywords-3 () | |
2062 | (c-compose-keywords-list c-font-lock-keywords-3)) | |
2063 | (defun c-font-lock-keywords () | |
2064 | (c-compose-keywords-list c-font-lock-keywords)) | |
2065 | ||
2066 | \f | |
2067 | ;;; C++. | |
2068 | ||
2069 | (defun c-font-lock-c++-new (limit) | |
e15f8aaa AM |
2070 | ;; FIXME!!! Put in a comment about the context of this function's |
2071 | ;; invocation. I think it's called as an ANCHORED-MATCHER within an | |
2072 | ;; ANCHORED-HIGHLIGHTER. (2007/2/10). | |
2073 | ;; | |
d9e94c22 MS |
2074 | ;; Assuming point is after a "new" word, check that it isn't inside |
2075 | ;; a string or comment, and if so try to fontify the type in the | |
2076 | ;; allocation expression. Nil is always returned. | |
2077 | ;; | |
2078 | ;; As usual, C++ takes the prize in coming up with a hard to parse | |
2079 | ;; syntax. :P | |
0386b551 AM |
2080 | ;; |
2081 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
2082 | |
2083 | (unless (c-skip-comments-and-strings limit) | |
2084 | (save-excursion | |
2085 | (catch 'false-alarm | |
2086 | ;; A "new" keyword is followed by one to three expressions, where | |
2087 | ;; the type is the middle one, and the only required part. | |
2088 | (let (expr1-pos expr2-pos | |
2089 | ;; Enable recording of identifier ranges in `c-forward-type' | |
2090 | ;; etc for later fontification. Not using | |
2091 | ;; `c-fontify-types-and-refs' here since the ranges should | |
2092 | ;; be fontified selectively only when an allocation | |
2093 | ;; expression is successfully recognized. | |
2094 | (c-record-type-identifiers t) | |
2095 | c-record-ref-identifiers | |
2096 | ;; The font-lock package in Emacs is known to clobber | |
2097 | ;; `parse-sexp-lookup-properties' (when it exists). | |
2098 | (parse-sexp-lookup-properties | |
2099 | (cc-eval-when-compile | |
2100 | (boundp 'parse-sexp-lookup-properties)))) | |
2101 | (c-forward-syntactic-ws) | |
2102 | ||
2103 | ;; The first placement arglist is always parenthesized, if it | |
2104 | ;; exists. | |
2105 | (when (eq (char-after) ?\() | |
2106 | (setq expr1-pos (1+ (point))) | |
2107 | (condition-case nil | |
2108 | (c-forward-sexp) | |
2109 | (scan-error (throw 'false-alarm t))) | |
2110 | (c-forward-syntactic-ws)) | |
2111 | ||
2112 | ;; The second expression is either a type followed by some "*" or | |
2113 | ;; "[...]" or similar, or a parenthesized type followed by a full | |
2114 | ;; identifierless declarator. | |
2115 | (setq expr2-pos (1+ (point))) | |
2116 | (cond ((eq (char-after) ?\()) | |
2117 | ((let ((c-promote-possible-types t)) | |
2118 | (c-forward-type))) | |
2119 | (t (setq expr2-pos nil))) | |
2120 | ||
2121 | (when expr1-pos | |
2122 | (cond | |
2123 | ((not expr2-pos) | |
2124 | ;; No second expression, so the first has to be a | |
2125 | ;; parenthesized type. | |
2126 | (goto-char expr1-pos) | |
2127 | (let ((c-promote-possible-types t)) | |
2128 | (c-forward-type))) | |
2129 | ||
2130 | ((eq (char-before expr2-pos) ?\() | |
2131 | ;; Got two parenthesized expressions, so we have to look | |
2132 | ;; closer at them to decide which is the type. No need to | |
2133 | ;; handle `c-record-ref-identifiers' since all references | |
2134 | ;; has already been handled by other fontification rules. | |
2135 | (let (expr1-res expr2-res) | |
2136 | ||
2137 | (goto-char expr1-pos) | |
2138 | (when (setq expr1-res (c-forward-type)) | |
2139 | (unless (looking-at | |
2140 | (cc-eval-when-compile | |
2141 | (concat (c-lang-const c-symbol-start c++) | |
2142 | "\\|[*:\)\[]"))) | |
2143 | ;; There's something after the would-be type that | |
2144 | ;; can't be there, so this is a placement arglist. | |
2145 | (setq expr1-res nil))) | |
2146 | ||
2147 | (goto-char expr2-pos) | |
2148 | (when (setq expr2-res (c-forward-type)) | |
2149 | (unless (looking-at | |
2150 | (cc-eval-when-compile | |
2151 | (concat (c-lang-const c-symbol-start c++) | |
2152 | "\\|[*:\)\[]"))) | |
2153 | ;; There's something after the would-be type that can't | |
2154 | ;; be there, so this is an initialization expression. | |
2155 | (setq expr2-res nil)) | |
2156 | (when (and (c-go-up-list-forward) | |
2157 | (progn (c-forward-syntactic-ws) | |
2158 | (eq (char-after) ?\())) | |
2159 | ;; If there's a third initialization expression | |
2160 | ;; then the second one is the type, so demote the | |
2161 | ;; first match. | |
2162 | (setq expr1-res nil))) | |
2163 | ||
2164 | ;; We fontify the most likely type, with a preference for | |
2165 | ;; the first argument since a placement arglist is more | |
2166 | ;; unusual than an initializer. | |
2167 | (cond ((memq expr1-res '(t known prefix))) | |
2168 | ((memq expr2-res '(t known prefix))) | |
2169 | ((eq expr1-res 'found) | |
2170 | (let ((c-promote-possible-types t)) | |
2171 | (goto-char expr1-pos) | |
2172 | (c-forward-type))) | |
2173 | ((eq expr2-res 'found) | |
2174 | (let ((c-promote-possible-types t)) | |
2175 | (goto-char expr2-pos) | |
2176 | (c-forward-type))) | |
2177 | ((and (eq expr1-res 'maybe) (not expr2-res)) | |
2178 | (let ((c-promote-possible-types t)) | |
2179 | (goto-char expr1-pos) | |
2180 | (c-forward-type))) | |
2181 | ((and (not expr1-res) (eq expr2-res 'maybe)) | |
2182 | (let ((c-promote-possible-types t)) | |
2183 | (goto-char expr2-pos) | |
2184 | (c-forward-type))) | |
2185 | ;; If both type matches are 'maybe then we're | |
2186 | ;; too uncertain to promote either of them. | |
2187 | ))))) | |
2188 | ||
2189 | ;; Fontify the type that now is recorded in | |
2190 | ;; `c-record-type-identifiers', if any. | |
2191 | (c-fontify-recorded-types-and-refs))))) | |
2192 | nil) | |
2193 | ||
2194 | (c-override-default-keywords 'c++-font-lock-keywords) | |
2195 | ||
2196 | (defconst c++-font-lock-keywords-1 (c-lang-const c-matchers-1 c++) | |
2197 | "Minimal font locking for C++ mode. | |
2198 | Fontifies only preprocessor directives (in addition to the syntactic | |
2199 | fontification of strings and comments).") | |
2200 | ||
2201 | (defconst c++-font-lock-keywords-2 (c-lang-const c-matchers-2 c++) | |
2202 | "Fast normal font locking for C++ mode. | |
2203 | In addition to `c++-font-lock-keywords-1', this adds fontification of | |
2204 | keywords, simple types, declarations that are easy to recognize, the | |
2205 | user defined types on `c++-font-lock-extra-types', and the doc comment | |
2206 | styles specified by `c-doc-comment-style'.") | |
2207 | ||
2208 | (defconst c++-font-lock-keywords-3 (c-lang-const c-matchers-3 c++) | |
2209 | "Accurate normal font locking for C++ mode. | |
9fc9a531 | 2210 | Like the variable `c++-font-lock-keywords-2' but detects declarations in a more |
d9e94c22 MS |
2211 | accurate way that works in most cases for arbitrary types without the |
2212 | need for `c++-font-lock-extra-types'.") | |
2213 | ||
2214 | (defvar c++-font-lock-keywords c++-font-lock-keywords-3 | |
2215 | "Default expressions to highlight in C++ mode.") | |
2216 | ||
2217 | (defun c++-font-lock-keywords-2 () | |
2218 | (c-compose-keywords-list c++-font-lock-keywords-2)) | |
2219 | (defun c++-font-lock-keywords-3 () | |
2220 | (c-compose-keywords-list c++-font-lock-keywords-3)) | |
2221 | (defun c++-font-lock-keywords () | |
2222 | (c-compose-keywords-list c++-font-lock-keywords)) | |
2223 | ||
2224 | \f | |
2225 | ;;; Objective-C. | |
2226 | ||
d9e94c22 MS |
2227 | (defun c-font-lock-objc-method () |
2228 | ;; Assuming the point is after the + or - that starts an Objective-C | |
2229 | ;; method declaration, fontify it. This must be done before normal | |
2230 | ;; casts, declarations and labels are fontified since they will get | |
2231 | ;; false matches in these things. | |
0386b551 AM |
2232 | ;; |
2233 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
2234 | |
2235 | (c-fontify-types-and-refs | |
2236 | ((first t) | |
2237 | (c-promote-possible-types t)) | |
2238 | ||
2239 | (while (and | |
2240 | (progn | |
2241 | (c-forward-syntactic-ws) | |
2242 | ||
2243 | ;; An optional method type. | |
2244 | (if (eq (char-after) ?\() | |
2245 | (progn | |
2246 | (forward-char) | |
2247 | (c-forward-syntactic-ws) | |
2248 | (c-forward-type) | |
2249 | (prog1 (c-go-up-list-forward) | |
2250 | (c-forward-syntactic-ws))) | |
2251 | t)) | |
2252 | ||
2253 | ;; The name. The first time it's the first part of | |
2254 | ;; the function name, the rest of the time it's an | |
2255 | ;; argument name. | |
2256 | (looking-at c-symbol-key) | |
2257 | (progn | |
2258 | (goto-char (match-end 0)) | |
2259 | (c-put-font-lock-face (match-beginning 0) | |
2260 | (point) | |
2261 | (if first | |
2262 | 'font-lock-function-name-face | |
2263 | 'font-lock-variable-name-face)) | |
2264 | (c-forward-syntactic-ws) | |
2265 | ||
2266 | ;; Another optional part of the function name. | |
2267 | (when (looking-at c-symbol-key) | |
2268 | (goto-char (match-end 0)) | |
2269 | (c-put-font-lock-face (match-beginning 0) | |
2270 | (point) | |
2271 | 'font-lock-function-name-face) | |
2272 | (c-forward-syntactic-ws)) | |
2273 | ||
2274 | ;; There's another argument if a colon follows. | |
2275 | (eq (char-after) ?:))) | |
2276 | (forward-char) | |
2277 | (setq first nil)))) | |
2278 | ||
2279 | (defun c-font-lock-objc-methods (limit) | |
2280 | ;; Fontify method declarations in Objective-C. Nil is always | |
2281 | ;; returned. | |
0386b551 AM |
2282 | ;; |
2283 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
2284 | |
2285 | (let (;; The font-lock package in Emacs is known to clobber | |
2286 | ;; `parse-sexp-lookup-properties' (when it exists). | |
2287 | (parse-sexp-lookup-properties | |
2288 | (cc-eval-when-compile | |
2289 | (boundp 'parse-sexp-lookup-properties)))) | |
2290 | ||
2291 | (c-find-decl-spots | |
2292 | limit | |
2293 | "[-+]" | |
2294 | nil | |
2295 | (lambda (match-pos inside-macro) | |
2296 | (forward-char) | |
2297 | (c-font-lock-objc-method)))) | |
2298 | nil) | |
2299 | ||
2300 | (c-override-default-keywords 'objc-font-lock-keywords) | |
2301 | ||
2302 | (defconst objc-font-lock-keywords-1 (c-lang-const c-matchers-1 objc) | |
2303 | "Minimal font locking for Objective-C mode. | |
2304 | Fontifies only compiler directives (in addition to the syntactic | |
2305 | fontification of strings and comments).") | |
2306 | ||
2307 | (defconst objc-font-lock-keywords-2 (c-lang-const c-matchers-2 objc) | |
2308 | "Fast normal font locking for Objective-C mode. | |
2309 | In addition to `objc-font-lock-keywords-1', this adds fontification of | |
2310 | keywords, simple types, declarations that are easy to recognize, the | |
2311 | user defined types on `objc-font-lock-extra-types', and the doc | |
2312 | comment styles specified by `c-doc-comment-style'.") | |
2313 | ||
2314 | (defconst objc-font-lock-keywords-3 (c-lang-const c-matchers-3 objc) | |
2315 | "Accurate normal font locking for Objective-C mode. | |
9fc9a531 | 2316 | Like the variable `objc-font-lock-keywords-2' but detects declarations in a more |
d9e94c22 MS |
2317 | accurate way that works in most cases for arbitrary types without the |
2318 | need for `objc-font-lock-extra-types'.") | |
2319 | ||
2320 | (defvar objc-font-lock-keywords objc-font-lock-keywords-3 | |
2321 | "Default expressions to highlight in Objective-C mode.") | |
2322 | ||
2323 | (defun objc-font-lock-keywords-2 () | |
2324 | (c-compose-keywords-list objc-font-lock-keywords-2)) | |
2325 | (defun objc-font-lock-keywords-3 () | |
2326 | (c-compose-keywords-list objc-font-lock-keywords-3)) | |
2327 | (defun objc-font-lock-keywords () | |
2328 | (c-compose-keywords-list objc-font-lock-keywords)) | |
2329 | ||
2330 | ;; Kludge to override the default value that | |
2331 | ;; `objc-font-lock-extra-types' might have gotten from the font-lock | |
2332 | ;; package. The value replaced here isn't relevant now anyway since | |
2333 | ;; those types are builtin and therefore listed directly in | |
2334 | ;; `c-primitive-type-kwds'. | |
2335 | (when (equal (sort (append objc-font-lock-extra-types nil) 'string-lessp) | |
2336 | '("BOOL" "Class" "IMP" "SEL")) | |
2337 | (setq objc-font-lock-extra-types | |
2338 | (cc-eval-when-compile (list (concat "[" c-upper "]\\sw*"))))) | |
2339 | ||
2340 | \f | |
2341 | ;;; Java. | |
2342 | ||
2343 | (c-override-default-keywords 'java-font-lock-keywords) | |
2344 | ||
2345 | (defconst java-font-lock-keywords-1 (c-lang-const c-matchers-1 java) | |
2346 | "Minimal font locking for Java mode. | |
2347 | Fontifies nothing except the syntactic fontification of strings and | |
2348 | comments.") | |
2349 | ||
2350 | (defconst java-font-lock-keywords-2 (c-lang-const c-matchers-2 java) | |
2351 | "Fast normal font locking for Java mode. | |
2352 | In addition to `java-font-lock-keywords-1', this adds fontification of | |
2353 | keywords, simple types, declarations that are easy to recognize, the | |
2354 | user defined types on `java-font-lock-extra-types', and the doc | |
2355 | comment styles specified by `c-doc-comment-style'.") | |
2356 | ||
2357 | (defconst java-font-lock-keywords-3 (c-lang-const c-matchers-3 java) | |
2358 | "Accurate normal font locking for Java mode. | |
9fc9a531 | 2359 | Like variable `java-font-lock-keywords-2' but detects declarations in a more |
d9e94c22 MS |
2360 | accurate way that works in most cases for arbitrary types without the |
2361 | need for `java-font-lock-extra-types'.") | |
2362 | ||
2363 | (defvar java-font-lock-keywords java-font-lock-keywords-3 | |
2364 | "Default expressions to highlight in Java mode.") | |
2365 | ||
2366 | (defun java-font-lock-keywords-2 () | |
2367 | (c-compose-keywords-list java-font-lock-keywords-2)) | |
2368 | (defun java-font-lock-keywords-3 () | |
2369 | (c-compose-keywords-list java-font-lock-keywords-3)) | |
2370 | (defun java-font-lock-keywords () | |
2371 | (c-compose-keywords-list java-font-lock-keywords)) | |
2372 | ||
2373 | \f | |
2374 | ;;; CORBA IDL. | |
2375 | ||
2376 | (c-override-default-keywords 'idl-font-lock-keywords) | |
2377 | ||
2378 | (defconst idl-font-lock-keywords-1 (c-lang-const c-matchers-1 idl) | |
2379 | "Minimal font locking for CORBA IDL mode. | |
2380 | Fontifies nothing except the syntactic fontification of strings and | |
2381 | comments.") | |
2382 | ||
2383 | (defconst idl-font-lock-keywords-2 (c-lang-const c-matchers-2 idl) | |
2384 | "Fast normal font locking for CORBA IDL mode. | |
2385 | In addition to `idl-font-lock-keywords-1', this adds fontification of | |
2386 | keywords, simple types, declarations that are easy to recognize, the | |
2387 | user defined types on `idl-font-lock-extra-types', and the doc comment | |
2388 | styles specified by `c-doc-comment-style'.") | |
2389 | ||
2390 | (defconst idl-font-lock-keywords-3 (c-lang-const c-matchers-3 idl) | |
2391 | "Accurate normal font locking for CORBA IDL mode. | |
9fc9a531 | 2392 | Like the variable `idl-font-lock-keywords-2' but detects declarations in a more |
d9e94c22 MS |
2393 | accurate way that works in most cases for arbitrary types without the |
2394 | need for `idl-font-lock-extra-types'.") | |
2395 | ||
2396 | (defvar idl-font-lock-keywords idl-font-lock-keywords-3 | |
2397 | "Default expressions to highlight in CORBA IDL mode.") | |
2398 | ||
2399 | (defun idl-font-lock-keywords-2 () | |
2400 | (c-compose-keywords-list idl-font-lock-keywords-2)) | |
2401 | (defun idl-font-lock-keywords-3 () | |
2402 | (c-compose-keywords-list idl-font-lock-keywords-3)) | |
2403 | (defun idl-font-lock-keywords () | |
2404 | (c-compose-keywords-list idl-font-lock-keywords)) | |
2405 | ||
2406 | \f | |
2407 | ;;; Pike. | |
2408 | ||
2409 | (c-override-default-keywords 'pike-font-lock-keywords) | |
2410 | ||
2411 | (defconst pike-font-lock-keywords-1 (c-lang-const c-matchers-1 pike) | |
2412 | "Minimal font locking for Pike mode. | |
2413 | Fontifies only preprocessor directives (in addition to the syntactic | |
2414 | fontification of strings and comments).") | |
2415 | ||
2416 | (defconst pike-font-lock-keywords-2 (c-lang-const c-matchers-2 pike) | |
2417 | "Fast normal font locking for Pike mode. | |
2418 | In addition to `pike-font-lock-keywords-1', this adds fontification of | |
2419 | keywords, simple types, declarations that are easy to recognize, the | |
2420 | user defined types on `pike-font-lock-extra-types', and the doc | |
2421 | comment styles specified by `c-doc-comment-style'.") | |
2422 | ||
2423 | (defconst pike-font-lock-keywords-3 (c-lang-const c-matchers-3 pike) | |
2424 | "Accurate normal font locking for Pike mode. | |
9fc9a531 | 2425 | Like the variable `pike-font-lock-keywords-2' but detects declarations in a more |
d9e94c22 MS |
2426 | accurate way that works in most cases for arbitrary types without the |
2427 | need for `pike-font-lock-extra-types'.") | |
2428 | ||
2429 | (defvar pike-font-lock-keywords pike-font-lock-keywords-3 | |
2430 | "Default expressions to highlight in Pike mode.") | |
2431 | ||
2432 | (defun pike-font-lock-keywords-2 () | |
2433 | (c-compose-keywords-list pike-font-lock-keywords-2)) | |
2434 | (defun pike-font-lock-keywords-3 () | |
2435 | (c-compose-keywords-list pike-font-lock-keywords-3)) | |
2436 | (defun pike-font-lock-keywords () | |
2437 | (c-compose-keywords-list pike-font-lock-keywords)) | |
2438 | ||
2439 | \f | |
2440 | ;;; Doc comments. | |
2441 | ||
2442 | (defun c-font-lock-doc-comments (prefix limit keywords) | |
2443 | ;; Fontify the comments between the point and LIMIT whose start | |
2444 | ;; matches PREFIX with `c-doc-face-name'. Assumes comments have been | |
2445 | ;; fontified with `font-lock-comment-face' already. nil is always | |
2446 | ;; returned. | |
2447 | ;; | |
2448 | ;; After the fontification of a matching comment, fontification | |
2449 | ;; according to KEYWORDS is applied inside it. It's a list like | |
2450 | ;; `font-lock-keywords' except that anchored matches and eval | |
2451 | ;; clauses aren't supported and that some abbreviated forms can't be | |
2452 | ;; used. The buffer is narrowed to the comment while KEYWORDS is | |
2453 | ;; applied; leading comment starters are included but trailing | |
2454 | ;; comment enders for block comment are not. | |
2455 | ;; | |
2456 | ;; Note that faces added through KEYWORDS should never replace the | |
2457 | ;; existing `c-doc-face-name' face since the existence of that face | |
2458 | ;; is used as a flag in other code to skip comments. | |
0386b551 AM |
2459 | ;; |
2460 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
2461 | |
2462 | (let (comment-beg region-beg) | |
2463 | (if (eq (get-text-property (point) 'face) | |
2464 | 'font-lock-comment-face) | |
2465 | ;; Handle the case when the fontified region starts inside a | |
2466 | ;; comment. | |
2467 | (let ((range (c-literal-limits))) | |
2468 | (setq region-beg (point)) | |
2469 | (when range | |
2470 | (goto-char (car range))) | |
2471 | (when (looking-at prefix) | |
2472 | (setq comment-beg (point))))) | |
2473 | ||
2474 | (while (or | |
2475 | comment-beg | |
2476 | ||
2477 | ;; Search for the prefix until a match is found at the start | |
2478 | ;; of a comment. | |
2479 | (while (when (re-search-forward prefix limit t) | |
2480 | (setq comment-beg (match-beginning 0)) | |
2481 | (or (not (c-got-face-at comment-beg | |
2482 | c-literal-faces)) | |
2483 | (and (/= comment-beg (point-min)) | |
2484 | (c-got-face-at (1- comment-beg) | |
2485 | c-literal-faces)))) | |
2486 | (setq comment-beg nil)) | |
2487 | (setq region-beg comment-beg)) | |
2488 | ||
2489 | (if (eq (elt (parse-partial-sexp comment-beg (+ comment-beg 2)) 7) t) | |
2490 | ;; Collect a sequence of doc style line comments. | |
2491 | (progn | |
2492 | (goto-char comment-beg) | |
2493 | (while (and (progn | |
2494 | (c-forward-single-comment) | |
2495 | (skip-syntax-forward " ") | |
2496 | (< (point) limit)) | |
2497 | (looking-at prefix)))) | |
2498 | (goto-char comment-beg) | |
2499 | (c-forward-single-comment)) | |
2500 | (if (> (point) limit) (goto-char limit)) | |
2501 | (setq comment-beg nil) | |
2502 | ||
2503 | (let ((region-end (point)) | |
2504 | (keylist keywords) keyword matcher highlights) | |
2505 | (c-put-font-lock-face region-beg region-end c-doc-face-name) | |
2506 | (save-restriction | |
2507 | ;; Narrow to the doc comment. Among other things, this | |
2508 | ;; helps by making "^" match at the start of the comment. | |
2509 | ;; Do not include a trailing block comment ender, though. | |
2510 | (and (> region-end (1+ region-beg)) | |
2511 | (progn (goto-char region-end) | |
2512 | (backward-char 2) | |
2513 | (looking-at "\\*/")) | |
2514 | (setq region-end (point))) | |
2515 | (narrow-to-region region-beg region-end) | |
2516 | ||
2517 | (while keylist | |
2518 | (setq keyword (car keylist) | |
2519 | keylist (cdr keylist) | |
2520 | matcher (car keyword)) | |
2521 | (goto-char region-beg) | |
2522 | (while (if (stringp matcher) | |
2523 | (re-search-forward matcher region-end t) | |
2524 | (funcall matcher region-end)) | |
2525 | (setq highlights (cdr keyword)) | |
2526 | (if (consp (car highlights)) | |
2527 | (while highlights | |
2528 | (font-lock-apply-highlight (car highlights)) | |
2529 | (setq highlights (cdr highlights))) | |
2530 | (font-lock-apply-highlight highlights)))) | |
2531 | ||
2532 | (goto-char region-end))))) | |
2533 | nil) | |
2534 | (put 'c-font-lock-doc-comments 'lisp-indent-function 2) | |
2535 | ||
2536 | (defun c-find-invalid-doc-markup (regexp limit) | |
2537 | ;; Used to fontify invalid markup in doc comments after the correct | |
5a89f0a7 | 2538 | ;; ones have been fontified: Find the first occurrence of REGEXP |
d9e94c22 MS |
2539 | ;; between the point and LIMIT that only is fontified with |
2540 | ;; `c-doc-face-name'. If a match is found then submatch 0 surrounds | |
2541 | ;; the first char and t is returned, otherwise nil is returned. | |
0386b551 AM |
2542 | ;; |
2543 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
2544 | (let (start) |
2545 | (while (if (re-search-forward regexp limit t) | |
2546 | (not (eq (get-text-property | |
2547 | (setq start (match-beginning 0)) 'face) | |
2548 | c-doc-face-name)) | |
2549 | (setq start nil))) | |
2550 | (when start | |
2551 | (store-match-data (list (copy-marker start) | |
2552 | (copy-marker (1+ start)))) | |
2553 | t))) | |
2554 | ||
0386b551 AM |
2555 | ;; GtkDoc patterns contributed by Masatake YAMATO <jet@gyve.org>. |
2556 | ||
2557 | (defconst gtkdoc-font-lock-doc-comments | |
2558 | (let ((symbol "[a-zA-Z0-9_]+") | |
2559 | (header "^ \\* ")) | |
7d0ee75c | 2560 | `((,(concat header "\\(" symbol "\\):[ \t]*$") |
0386b551 AM |
2561 | 1 ,c-doc-markup-face-name prepend nil) |
2562 | (,(concat symbol "()") | |
2563 | 0 ,c-doc-markup-face-name prepend nil) | |
2564 | (,(concat header "\\(" "@" symbol "\\):") | |
2565 | 1 ,c-doc-markup-face-name prepend nil) | |
68a4a27a | 2566 | (,(concat "[#%@]" symbol) |
0386b551 AM |
2567 | 0 ,c-doc-markup-face-name prepend nil)) |
2568 | )) | |
2569 | ||
2570 | (defconst gtkdoc-font-lock-doc-protection | |
2571 | `(("< \\(public\\|private\\|protected\\) >" | |
2572 | 1 ,c-doc-markup-face-name prepend nil))) | |
2573 | ||
2574 | (defconst gtkdoc-font-lock-keywords | |
2575 | `((,(lambda (limit) | |
2576 | (c-font-lock-doc-comments "/\\*\\*$" limit | |
2577 | gtkdoc-font-lock-doc-comments) | |
2578 | (c-font-lock-doc-comments "/\\*< " limit | |
2579 | gtkdoc-font-lock-doc-protection) | |
2580 | )))) | |
2581 | ||
2582 | ;; Javadoc. | |
2583 | ||
7bfc3fdb MS |
2584 | (defconst javadoc-font-lock-doc-comments |
2585 | `(("{@[a-z]+[^}\n\r]*}" ; "{@foo ...}" markup. | |
2586 | 0 ,c-doc-markup-face-name prepend nil) | |
0386b551 AM |
2587 | ("^\\(/\\*\\)?\\(\\s \\|\\*\\)*\\(@[a-z]+\\)" ; "@foo ..." markup. |
2588 | 3 ,c-doc-markup-face-name prepend nil) | |
7bfc3fdb MS |
2589 | (,(concat "</?\\sw" ; HTML tags. |
2590 | "\\(" | |
2591 | (concat "\\sw\\|\\s \\|[=\n\r*.:]\\|" | |
2592 | "\"[^\"]*\"\\|'[^']*'") | |
2593 | "\\)*>") | |
2594 | 0 ,c-doc-markup-face-name prepend nil) | |
2595 | ("&\\(\\sw\\|[.:]\\)+;" ; HTML entities. | |
2596 | 0 ,c-doc-markup-face-name prepend nil) | |
2597 | ;; Fontify remaining markup characters as invalid. Note | |
2598 | ;; that the Javadoc spec is hazy about when "@" is | |
2599 | ;; allowed in non-markup use. | |
2600 | (,(lambda (limit) | |
2601 | (c-find-invalid-doc-markup "[<>&]\\|{@" limit)) | |
0386b551 | 2602 | 0 'font-lock-warning-face prepend nil))) |
7bfc3fdb MS |
2603 | |
2604 | (defconst javadoc-font-lock-keywords | |
2605 | `((,(lambda (limit) | |
2606 | (c-font-lock-doc-comments "/\\*\\*" limit | |
2607 | javadoc-font-lock-doc-comments))))) | |
d9e94c22 | 2608 | |
0386b551 AM |
2609 | ;; Pike autodoc. |
2610 | ||
d9e94c22 MS |
2611 | (defconst autodoc-decl-keywords |
2612 | ;; Adorned regexp matching the keywords that introduce declarations | |
2613 | ;; in Pike Autodoc. | |
2614 | (cc-eval-when-compile | |
2615 | (c-make-keywords-re t '("@decl" "@elem" "@index" "@member") 'pike-mode))) | |
2616 | ||
2617 | (defconst autodoc-decl-type-keywords | |
2618 | ;; Adorned regexp matching the keywords that are followed by a type. | |
2619 | (cc-eval-when-compile | |
2620 | (c-make-keywords-re t '("@elem" "@member") 'pike-mode))) | |
2621 | ||
2622 | (defun autodoc-font-lock-line-markup (limit) | |
2623 | ;; Fontify all line oriented keywords between the point and LIMIT. | |
2624 | ;; Nil is always returned. | |
0386b551 AM |
2625 | ;; |
2626 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
2627 | |
2628 | (let ((line-re (concat "^\\(\\(/\\*!\\|\\s *\\(" | |
2629 | c-current-comment-prefix | |
2630 | "\\)\\)\\s *\\)@[A-Za-z_-]+\\(\\s \\|$\\)")) | |
2631 | (markup-faces (list c-doc-markup-face-name c-doc-face-name))) | |
2632 | ||
2633 | (while (re-search-forward line-re limit t) | |
2634 | (goto-char (match-end 1)) | |
2635 | ||
2636 | (if (looking-at autodoc-decl-keywords) | |
2637 | (let* ((kwd-pos (point)) | |
2638 | (start (match-end 1)) | |
2639 | (pos start) | |
2640 | end) | |
2641 | ||
2642 | (c-put-font-lock-face (point) pos markup-faces) | |
2643 | ||
2644 | ;; Put a declaration end mark at the markup keyword and | |
2645 | ;; remove the faces from the rest of the line so that it | |
2646 | ;; gets refontified as a declaration later on by | |
2647 | ;; `c-font-lock-declarations'. | |
2648 | (c-put-char-property (1- pos) 'c-type 'c-decl-end) | |
2649 | (goto-char pos) | |
2650 | (while (progn | |
2651 | (end-of-line) | |
2652 | (setq end (point)) | |
2653 | (and (eq (char-before) ?@) | |
2654 | (not (eobp)) | |
2655 | (progn (forward-char) | |
0386b551 | 2656 | (skip-syntax-forward " ") |
d9e94c22 MS |
2657 | (looking-at c-current-comment-prefix)))) |
2658 | (goto-char (match-end 0)) | |
2659 | (c-remove-font-lock-face pos (1- end)) | |
2660 | (c-put-font-lock-face (1- end) end markup-faces) | |
2661 | (setq pos (point))) | |
2662 | ||
2663 | ;; Include the final newline in the removed area. This | |
2664 | ;; has no visual effect but it avoids some tricky special | |
2665 | ;; cases in the testsuite wrt the differences in string | |
2666 | ;; fontification in Emacs vs XEmacs. | |
2667 | (c-remove-font-lock-face pos (min (1+ (point)) (point-max))) | |
2668 | ||
2669 | ;; Must handle string literals explicitly inside the declaration. | |
2670 | (goto-char start) | |
2671 | (while (re-search-forward | |
2672 | "\"\\([^\\\"]\\|\\\\.\\)*\"\\|'\\([^\\']\\|\\\\.\\)*'" | |
2673 | end 'move) | |
2674 | (c-put-font-lock-string-face (match-beginning 0) | |
2675 | (point))) | |
2676 | ||
2677 | ;; Fontify types after keywords that always are followed | |
2678 | ;; by them. | |
2679 | (goto-char kwd-pos) | |
2680 | (when (looking-at autodoc-decl-type-keywords) | |
2681 | (c-fontify-types-and-refs ((c-promote-possible-types t)) | |
2682 | (goto-char start) | |
2683 | (c-forward-syntactic-ws) | |
2684 | (c-forward-type)))) | |
2685 | ||
2686 | ;; Mark each whole line as markup, as long as the logical line | |
2687 | ;; continues. | |
2688 | (while (progn | |
2689 | (c-put-font-lock-face (point) | |
2690 | (progn (end-of-line) (point)) | |
2691 | markup-faces) | |
2692 | (and (eq (char-before) ?@) | |
2693 | (not (eobp)) | |
2694 | (progn (forward-char) | |
0386b551 | 2695 | (skip-syntax-forward " ") |
d9e94c22 MS |
2696 | (looking-at c-current-comment-prefix)))) |
2697 | (goto-char (match-end 0)))))) | |
2698 | ||
2699 | nil) | |
2700 | ||
7bfc3fdb MS |
2701 | (defconst autodoc-font-lock-doc-comments |
2702 | `(("@\\(\\w+{\\|\\[\\([^\]@\n\r]\\|@@\\)*\\]\\|[@}]\\|$\\)" | |
2703 | ;; In-text markup. | |
2704 | 0 ,c-doc-markup-face-name prepend nil) | |
2705 | (autodoc-font-lock-line-markup) | |
2706 | ;; Fontify remaining markup characters as invalid. | |
2707 | (,(lambda (limit) | |
2708 | (c-find-invalid-doc-markup "@" limit)) | |
0386b551 | 2709 | 0 'font-lock-warning-face prepend nil) |
7bfc3fdb MS |
2710 | )) |
2711 | ||
d9e94c22 MS |
2712 | (defun autodoc-font-lock-keywords () |
2713 | ;; Note that we depend on that `c-current-comment-prefix' has got | |
2714 | ;; its proper value here. | |
0386b551 AM |
2715 | ;; |
2716 | ;; This function might do hidden buffer changes. | |
d9e94c22 MS |
2717 | |
2718 | ;; The `c-type' text property with `c-decl-end' is used to mark the | |
2719 | ;; end of the `autodoc-decl-keywords' occurrences to fontify the | |
2720 | ;; following declarations. | |
2721 | (setq c-type-decl-end-used t) | |
2722 | ||
7bfc3fdb MS |
2723 | `((,(lambda (limit) |
2724 | (c-font-lock-doc-comments "/[*/]!" limit | |
2725 | autodoc-font-lock-doc-comments))))) | |
d9e94c22 MS |
2726 | |
2727 | \f | |
3c0ab532 | 2728 | ;; 2006-07-10: awk-font-lock-keywords has been moved back to cc-awk.el. |
d9e94c22 MS |
2729 | (cc-provide 'cc-fonts) |
2730 | ||
2731 | ;;; cc-fonts.el ends here |