Mercurial > emacs
comparison lisp/font-lock.el @ 13299:d6bfe124472c
General reorganisation; moving and renaming etc.
Addition to font-lock-keywords; MATCH-ANCHORED structure and OVERRIDE values.
font-lock-fontify-anchored-keywords written to use the former,
font-lock-apply-highlight modified to use the latter.
author | Simon Marshall <simon@gnu.org> |
---|---|
date | Thu, 26 Oct 1995 13:27:36 +0000 |
parents | c9ed95ec05b6 |
children | 84acc3adcd63 |
comparison
equal
deleted
inserted
replaced
13298:945fd19491bc | 13299:d6bfe124472c |
---|---|
1 ;; Electric Font Lock Mode | 1 ;; Electric Font Lock Mode |
2 ;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. | 2 ;; Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc. |
3 | 3 |
4 ;; Author: jwz, then rms and sm <simon@gnu.ai.mit.edu> | 4 ;; Author: jwz, then rms, then sm <simon@gnu.ai.mit.edu> |
5 ;; Maintainer: FSF | 5 ;; Maintainer: FSF |
6 ;; Keywords: languages, faces | 6 ;; Keywords: languages, faces |
7 | 7 |
8 ;; This file is part of GNU Emacs. | 8 ;; This file is part of GNU Emacs. |
9 | 9 |
28 ;; | 28 ;; |
29 ;; Comments will be displayed in `font-lock-comment-face'. | 29 ;; Comments will be displayed in `font-lock-comment-face'. |
30 ;; Strings will be displayed in `font-lock-string-face'. | 30 ;; Strings will be displayed in `font-lock-string-face'. |
31 ;; Regexps are used to display selected patterns in other faces. | 31 ;; Regexps are used to display selected patterns in other faces. |
32 ;; | 32 ;; |
33 ;; To make the text you type be fontified, use M-x font-lock-mode. | 33 ;; To make the text you type be fontified, use M-x font-lock-mode RET. |
34 ;; When this minor mode is on, the faces of the current line are | 34 ;; When this minor mode is on, the faces of the current line are updated with |
35 ;; updated with every insertion or deletion. | 35 ;; every insertion or deletion. |
36 ;; | 36 ;; |
37 ;; To turn Font Lock mode on automatically, add this to your .emacs file: | 37 ;; To turn Font Lock mode on automatically, add this to your .emacs file: |
38 ;; | 38 ;; |
39 ;; (add-hook 'emacs-lisp-mode-hook 'turn-on-font-lock) | 39 ;; (add-hook 'emacs-lisp-mode-hook 'turn-on-font-lock) |
40 ;; | 40 ;; |
41 ;; On a Sparc2, `font-lock-fontify-buffer' takes about 10 seconds for a 120k | 41 ;; Fontification for a particular mode may be available in a number of levels |
42 ;; file of C code using the default configuration, and about 25 seconds using | 42 ;; of decoration. The higher the level, the more decoration, but the more time |
43 ;; the more extensive configuration, though times also depend on file contents. | 43 ;; it takes to fontify. See the variable `font-lock-maximum-decoration', and |
44 ;; You can speed this up substantially by removing some of the patterns that | 44 ;; also the variable `font-lock-maximum-size'. |
45 ;; are highlighted by default. Fontifying Lisp code is significantly faster, | 45 |
46 ;; because Lisp has a more regular syntax than C, so the expressions don't have | |
47 ;; to be as hairy. | |
48 ;; | |
49 ;; If you add patterns for a new mode, say foo.el's `foo-mode', say in which | 46 ;; If you add patterns for a new mode, say foo.el's `foo-mode', say in which |
50 ;; you don't want syntactic fontification to occur, you can make Font Lock mode | 47 ;; you don't want syntactic fontification to occur, you can make Font Lock mode |
51 ;; use your regexps when turning on Font Lock by adding to `foo-mode-hook': | 48 ;; use your regexps when turning on Font Lock by adding to `foo-mode-hook': |
52 ;; | 49 ;; |
53 ;; (add-hook 'foo-mode-hook | 50 ;; (add-hook 'foo-mode-hook |
56 ;; | 53 ;; |
57 ;; Nasty regexps of the form "bar\\(\\|lo\\)\\|f\\(oo\\|u\\(\\|bar\\)\\)\\|lo" | 54 ;; Nasty regexps of the form "bar\\(\\|lo\\)\\|f\\(oo\\|u\\(\\|bar\\)\\)\\|lo" |
58 ;; are made thusly: (make-regexp '("foo" "fu" "fubar" "bar" "barlo" "lo")) for | 55 ;; are made thusly: (make-regexp '("foo" "fu" "fubar" "bar" "barlo" "lo")) for |
59 ;; efficiency. See /pub/gnu/emacs/elisp-archive/functions/make-regexp.el.Z on | 56 ;; efficiency. See /pub/gnu/emacs/elisp-archive/functions/make-regexp.el.Z on |
60 ;; archive.cis.ohio-state.edu for this and other functions. | 57 ;; archive.cis.ohio-state.edu for this and other functions. |
58 | |
59 ;; What is fontification for? You might say, "It's to make my code look nice." | |
60 ;; I think it should be for adding information in the form of cues. These cues | |
61 ;; should provide you with enough information to both (a) distinguish between | |
62 ;; different items, and (b) identify the item meanings, without having to read | |
63 ;; the items and think about it. Therefore, fontification allows you to think | |
64 ;; less about, say, the structure of code, and more about, say, why the code | |
65 ;; doesn't work. Or maybe it allows you to think less and drift off to sleep. | |
66 ;; | |
67 ;; So, here are my opinions/advice/guidelines: | |
68 ;; | |
69 ;; - Use the same face for the same conceptual object, across all modes. | |
70 ;; i.e., (b) above, all modes that have items that can be thought of as, say, | |
71 ;; keywords, should be highlighted with the same face, etc. | |
72 ;; - Keep the faces distinct from each other as far as possible. | |
73 ;; i.e., (a) above. | |
74 ;; - Make the face attributes fit the concept as far as possible. | |
75 ;; i.e., function names might be a bold colour such as blue, comments might | |
76 ;; be a bright colour such as red, character strings might be brown, because, | |
77 ;; err, strings are brown (that was not the reason, please believe me). | |
78 ;; - Don't use a non-nil OVERRIDE unless you have a good reason. | |
79 ;; Only use OVERRIDE for special things that are easy to define, such as the | |
80 ;; way `...' quotes are treated in strings and comments in Emacs Lisp mode. | |
81 ;; Don't use it to, say, highlight keywords in commented out code or strings. | |
82 ;; - Err, that's it. | |
61 | 83 |
62 ;;; Code: | 84 ;; User variables. |
63 | 85 |
64 (defvar font-lock-comment-face 'font-lock-comment-face | 86 (defvar font-lock-verbose t |
87 "*If non-nil, means show status messages when fontifying.") | |
88 | |
89 ;;;###autoload | |
90 (defvar font-lock-maximum-decoration nil | |
91 "*If non-nil, the maximum decoration level for fontifying. | |
92 If nil, use the default decoration (typically the minimum available). | |
93 If t, use the maximum decoration available. | |
94 If a number, use that level of decoration (or if not available the maximum). | |
95 If a list, each element should be a cons pair of the form (MAJOR-MODE . LEVEL), | |
96 where MAJOR-MODE is a symbol or t (meaning the default). For example: | |
97 ((c++-mode . 2) (c-mode . t) (t . 1)) | |
98 means use level 2 decoration for buffers in `c++-mode', the maximum decoration | |
99 available for buffers in `c-mode', and level 1 decoration otherwise.") | |
100 | |
101 ;;;###autoload | |
102 (defvar font-lock-maximum-size (* 250 1024) | |
103 "*If non-nil, the maximum size for buffers for fontifying. | |
104 Only buffers less than this can be fontified when Font Lock mode is turned on. | |
105 If nil, means size is irrelevant. | |
106 If a list, each element should be a cons pair of the form (MAJOR-MODE . SIZE), | |
107 where MAJOR-MODE is a symbol or t (meaning the default). For example: | |
108 ((c++-mode . 256000) (c-mode . 256000) (rmail-mode . 1048576)) | |
109 means that the maximum size is 250K for buffers in `c++-mode' or `c-mode', one | |
110 megabyte for buffers in `rmail-mode', and size is irrelevant otherwise.") | |
111 | |
112 ;; Fontification variables: | |
113 | |
114 (defvar font-lock-comment-face 'font-lock-comment-face | |
65 "Face to use for comments.") | 115 "Face to use for comments.") |
66 | 116 |
67 (defvar font-lock-string-face 'font-lock-string-face | 117 (defvar font-lock-string-face 'font-lock-string-face |
68 "Face to use for strings.") | 118 "Face to use for strings.") |
69 | 119 |
70 (defvar font-lock-function-name-face 'font-lock-function-name-face | 120 (defvar font-lock-keyword-face 'font-lock-keyword-face |
121 "Face to use for keywords.") | |
122 | |
123 (defvar font-lock-function-name-face 'font-lock-function-name-face | |
71 "Face to use for function names.") | 124 "Face to use for function names.") |
72 | 125 |
73 (defvar font-lock-variable-name-face 'font-lock-variable-name-face | 126 (defvar font-lock-variable-name-face 'font-lock-variable-name-face |
74 "Face to use for variable names.") | 127 "Face to use for variable names.") |
75 | 128 |
76 (defvar font-lock-keyword-face 'font-lock-keyword-face | 129 (defvar font-lock-type-face 'font-lock-type-face |
77 "Face to use for keywords.") | 130 "Face to use for type names.") |
78 | 131 |
79 (defvar font-lock-type-face 'font-lock-type-face | 132 (defvar font-lock-reference-face 'font-lock-reference-face |
80 "Face to use for data types.") | 133 "Face to use for reference names.") |
81 | 134 |
82 (defvar font-lock-reference-face 'font-lock-reference-face | |
83 "Face to use for references.") | |
84 | |
85 (make-variable-buffer-local 'font-lock-keywords) | |
86 (defvar font-lock-keywords nil | 135 (defvar font-lock-keywords nil |
87 "*A list of the keywords to highlight. | 136 "*A list of the keywords to highlight. |
88 Each element should be of the form: | 137 Each element should be of the form: |
89 | 138 |
90 MATCHER | 139 MATCHER |
91 (MATCHER . MATCH) | 140 (MATCHER . MATCH) |
92 (MATCHER . FACENAME) | 141 (MATCHER . FACENAME) |
93 (MATCHER . HIGHLIGHT) | 142 (MATCHER . HIGHLIGHT) |
94 (MATCHER HIGHLIGHT ...) | 143 (MATCHER HIGHLIGHT ...) |
95 | 144 |
96 where HIGHLIGHT should be of the form (MATCH FACENAME OVERRIDE LAXMATCH). | 145 where HIGHLIGHT should be either MATCH-HIGHLIGHT or MATCH-ANCHORED. |
97 MATCHER can be either the regexp to search for, or the function name to call to | 146 |
98 make the search (called with one argument, the limit of the search). MATCH is | 147 For highlighting single items, typically only MATCH-HIGHLIGHT is required. |
99 the subexpression of MATCHER to be highlighted. FACENAME is an expression | 148 However, if an item or (typically) items is to be hightlighted following the |
100 whose value is the face name to use. FACENAME's default attributes may be | 149 instance of another item (the anchor) then MATCH-ANCHORED may be required. |
101 defined in `font-lock-face-attributes'. | 150 |
151 MATCH-HIGHLIGHT should be of the form: | |
152 | |
153 (MATCH FACENAME OVERRIDE LAXMATCH) | |
154 | |
155 Where MATCHER can be either the regexp to search for, or the function name to | |
156 call to make the search (called with one argument, the limit of the search). | |
157 MATCH is the subexpression of MATCHER to be highlighted. FACENAME is an | |
158 expression whose value is the face name to use. FACENAME's default attributes | |
159 may be defined in `font-lock-face-attributes'. | |
102 | 160 |
103 OVERRIDE and LAXMATCH are flags. If OVERRIDE is t, existing fontification may | 161 OVERRIDE and LAXMATCH are flags. If OVERRIDE is t, existing fontification may |
104 be overriden. If `keep', only parts not already fontified are highlighted. | 162 be overwritten. If `keep', only parts not already fontified are highlighted. |
163 If `prepend' or `append', existing fontification is merged with the new, in | |
164 which the new or existing fontification, respectively, takes precedence. | |
105 If LAXMATCH is non-nil, no error is signalled if there is no MATCH in MATCHER. | 165 If LAXMATCH is non-nil, no error is signalled if there is no MATCH in MATCHER. |
166 | |
167 For example, an element of the form highlights (if not already highlighted): | |
168 | |
169 \"foo\" Occurrences of \"foo\" in `font-lock-keyword-face'. | |
170 (\"fu\\\\(bar\\\\)\" . 1) Substring \"bar\" within all occurrences of \"fubar\" in | |
171 the value of `font-lock-keyword-face'. | |
172 (\"fubar\" . fubar-face) Occurrences of \"fubar\" in the value of `fubar-face'. | |
173 (\"foo\\\\|bar\" 0 foo-bar-face t) | |
174 Occurrences of either \"foo\" or \"bar\" in the value | |
175 of `foo-bar-face', even if already highlighted. | |
176 | |
177 MATCH-ANCHORED should be of the form: | |
178 | |
179 (MATCHER PRE-MATCH-FORM POST-MATCH-FORM MATCH-HIGHLIGHT ...) | |
180 | |
181 Where MATCHER is as for MATCH-HIGHLIGHT. PRE-MATCH-FORM and POST-MATCH-FORM | |
182 are evaluated before the first, and after the last, instance MATCH-ANCHORED's | |
183 MATCHER is used. Therefore they can be used to initialise before, and cleanup | |
184 after, MATCHER is used. Typically, PRE-MATCH-FORM is used to move to some | |
185 position relative to the original MATCHER, before starting with | |
186 MATCH-ANCHORED's MATCHER. POST-MATCH-FORM might be used to move, before | |
187 resuming with MATCH-ANCHORED's parent's MATCHER. | |
188 | |
189 For example, an element of the form highlights (if not already highlighted): | |
190 | |
191 (\"anchor\" (0 anchor-face) (\".*\\\\(item\\\\)\" nil nil (1 item-face))) | |
192 | |
193 Occurrences of \"anchor\" in the value of `anchor-face', and subsequent | |
194 occurrences of \"item\" on the same line (by virtue of the `.*' regexp) in the | |
195 value of `item-face'. (Here PRE-MATCH-FORM and POST-MATCH-FORM are nil. | |
196 Therefore \"item\" is initially searched for starting from the end of the match | |
197 of \"anchor\", and searching for subsequent instance of \"anchor\" resumes from | |
198 where searching for \"item\" concluded.) | |
199 | |
200 Note that the MATCH-ANCHORED feature is experimental; in the future, we may | |
201 replace it with other ways of providing this functionality. | |
106 | 202 |
107 These regular expressions should not match text which spans lines. While | 203 These regular expressions should not match text which spans lines. While |
108 \\[font-lock-fontify-buffer] handles multi-line patterns correctly, updating | 204 \\[font-lock-fontify-buffer] handles multi-line patterns correctly, updating |
109 when you edit the buffer does not, since it considers text one line at a time. | 205 when you edit the buffer does not, since it considers text one line at a time. |
110 | 206 |
111 Be careful composing regexps for this list; | 207 Be very careful composing regexps for this list; |
112 the wrong pattern can dramatically slow things down!") | 208 the wrong pattern can dramatically slow things down!") |
209 (make-variable-buffer-local 'font-lock-keywords) | |
113 | 210 |
114 (defvar font-lock-defaults nil | 211 (defvar font-lock-defaults nil |
115 "If set by a major mode, should be the defaults for Font Lock mode. | 212 "If set by a major mode, should be the defaults for Font Lock mode. |
116 The value should look like the `cdr' of an item in `font-lock-defaults-alist'.") | 213 The value should be like the `cdr' of an item in `font-lock-defaults-alist'.") |
117 | 214 |
118 (defvar font-lock-defaults-alist | 215 (defvar font-lock-defaults-alist |
119 (let ( | 216 (let (;; For C and Lisp modes we use `beginning-of-defun', rather than nil, |
120 ;; For C and Lisp modes we use `beginning-of-defun', rather than nil, | 217 ;; for SYNTAX-BEGIN. Thus the calculation of the cache is usually |
121 ;; for SYNTAX-BEGIN. Thus the calculation of the cache is faster but | 218 ;; faster but not infallible, so we risk mis-fontification. --sm. |
122 ;; not infallible, so we risk mis-fontification. --sm | |
123 (c-mode-defaults | 219 (c-mode-defaults |
124 '((c-font-lock-keywords c-font-lock-keywords-1 c-font-lock-keywords-2) | 220 '((c-font-lock-keywords c-font-lock-keywords-1 |
125 nil nil ((?\_ . "w")) beginning-of-defun)) | 221 c-font-lock-keywords-2 c-font-lock-keywords-3) |
222 nil nil ((?_ . "w")) beginning-of-defun)) | |
126 (c++-mode-defaults | 223 (c++-mode-defaults |
127 '((c++-font-lock-keywords c++-font-lock-keywords-1 | 224 '((c++-font-lock-keywords c++-font-lock-keywords-1 |
128 c++-font-lock-keywords-2) | 225 c++-font-lock-keywords-2 c++-font-lock-keywords-3) |
129 nil nil ((?\_ . "w")) beginning-of-defun)) | 226 nil nil ((?_ . "w") (?~ . "w")) beginning-of-defun)) |
130 (lisp-mode-defaults | 227 (lisp-mode-defaults |
131 '((lisp-font-lock-keywords lisp-font-lock-keywords-1 | 228 '((lisp-font-lock-keywords |
132 lisp-font-lock-keywords-2) | 229 lisp-font-lock-keywords-1 lisp-font-lock-keywords-2) |
133 nil nil ((?\: . "w") (?\- . "w") (?\* . "w")) | 230 nil nil |
231 ((?: . "w") (?- . "w") (?* . "w") (?+ . "w") (?. . "w") (?< . "w") | |
232 (?> . "w") (?= . "w") (?! . "w") (?? . "w") (?$ . "w") (?% . "w") | |
233 (?_ . "w") (?& . "w") (?~ . "w") (?^ . "w") (?/ . "w")) | |
134 beginning-of-defun)) | 234 beginning-of-defun)) |
135 (scheme-mode-defaults | 235 (scheme-mode-defaults |
136 '(scheme-font-lock-keywords | 236 '(scheme-font-lock-keywords nil t |
137 nil nil ((?\: . "w") (?\- . "w") (?\* . "w") (?\/ . "w")) | 237 ((?: . "w") (?- . "w") (?* . "w") (?+ . "w") (?. . "w") (?< . "w") |
238 (?> . "w") (?= . "w") (?! . "w") (?? . "w") (?$ . "w") (?% . "w") | |
239 (?_ . "w") (?& . "w") (?~ . "w") (?^ . "w") (?/ . "w")) | |
138 beginning-of-defun)) | 240 beginning-of-defun)) |
139 ;; For TeX modes we could use `backward-paragraph' for the same reason. | 241 ;; For TeX modes we could use `backward-paragraph' for the same reason. |
140 (tex-mode-defaults '(tex-font-lock-keywords nil nil ((?\$ . "\"")))) | 242 (tex-mode-defaults '(tex-font-lock-keywords nil nil ((?$ . "\"")))) |
141 ) | 243 ) |
142 (list | 244 (list |
143 (cons 'bibtex-mode tex-mode-defaults) | 245 (cons 'bibtex-mode tex-mode-defaults) |
144 (cons 'c++-c-mode c-mode-defaults) | 246 (cons 'c++-c-mode c-mode-defaults) |
145 (cons 'c++-mode c++-mode-defaults) | 247 (cons 'c++-mode c++-mode-defaults) |
146 (cons 'c-mode c-mode-defaults) | 248 (cons 'c-mode c-mode-defaults) |
249 (cons 'elec-c-mode c-mode-defaults) | |
147 (cons 'emacs-lisp-mode lisp-mode-defaults) | 250 (cons 'emacs-lisp-mode lisp-mode-defaults) |
148 (cons 'inferior-scheme-mode scheme-mode-defaults) | 251 (cons 'inferior-scheme-mode scheme-mode-defaults) |
149 (cons 'latex-mode tex-mode-defaults) | 252 (cons 'latex-mode tex-mode-defaults) |
150 (cons 'lisp-mode lisp-mode-defaults) | 253 (cons 'lisp-mode lisp-mode-defaults) |
151 (cons 'lisp-interaction-mode lisp-mode-defaults) | 254 (cons 'lisp-interaction-mode lisp-mode-defaults) |
152 (cons 'plain-tex-mode tex-mode-defaults) | 255 (cons 'plain-tex-mode tex-mode-defaults) |
153 (cons 'scheme-mode scheme-mode-defaults) | 256 (cons 'scheme-mode scheme-mode-defaults) |
154 (cons 'scheme-interaction-mode scheme-mode-defaults) | 257 (cons 'scheme-interaction-mode scheme-mode-defaults) |
155 (cons 'slitex-mode tex-mode-defaults) | 258 (cons 'slitex-mode tex-mode-defaults) |
156 (cons 'tex-mode tex-mode-defaults))) | 259 (cons 'tex-mode tex-mode-defaults))) |
157 "*Alist of default major mode and Font Lock defaults. | 260 "Alist of default major mode and Font Lock defaults. |
158 Each item should be a list of the form: | 261 Each item should be a list of the form: |
159 | 262 |
160 (MAJOR-MODE . (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN)) | 263 (MAJOR-MODE . (KEYWORDS KEYWORDS-ONLY CASE-FOLD SYNTAX-ALIST SYNTAX-BEGIN)) |
161 | 264 |
162 where MAJOR-MODE is a symbol, and KEYWORDS may be a symbol or a list of | 265 where MAJOR-MODE is a symbol. KEYWORDS may be a symbol (a variable or function |
163 symbols. If KEYWORDS-ONLY is non-nil, syntactic fontification (strings and | 266 whose value is the keywords to use for fontification) or a list of symbols. |
164 comments) is not performed. If CASE-FOLD is non-nil, the case of the keywords | 267 If KEYWORDS-ONLY is non-nil, syntactic fontification (strings and comments) is |
165 is ignored when fontifying. If SYNTAX-ALIST is non-nil, it should be a list of | 268 not performed. If CASE-FOLD is non-nil, the case of the keywords is ignored |
166 cons pairs of the form (CHAR . STRING) used to set the local Font Lock syntax | 269 when fontifying. If SYNTAX-ALIST is non-nil, it should be a list of cons pairs |
167 table for keyword and syntactic fontification. (See `modify-syntax-entry'.) | 270 of the form (CHAR . STRING) used to set the local Font Lock syntax table, for |
168 | 271 keyword and syntactic fontification (see `modify-syntax-entry'). |
169 SYNTAX-BEGIN should be a function, it is called with no args to move outside of | 272 |
170 a syntactic block for syntactic fontification. Typical values are nil | 273 If SYNTAX-BEGIN is non-nil, it should be a function with no args used to move |
171 \(equivalent to `beginning-of-buffer'), `beginning-of-line' (i.e., the start of | 274 backwards outside any enclosing syntactic block, for syntactic fontification. |
172 the line is known to be outside a syntactic block), or `beginning-of-defun' for | 275 Typical values are `beginning-of-line' (i.e., the start of the line is known to |
173 programming modes or `backward-paragraph' for textual modes (i.e., the | 276 be outside a syntactic block), or `beginning-of-defun' for programming modes or |
174 mode-dependent function is known to move outside a syntactic block). | 277 `backward-paragraph' for textual modes (i.e., the mode-dependent function is |
278 known to move outside a syntactic block). If nil, the beginning of the buffer | |
279 is used as a position outside of a syntactic block, in the worst case. | |
175 | 280 |
176 These item elements are used by Font Lock mode to set the variables | 281 These item elements are used by Font Lock mode to set the variables |
177 `font-lock-keywords', `font-lock-no-comments', | 282 `font-lock-keywords', `font-lock-keywords-only', |
178 `font-lock-keywords-case-fold-search', `font-lock-syntax-table' and | 283 `font-lock-keywords-case-fold-search', `font-lock-syntax-table' and |
179 `font-lock-beginning-of-syntax-function', respectively.") | 284 `font-lock-beginning-of-syntax-function', respectively.") |
180 | 285 |
181 (defvar font-lock-no-comments nil | 286 (defvar font-lock-keywords-only nil |
182 "*Non-nil means Font Lock should not fontify comments or strings. | 287 "*Non-nil means Font Lock should not fontify comments or strings. |
183 This is normally set via `font-lock-defaults'.") | 288 This is normally set via `font-lock-defaults'.") |
184 | 289 |
185 (defvar font-lock-keywords-case-fold-search nil | 290 (defvar font-lock-keywords-case-fold-search nil |
186 "*Non-nil means the patterns in `font-lock-keywords' are case-insensitive. | 291 "*Non-nil means the patterns in `font-lock-keywords' are case-insensitive. |
189 (defvar font-lock-syntax-table nil | 294 (defvar font-lock-syntax-table nil |
190 "Non-nil means use this syntax table for fontifying. | 295 "Non-nil means use this syntax table for fontifying. |
191 If this is nil, the major mode's syntax table is used. | 296 If this is nil, the major mode's syntax table is used. |
192 This is normally set via `font-lock-defaults'.") | 297 This is normally set via `font-lock-defaults'.") |
193 | 298 |
299 ;; If this is nil, we only use the beginning of the buffer if we can't use | |
300 ;; `font-lock-cache-position' and `font-lock-cache-state'. | |
194 (defvar font-lock-beginning-of-syntax-function nil | 301 (defvar font-lock-beginning-of-syntax-function nil |
195 "*Non-nil means use this function to move outside of a syntactic block. | 302 "*Non-nil means use this function to move back outside of a syntactic block. |
196 If this is nil, `beginning-of-buffer' is used. | 303 If this is nil, the beginning of the buffer is used (in the worst case). |
197 This is normally set via `font-lock-defaults'.") | 304 This is normally set via `font-lock-defaults'.") |
198 | 305 |
199 (defvar font-lock-verbose t | 306 ;; These record the parse state at a particular position, always the start of a |
200 "*Non-nil means `font-lock-fontify-buffer' should print status messages.") | 307 ;; line. Used to make `font-lock-fontify-syntactically-region' faster. |
201 | 308 (defvar font-lock-cache-position nil) |
202 ;;;###autoload | 309 (defvar font-lock-cache-state nil) |
203 (defvar font-lock-maximum-decoration nil | 310 (make-variable-buffer-local 'font-lock-cache-position) |
204 "*If non-nil, the maximum decoration for fontifying. | 311 (make-variable-buffer-local 'font-lock-cache-state) |
205 If nil, use the default decoration (typically the minimum available). | 312 |
206 If t, use the maximum decoration available. | 313 (defvar font-lock-mode nil) ; For the modeline. |
207 If a number, use that level of decoration (or if not available the maximum).") | 314 (defvar font-lock-fontified nil) ; Whether we have fontified the buffer. |
208 | 315 (put 'font-lock-fontified 'permanent-local t) |
209 ;;;###autoload | |
210 (defvar font-lock-maximum-size | |
211 (if font-lock-maximum-decoration (* 150 1024) (* 300 1024)) | |
212 "*If non-nil, the maximum size for buffers for fontifying. | |
213 Only buffers less than this can be fontified when Font Lock mode is turned on. | |
214 If nil, means size is irrelevant.") | |
215 | 316 |
216 ;;;###autoload | 317 ;;;###autoload |
217 (defvar font-lock-mode-hook nil | 318 (defvar font-lock-mode-hook nil |
218 "Function or functions to run on entry to Font Lock mode.") | 319 "Function or functions to run on entry to Font Lock mode.") |
320 | |
321 ;; User functions. | |
322 | |
323 ;;;###autoload | |
324 (defun font-lock-mode (&optional arg) | |
325 "Toggle Font Lock mode. | |
326 With arg, turn Font Lock mode on if and only if arg is positive. | |
327 | |
328 When Font Lock mode is enabled, text is fontified as you type it: | |
329 | |
330 - Comments are displayed in `font-lock-comment-face'; | |
331 - Strings are displayed in `font-lock-string-face'; | |
332 - Certain other expressions are displayed in other faces according to the | |
333 value of the variable `font-lock-keywords'. | |
334 | |
335 You can enable Font Lock mode in any major mode automatically by turning on in | |
336 the major mode's hook. For example, put in your ~/.emacs: | |
337 | |
338 (add-hook 'c-mode-hook 'turn-on-font-lock) | |
339 | |
340 Or for any visited file with the following in your ~/.emacs: | |
341 | |
342 (add-hook 'find-file-hooks 'turn-on-font-lock) | |
343 | |
344 The default Font Lock mode faces and their attributes are defined in the | |
345 variable `font-lock-face-attributes', and Font Lock mode default settings in | |
346 the variable `font-lock-defaults-alist'. You can set your own default settings | |
347 for some mode, by setting a buffer local value for `font-lock-defaults', via | |
348 its mode hook. | |
349 | |
350 Where modes support different levels of fontification, you can use the variable | |
351 `font-lock-maximum-decoration' to specify which level you generally prefer. | |
352 When you turn Font Lock mode on/off the buffer is fontified/defontified, though | |
353 fontification occurs only if the buffer is less than `font-lock-maximum-size'. | |
354 To fontify a buffer without turning on Font Lock mode, and regardless of buffer | |
355 size, you can use \\[font-lock-fontify-buffer]." | |
356 (interactive "P") | |
357 (let ((on-p (if arg (> (prefix-numeric-value arg) 0) (not font-lock-mode))) | |
358 (maximum-size (if (not (consp font-lock-maximum-size)) | |
359 font-lock-maximum-size | |
360 (cdr (or (assq major-mode font-lock-maximum-size) | |
361 (assq t font-lock-maximum-size)))))) | |
362 (if (equal (buffer-name) " *Compiler Input*") ; hack for bytecomp... | |
363 (setq on-p nil)) | |
364 (if (not on-p) | |
365 (remove-hook 'after-change-functions 'font-lock-after-change-function) | |
366 (make-local-variable 'after-change-functions) | |
367 (add-hook 'after-change-functions 'font-lock-after-change-function)) | |
368 (set (make-local-variable 'font-lock-mode) on-p) | |
369 (cond (on-p | |
370 (font-lock-set-defaults) | |
371 (make-local-variable 'before-revert-hook) | |
372 (make-local-variable 'after-revert-hook) | |
373 ;; If buffer is reverted, must clean up the state. | |
374 (add-hook 'before-revert-hook 'font-lock-revert-setup) | |
375 (add-hook 'after-revert-hook 'font-lock-revert-cleanup) | |
376 (run-hooks 'font-lock-mode-hook) | |
377 (cond (font-lock-fontified | |
378 nil) | |
379 ((or (null maximum-size) (<= (buffer-size) maximum-size)) | |
380 (font-lock-fontify-buffer)) | |
381 (font-lock-verbose | |
382 (message "Fontifying %s... buffer too big." (buffer-name))))) | |
383 (font-lock-fontified | |
384 (setq font-lock-fontified nil) | |
385 (remove-hook 'before-revert-hook 'font-lock-revert-setup) | |
386 (remove-hook 'after-revert-hook 'font-lock-revert-cleanup) | |
387 (font-lock-unfontify-region (point-min) (point-max)) | |
388 (font-lock-thing-lock-cleanup)) | |
389 (t | |
390 (remove-hook 'before-revert-hook 'font-lock-revert-setup) | |
391 (remove-hook 'after-revert-hook 'font-lock-revert-cleanup) | |
392 (font-lock-thing-lock-cleanup))) | |
393 (force-mode-line-update))) | |
394 | |
395 ;;;###autoload | |
396 (defun turn-on-font-lock () | |
397 "Unconditionally turn on Font Lock mode." | |
398 (font-lock-mode 1)) | |
399 | |
400 ;;;###autoload | |
401 (defun font-lock-fontify-buffer () | |
402 "Fontify the current buffer the way `font-lock-mode' would." | |
403 (interactive) | |
404 (let ((verbose (and (or font-lock-verbose (interactive-p)) | |
405 (not (zerop (buffer-size))))) | |
406 (modified (buffer-modified-p))) | |
407 (set (make-local-variable 'font-lock-fontified) nil) | |
408 (if verbose (message "Fontifying %s..." (buffer-name))) | |
409 ;; Turn it on to run hooks and get the right `font-lock-keywords' etc. | |
410 (or font-lock-mode (font-lock-set-defaults)) | |
411 (condition-case nil | |
412 (save-excursion | |
413 (font-lock-fontify-region (point-min) (point-max) verbose) | |
414 (setq font-lock-fontified t)) | |
415 ;; We don't restore the old fontification, so it's best to unfontify. | |
416 (quit (font-lock-unfontify-region (point-min) (point-max)))) | |
417 (if verbose (message "Fontifying %s... %s." (buffer-name) | |
418 (if font-lock-fontified "done" "aborted"))) | |
419 (and (buffer-modified-p) | |
420 (not modified) | |
421 (set-buffer-modified-p nil)) | |
422 (font-lock-after-fontify-buffer))) | |
423 | |
424 ;; Fontification functions. | |
425 | |
426 ;; We use this wrapper. However, `font-lock-fontify-region' used to be the | |
427 ;; name used for `font-lock-fontify-syntactically-region', so a change isn't | |
428 ;; back-compatible. But you shouldn't be calling these directly, should you? | |
429 (defun font-lock-fontify-region (beg end &optional loudly) | |
430 (if font-lock-keywords-only | |
431 (font-lock-unfontify-region beg end) | |
432 (font-lock-fontify-syntactically-region beg end loudly)) | |
433 (font-lock-fontify-keywords-region beg end loudly)) | |
434 | |
435 ;; The following must be rethought, since keywords can override fontification. | |
436 ; ;; Now scan for keywords, but not if we are inside a comment now. | |
437 ; (or (and (not font-lock-keywords-only) | |
438 ; (let ((state (parse-partial-sexp beg end nil nil | |
439 ; font-lock-cache-state))) | |
440 ; (or (nth 4 state) (nth 7 state)))) | |
441 ; (font-lock-fontify-keywords-region beg end)) | |
442 | |
443 (defun font-lock-unfontify-region (beg end) | |
444 (let ((modified (buffer-modified-p)) | |
445 (buffer-undo-list t) (inhibit-read-only t) | |
446 buffer-file-name buffer-file-truename) | |
447 (remove-text-properties beg end '(face nil)) | |
448 (and (buffer-modified-p) | |
449 (not modified) | |
450 (set-buffer-modified-p nil)))) | |
451 | |
452 ;; Called when any modification is made to buffer text. | |
453 (defun font-lock-after-change-function (beg end old-len) | |
454 (save-excursion | |
455 (save-match-data | |
456 ;; Rescan between start of line from `beg' and start of line after `end'. | |
457 (font-lock-fontify-region | |
458 (progn (goto-char beg) (beginning-of-line) (point)) | |
459 (progn (goto-char end) (forward-line 1) (point)))))) | |
460 | |
461 ;; Syntactic fontification functions. | |
462 | |
463 (defun font-lock-fontify-syntactically-region (start end &optional loudly) | |
464 "Put proper face on each string and comment between START and END. | |
465 START should be at the beginning of a line." | |
466 (let ((inhibit-read-only t) (buffer-undo-list t) | |
467 (modified (buffer-modified-p)) | |
468 (old-syntax (syntax-table)) | |
469 (synstart (if comment-start-skip | |
470 (concat "\\s\"\\|" comment-start-skip) | |
471 "\\s\"")) | |
472 (comstart (if comment-start-skip | |
473 (concat "\\s<\\|" comment-start-skip) | |
474 "\\s<")) | |
475 buffer-file-name buffer-file-truename | |
476 state prev prevstate) | |
477 (if loudly (message "Fontifying %s... (syntactically...)" (buffer-name))) | |
478 (unwind-protect | |
479 (save-restriction | |
480 (widen) | |
481 (goto-char start) | |
482 ;; | |
483 ;; Use the fontification syntax table, if any. | |
484 (if font-lock-syntax-table (set-syntax-table font-lock-syntax-table)) | |
485 ;; | |
486 ;; Find the state at the `beginning-of-line' before `start'. | |
487 (if (eq start font-lock-cache-position) | |
488 ;; Use the cache for the state of `start'. | |
489 (setq state font-lock-cache-state) | |
490 ;; Find the state of `start'. | |
491 (if (null font-lock-beginning-of-syntax-function) | |
492 ;; Use the state at the previous cache position, if any, or | |
493 ;; otherwise calculate from `point-min'. | |
494 (if (or (null font-lock-cache-position) | |
495 (< start font-lock-cache-position)) | |
496 (setq state (parse-partial-sexp (point-min) start)) | |
497 (setq state (parse-partial-sexp | |
498 font-lock-cache-position start | |
499 nil nil font-lock-cache-state))) | |
500 ;; Call the function to move outside any syntactic block. | |
501 (funcall font-lock-beginning-of-syntax-function) | |
502 (setq state (parse-partial-sexp (point) start))) | |
503 ;; Cache the state and position of `start'. | |
504 (setq font-lock-cache-state state | |
505 font-lock-cache-position start)) | |
506 ;; | |
507 ;; If the region starts inside a string, show the extent of it. | |
508 (if (nth 3 state) | |
509 (let ((beg (point))) | |
510 (while (and (re-search-forward "\\s\"" end 'move) | |
511 (nth 3 (parse-partial-sexp beg (point) | |
512 nil nil state)))) | |
513 (put-text-property beg (point) 'face font-lock-string-face) | |
514 (setq state (parse-partial-sexp beg (point) nil nil state)))) | |
515 ;; | |
516 ;; Likewise for a comment. | |
517 (if (or (nth 4 state) (nth 7 state)) | |
518 (let ((beg (point))) | |
519 (save-restriction | |
520 (narrow-to-region (point-min) end) | |
521 (condition-case nil | |
522 (progn | |
523 (re-search-backward comstart (point-min) 'move) | |
524 (forward-comment 1) | |
525 ;; forward-comment skips all whitespace, | |
526 ;; so go back to the real end of the comment. | |
527 (skip-chars-backward " \t")) | |
528 (error (goto-char end)))) | |
529 (put-text-property beg (point) 'face font-lock-comment-face) | |
530 (setq state (parse-partial-sexp beg (point) nil nil state)))) | |
531 ;; | |
532 ;; Find each interesting place between here and `end'. | |
533 (while (and (< (point) end) | |
534 (setq prev (point) prevstate state) | |
535 (re-search-forward synstart end t) | |
536 (progn | |
537 ;; Clear out the fonts of what we skip over. | |
538 (remove-text-properties prev (point) '(face nil)) | |
539 ;; Verify the state at that place | |
540 ;; so we don't get fooled by \" or \;. | |
541 (setq state (parse-partial-sexp prev (point) | |
542 nil nil state)))) | |
543 (let ((here (point))) | |
544 (if (or (nth 4 state) (nth 7 state)) | |
545 ;; | |
546 ;; We found a real comment start. | |
547 (let ((beg (match-beginning 0))) | |
548 (goto-char beg) | |
549 (save-restriction | |
550 (narrow-to-region (point-min) end) | |
551 (condition-case nil | |
552 (progn | |
553 (forward-comment 1) | |
554 ;; forward-comment skips all whitespace, | |
555 ;; so go back to the real end of the comment. | |
556 (skip-chars-backward " \t")) | |
557 (error (goto-char end)))) | |
558 (put-text-property beg (point) 'face | |
559 font-lock-comment-face) | |
560 (setq state (parse-partial-sexp here (point) nil nil state))) | |
561 (if (nth 3 state) | |
562 ;; | |
563 ;; We found a real string start. | |
564 (let ((beg (match-beginning 0))) | |
565 (while (and (re-search-forward "\\s\"" end 'move) | |
566 (nth 3 (parse-partial-sexp here (point) | |
567 nil nil state)))) | |
568 (put-text-property beg (point) 'face font-lock-string-face) | |
569 (setq state (parse-partial-sexp here (point) | |
570 nil nil state)))))) | |
571 ;; | |
572 ;; Make sure `prev' is non-nil after the loop | |
573 ;; only if it was set on the very last iteration. | |
574 (setq prev nil))) | |
575 ;; | |
576 ;; Clean up. | |
577 (set-syntax-table old-syntax) | |
578 (if prev (remove-text-properties prev end '(face nil))) | |
579 (and (buffer-modified-p) | |
580 (not modified) | |
581 (set-buffer-modified-p nil))))) | |
582 | |
583 ;;; Additional text property functions. | |
584 | |
585 ;; The following three text property functions are not generally available (and | |
586 ;; it's not certain that they should be) so they are inlined for speed. | |
587 ;; The case for `fillin-text-property' is simple; it may or not be generally | |
588 ;; useful. (Since it is used here, it is useful in at least one place.;-) | |
589 ;; However, the case for `append-text-property' and `prepend-text-property' is | |
590 ;; more complicated. Should they remove duplicate property values or not? If | |
591 ;; so, should the first or last duplicate item remain? Or the one that was | |
592 ;; added? In our implementation, the first duplicate remains. | |
593 | |
594 (defsubst font-lock-fillin-text-property (start end prop value &optional object) | |
595 "Fill in one property of the text from START to END. | |
596 Arguments PROP and VALUE specify the property and value to put where none are | |
597 already in place. Therefore existing property values are not overwritten. | |
598 Optional argument OBJECT is the string or buffer containing the text." | |
599 (let ((start (text-property-any start end prop nil object)) next) | |
600 (while start | |
601 (setq next (next-single-property-change start prop object end)) | |
602 (put-text-property start next prop value object) | |
603 (setq start (text-property-any next end prop nil object))))) | |
604 | |
605 ;; This function (from simon's unique.el) is rewritten and inlined for speed. | |
606 ;(defun unique (list function) | |
607 ; "Uniquify LIST, deleting elements using FUNCTION. | |
608 ;Return the list with subsequent duplicate items removed by side effects. | |
609 ;FUNCTION is called with an element of LIST and a list of elements from LIST, | |
610 ;and should return the list of elements with occurrences of the element removed, | |
611 ;i.e., a function such as `delete' or `delq'. | |
612 ;This function will work even if LIST is unsorted. See also `uniq'." | |
613 ; (let ((list list)) | |
614 ; (while list | |
615 ; (setq list (setcdr list (funcall function (car list) (cdr list)))))) | |
616 ; list) | |
617 | |
618 (defsubst font-lock-unique (list) | |
619 "Uniquify LIST, deleting elements using `delq'. | |
620 Return the list with subsequent duplicate items removed by side effects." | |
621 (let ((list list)) | |
622 (while list | |
623 (setq list (setcdr list (delq (car list) (cdr list)))))) | |
624 list) | |
625 | |
626 ;; A generalisation of `facemenu-add-face' for any property, but without the | |
627 ;; removal of inactive faces via `facemenu-discard-redundant-faces' and special | |
628 ;; treatment of `default'. Uses `unique' to remove duplicate property values. | |
629 (defsubst font-lock-prepend-text-property (start end prop value &optional object) | |
630 "Prepend to one property of the text from START to END. | |
631 Arguments PROP and VALUE specify the property and value to prepend to the value | |
632 already in place. The resulting property values are always lists, and unique. | |
633 Optional argument OBJECT is the string or buffer containing the text." | |
634 (let ((val (if (listp value) value (list value))) next prev) | |
635 (while (/= start end) | |
636 (setq next (next-single-property-change start prop object end) | |
637 prev (get-text-property start prop object)) | |
638 (put-text-property | |
639 start next prop | |
640 (font-lock-unique (append val (if (listp prev) prev (list prev)))) | |
641 object) | |
642 (setq start next)))) | |
643 | |
644 (defsubst font-lock-append-text-property (start end prop value &optional object) | |
645 "Append to one property of the text from START to END. | |
646 Arguments PROP and VALUE specify the property and value to append to the value | |
647 already in place. The resulting property values are always lists, and unique. | |
648 Optional argument OBJECT is the string or buffer containing the text." | |
649 (let ((val (if (listp value) value (list value))) next prev) | |
650 (while (/= start end) | |
651 (setq next (next-single-property-change start prop object end) | |
652 prev (get-text-property start prop object)) | |
653 (put-text-property | |
654 start next prop | |
655 (font-lock-unique (append (if (listp prev) prev (list prev)) val)) | |
656 object) | |
657 (setq start next)))) | |
658 | |
659 ;;; Regexp fontification functions. | |
660 | |
661 (defsubst font-lock-apply-highlight (highlight) | |
662 "Apply HIGHLIGHT following a match. | |
663 HIGHLIGHT should be of the form MATCH-HIGHLIGHT, see `font-lock-keywords'." | |
664 (let* ((match (nth 0 highlight)) | |
665 (start (match-beginning match)) (end (match-end match)) | |
666 (override (nth 2 highlight))) | |
667 (cond ((not start) | |
668 ;; No match but we might not signal an error. | |
669 (or (nth 3 highlight) | |
670 (error "No match %d in highlight %S" match highlight))) | |
671 ((not override) | |
672 ;; Cannot override existing fontification. | |
673 (or (text-property-not-all start end 'face nil) | |
674 (put-text-property start end 'face (eval (nth 1 highlight))))) | |
675 ((eq override t) | |
676 ;; Override existing fontification. | |
677 (put-text-property start end 'face (eval (nth 1 highlight)))) | |
678 ((eq override 'keep) | |
679 ;; Keep existing fontification. | |
680 (font-lock-fillin-text-property start end 'face | |
681 (eval (nth 1 highlight)))) | |
682 ((eq override 'prepend) | |
683 ;; Prepend to existing fontification. | |
684 (font-lock-prepend-text-property start end 'face | |
685 (eval (nth 1 highlight)))) | |
686 ((eq override 'append) | |
687 ;; Append to existing fontification. | |
688 (font-lock-append-text-property start end 'face | |
689 (eval (nth 1 highlight))))))) | |
690 | |
691 (defsubst font-lock-fontify-anchored-keywords (keywords limit) | |
692 "Fontify according to KEYWORDS until LIMIT. | |
693 KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords'." | |
694 (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights) | |
695 (eval (nth 1 keywords)) | |
696 (save-match-data | |
697 (while (if (stringp matcher) | |
698 (re-search-forward matcher limit t) | |
699 (funcall matcher limit)) | |
700 (setq highlights lowdarks) | |
701 (while highlights | |
702 (font-lock-apply-highlight (car highlights)) | |
703 (setq highlights (cdr highlights))))) | |
704 (eval (nth 2 keywords)))) | |
705 | |
706 (defun font-lock-fontify-keywords-region (start end &optional loudly) | |
707 "Fontify according to `font-lock-keywords' between START and END. | |
708 START should be at the beginning of a line." | |
709 (let ((case-fold-search font-lock-keywords-case-fold-search) | |
710 (keywords (cdr (if (eq (car-safe font-lock-keywords) t) | |
711 font-lock-keywords | |
712 (font-lock-compile-keywords)))) | |
713 (inhibit-read-only t) (buffer-undo-list t) | |
714 (modified (buffer-modified-p)) | |
715 (old-syntax (syntax-table)) | |
716 (bufname (buffer-name)) (count 0) | |
717 buffer-file-name buffer-file-truename) | |
718 (unwind-protect | |
719 (let (keyword matcher highlights) | |
720 ;; | |
721 ;; Use the fontification syntax table, if any. | |
722 (if font-lock-syntax-table (set-syntax-table font-lock-syntax-table)) | |
723 ;; | |
724 ;; Fontify each item in `font-lock-keywords' from `start' to `end'. | |
725 (while keywords | |
726 (if loudly (message "Fontifying %s... (regexps..%s)" bufname | |
727 (make-string (setq count (1+ count)) ?.))) | |
728 ;; | |
729 ;; Find an occurrence of `matcher' from `start' to `end'. | |
730 (setq keyword (car keywords) matcher (car keyword)) | |
731 (goto-char start) | |
732 (while (if (stringp matcher) | |
733 (re-search-forward matcher end t) | |
734 (funcall matcher end)) | |
735 ;; Apply each highlight to this instance of `matcher', which may | |
736 ;; be specific highlights or more keywords anchored to `matcher'. | |
737 (setq highlights (cdr keyword)) | |
738 (while highlights | |
739 (if (numberp (car (car highlights))) | |
740 (font-lock-apply-highlight (car highlights)) | |
741 (font-lock-fontify-anchored-keywords (car highlights) end)) | |
742 (setq highlights (cdr highlights)))) | |
743 (setq keywords (cdr keywords)))) | |
744 ;; | |
745 ;; Clean up. | |
746 (set-syntax-table old-syntax) | |
747 (and (buffer-modified-p) | |
748 (not modified) | |
749 (set-buffer-modified-p nil))))) | |
750 | |
751 ;; Various functions. | |
752 | |
753 ;; Turn off other related packages if they're on. I prefer a hook. --sm. | |
754 ;; These explicit calls are easier to understand | |
755 ;; because people know what they will do. | |
756 ;; A hook is a mystery because it might do anything whatever. --rms. | |
757 (defun font-lock-thing-lock-cleanup () | |
758 (cond ((and (boundp 'fast-lock-mode) fast-lock-mode) | |
759 (fast-lock-mode -1)) | |
760 ((and (boundp 'lazy-lock-mode) lazy-lock-mode) | |
761 (lazy-lock-mode -1)))) | |
762 | |
763 ;; Do something special for these packages after fontifying. I prefer a hook. | |
764 (defun font-lock-after-fontify-buffer () | |
765 (cond ((and (boundp 'fast-lock-mode) fast-lock-mode) | |
766 (fast-lock-after-fontify-buffer)) | |
767 ((and (boundp 'lazy-lock-mode) lazy-lock-mode) | |
768 (lazy-lock-after-fontify-buffer)))) | |
769 | |
770 ;; If the buffer is about to be reverted, it won't be fontified afterward. | |
771 (defun font-lock-revert-setup () | |
772 (setq font-lock-fontified nil)) | |
773 | |
774 ;; If the buffer has just been reverted, normally that turns off | |
775 ;; Font Lock mode. So turn the mode back on if necessary. | |
776 (defalias 'font-lock-revert-cleanup 'turn-on-font-lock) | |
777 | |
778 (defun font-lock-compile-keywords (&optional keywords) | |
779 ;; Compile `font-lock-keywords' into the form (t KEYWORD ...) where KEYWORD | |
780 ;; is the (MATCHER HIGHLIGHT ...) shown in the variable's doc string. | |
781 (let ((keywords (or keywords font-lock-keywords))) | |
782 (setq font-lock-keywords | |
783 (if (eq (car-safe keywords) t) | |
784 keywords | |
785 (cons t | |
786 (mapcar | |
787 (function (lambda (item) | |
788 (cond ((nlistp item) | |
789 (list item '(0 font-lock-keyword-face))) | |
790 ((numberp (cdr item)) | |
791 (list (car item) (list (cdr item) 'font-lock-keyword-face))) | |
792 ((symbolp (cdr item)) | |
793 (list (car item) (list 0 (cdr item)))) | |
794 ((nlistp (nth 1 item)) | |
795 (list (car item) (cdr item))) | |
796 (t | |
797 item)))) | |
798 keywords)))))) | |
799 | |
800 (defun font-lock-choose-keywords (keywords level) | |
801 ;; Return LEVELth element of KEYWORDS. A LEVEL of nil is equal to a | |
802 ;; LEVEL of 0, a LEVEL of t is equal to (1- (length KEYWORDS)). | |
803 (let ((level (if (not (consp level)) | |
804 level | |
805 (cdr (or (assq major-mode level) (assq t level)))))) | |
806 (cond ((symbolp keywords) | |
807 keywords) | |
808 ((numberp level) | |
809 (or (nth level keywords) (car (reverse keywords)))) | |
810 ((eq level t) | |
811 (car (reverse keywords))) | |
812 (t | |
813 (car keywords))))) | |
814 | |
815 (defun font-lock-set-defaults () | |
816 "Set fontification defaults appropriately for this mode. | |
817 Sets `font-lock-keywords', `font-lock-keywords-only', `font-lock-syntax-table', | |
818 `font-lock-beginning-of-syntax-function' and | |
819 `font-lock-keywords-case-fold-search' using `font-lock-defaults' (or, if nil, | |
820 using `font-lock-defaults-alist') and `font-lock-maximum-decoration'." | |
821 ;; Set face defaults. | |
822 (font-lock-make-faces) | |
823 ;; Set fontification defaults. | |
824 (or font-lock-keywords | |
825 (let* ((defaults (or font-lock-defaults | |
826 (cdr (assq major-mode font-lock-defaults-alist)))) | |
827 (keywords (font-lock-choose-keywords | |
828 (nth 0 defaults) font-lock-maximum-decoration))) | |
829 ;; Keywords? | |
830 (setq font-lock-keywords (if (fboundp keywords) | |
831 (funcall keywords) | |
832 (eval keywords))) | |
833 ;; Syntactic? | |
834 (if (nth 1 defaults) | |
835 (set (make-local-variable 'font-lock-keywords-only) t)) | |
836 ;; Case fold? | |
837 (if (nth 2 defaults) | |
838 (set (make-local-variable 'font-lock-keywords-case-fold-search) t)) | |
839 ;; Syntax table? | |
840 (if (nth 3 defaults) | |
841 (let ((slist (nth 3 defaults))) | |
842 (set (make-local-variable 'font-lock-syntax-table) | |
843 (copy-syntax-table (syntax-table))) | |
844 (while slist | |
845 (modify-syntax-entry (car (car slist)) (cdr (car slist)) | |
846 font-lock-syntax-table) | |
847 (setq slist (cdr slist))))) | |
848 ;; Syntax function? | |
849 (if (nth 4 defaults) | |
850 (set (make-local-variable 'font-lock-beginning-of-syntax-function) | |
851 (nth 4 defaults)))))) | |
219 | 852 |
220 ;; Colour etc. support. | 853 ;; Colour etc. support. |
221 | 854 |
222 (defvar font-lock-display-type nil | 855 (defvar font-lock-display-type nil |
223 "A symbol indicating the display Emacs is running under. | 856 "A symbol indicating the display Emacs is running under. |
390 (and (nth 4 face-attributes) (make-face-italic face nil t))) | 1023 (and (nth 4 face-attributes) (make-face-italic face nil t))) |
391 (or (funcall set-p face-name "Underline") | 1024 (or (funcall set-p face-name "Underline") |
392 (set-face-underline-p face (nth 5 face-attributes))) | 1025 (set-face-underline-p face (nth 5 face-attributes))) |
393 (set face face))) | 1026 (set face face))) |
394 | 1027 |
395 ;; Fontification. | 1028 ;;; Various regexp information shared by several modes. |
396 | |
397 ;; These variables record, for each buffer, the parse state at a particular | |
398 ;; position, always the start of a line. Used to make font-lock-fontify-region | |
399 ;; faster. | |
400 (defvar font-lock-cache-position nil) | |
401 (defvar font-lock-cache-state nil) | |
402 (make-variable-buffer-local 'font-lock-cache-position) | |
403 (make-variable-buffer-local 'font-lock-cache-state) | |
404 | |
405 (defun font-lock-fontify-region (start end &optional loudly) | |
406 "Put proper face on each string and comment between START and END." | |
407 (save-excursion | |
408 (save-restriction | |
409 (widen) | |
410 (goto-char start) | |
411 (beginning-of-line) | |
412 (if loudly (message "Fontifying %s... (syntactically...)" (buffer-name))) | |
413 (let ((inhibit-read-only t) (buffer-undo-list t) | |
414 buffer-file-name buffer-file-truename | |
415 (modified (buffer-modified-p)) | |
416 (old-syntax (syntax-table)) | |
417 (synstart (if comment-start-skip | |
418 (concat "\\s\"\\|" comment-start-skip) | |
419 "\\s\"")) | |
420 (comstart (if comment-start-skip | |
421 (concat "\\s<\\|" comment-start-skip) | |
422 "\\s<")) | |
423 (startline (point)) | |
424 state prev prevstate) | |
425 (unwind-protect | |
426 (progn | |
427 ;; | |
428 ;; Use the fontification syntax table, if any. | |
429 (if font-lock-syntax-table | |
430 (set-syntax-table font-lock-syntax-table)) | |
431 ;; | |
432 ;; Find the state at the `beginning-of-line' before `start'. | |
433 (if (eq startline font-lock-cache-position) | |
434 ;; Use the cache for the state of `startline'. | |
435 (setq state font-lock-cache-state) | |
436 ;; Find the state of `startline'. | |
437 (if (null font-lock-beginning-of-syntax-function) | |
438 ;; Use the state at the previous cache position, if any, or | |
439 ;; otherwise calculate from `point-min'. | |
440 (if (or (null font-lock-cache-position) | |
441 (< startline font-lock-cache-position)) | |
442 (setq state (parse-partial-sexp | |
443 (point-min) startline)) | |
444 (setq state (parse-partial-sexp | |
445 font-lock-cache-position startline | |
446 nil nil font-lock-cache-state))) | |
447 ;; Call the function to move outside any syntactic block. | |
448 (funcall font-lock-beginning-of-syntax-function) | |
449 (setq state (parse-partial-sexp (point) startline))) | |
450 ;; Cache the state and position of `startline'. | |
451 (setq font-lock-cache-state state | |
452 font-lock-cache-position startline)) | |
453 ;; | |
454 ;; Now find the state at `start' based on that of `startline'. | |
455 (setq state (parse-partial-sexp startline start nil nil state)) | |
456 ;; | |
457 ;; If the region starts inside a string, show the extent of it. | |
458 (if (nth 3 state) | |
459 (let ((beg (point))) | |
460 (while (and (re-search-forward "\\s\"" end 'move) | |
461 (nth 3 (parse-partial-sexp beg (point) nil nil | |
462 state)))) | |
463 (put-text-property beg (point) 'face font-lock-string-face) | |
464 (setq state (parse-partial-sexp beg (point) | |
465 nil nil state)))) | |
466 ;; | |
467 ;; Likewise for a comment. | |
468 (if (or (nth 4 state) (nth 7 state)) | |
469 (let ((beg (point))) | |
470 (save-restriction | |
471 (narrow-to-region (point-min) end) | |
472 (condition-case nil | |
473 (progn | |
474 (re-search-backward comstart (point-min) 'move) | |
475 (forward-comment 1) | |
476 ;; forward-comment skips all whitespace, | |
477 ;; so go back to the real end of the comment. | |
478 (skip-chars-backward " \t")) | |
479 (error (goto-char end)))) | |
480 (put-text-property beg (point) 'face | |
481 font-lock-comment-face) | |
482 (setq state (parse-partial-sexp beg (point) | |
483 nil nil state)))) | |
484 ;; | |
485 ;; Find each interesting place between here and `end'. | |
486 (while (and (< (point) end) | |
487 (setq prev (point) prevstate state) | |
488 (re-search-forward synstart end t) | |
489 (progn | |
490 ;; Clear out the fonts of what we skip over. | |
491 (remove-text-properties prev (point) '(face nil)) | |
492 ;; Verify the state at that place | |
493 ;; so we don't get fooled by \" or \;. | |
494 (setq state (parse-partial-sexp prev (point) | |
495 nil nil state)))) | |
496 (let ((here (point))) | |
497 (if (or (nth 4 state) (nth 7 state)) | |
498 ;; | |
499 ;; We found a real comment start. | |
500 (let ((beg (match-beginning 0))) | |
501 (goto-char beg) | |
502 (save-restriction | |
503 (narrow-to-region (point-min) end) | |
504 (condition-case nil | |
505 (progn | |
506 (forward-comment 1) | |
507 ;; forward-comment skips all whitespace, | |
508 ;; so go back to the real end of the comment. | |
509 (skip-chars-backward " \t")) | |
510 (error (goto-char end)))) | |
511 (put-text-property beg (point) 'face | |
512 font-lock-comment-face) | |
513 (setq state (parse-partial-sexp here (point) | |
514 nil nil state))) | |
515 (if (nth 3 state) | |
516 ;; | |
517 ;; We found a real string start. | |
518 (let ((beg (match-beginning 0))) | |
519 (while (and (re-search-forward "\\s\"" end 'move) | |
520 (nth 3 (parse-partial-sexp | |
521 here (point) nil nil state)))) | |
522 (put-text-property beg (point) 'face | |
523 font-lock-string-face) | |
524 (setq state (parse-partial-sexp here (point) | |
525 nil nil state)))))) | |
526 ;; | |
527 ;; Make sure `prev' is non-nil after the loop | |
528 ;; only if it was set on the very last iteration. | |
529 (setq prev nil))) | |
530 ;; | |
531 ;; Clean up. | |
532 (set-syntax-table old-syntax) | |
533 (and prev | |
534 (remove-text-properties prev end '(face nil))) | |
535 (and (buffer-modified-p) | |
536 (not modified) | |
537 (set-buffer-modified-p nil))))))) | |
538 | |
539 (defun font-lock-unfontify-region (beg end) | |
540 (let ((modified (buffer-modified-p)) | |
541 (buffer-undo-list t) (inhibit-read-only t) | |
542 buffer-file-name buffer-file-truename) | |
543 (remove-text-properties beg end '(face nil)) | |
544 (and (buffer-modified-p) | |
545 (not modified) | |
546 (set-buffer-modified-p nil)))) | |
547 | |
548 ;; Called when any modification is made to buffer text. | |
549 (defun font-lock-after-change-function (beg end old-len) | |
550 (save-excursion | |
551 (save-match-data | |
552 ;; Discard the cache info if text before it has changed. | |
553 (and font-lock-cache-position | |
554 (> font-lock-cache-position beg) | |
555 (setq font-lock-cache-position nil)) | |
556 ;; Rescan between start of line from `beg' and start of line after `end'. | |
557 (goto-char beg) | |
558 (beginning-of-line) | |
559 (setq beg (point)) | |
560 (goto-char end) | |
561 (forward-line 1) | |
562 (setq end (point)) | |
563 ;; First scan for strings and comments. | |
564 ;; Must scan from line start in case of | |
565 ;; inserting space into `intfoo () {}', and after widened. | |
566 (if font-lock-no-comments | |
567 (font-lock-unfontify-region beg end) | |
568 (font-lock-fontify-region beg end)) | |
569 ;; Now scan for keywords. | |
570 (font-lock-hack-keywords beg end)))) | |
571 | |
572 ;; The following must be rethought, since keywords can override fontification. | |
573 ; ;; Now scan for keywords, but not if we are inside a comment now. | |
574 ; (or (and (not font-lock-no-comments) | |
575 ; (let ((state (parse-partial-sexp beg end nil nil | |
576 ; font-lock-cache-state))) | |
577 ; (or (nth 4 state) (nth 7 state)))) | |
578 ; (font-lock-hack-keywords beg end)) | |
579 | |
580 ;;; Fontifying arbitrary patterns | |
581 | |
582 (defun font-lock-compile-keywords (&optional keywords) | |
583 ;; Compile `font-lock-keywords' into the form (t KEYWORD ...) where KEYWORD | |
584 ;; is the (MATCHER HIGHLIGHT ...) shown in the variable's doc string. | |
585 (let ((keywords (or keywords font-lock-keywords))) | |
586 (setq font-lock-keywords | |
587 (if (eq (car-safe keywords) t) | |
588 keywords | |
589 (cons t | |
590 (mapcar | |
591 (function (lambda (item) | |
592 (cond ((nlistp item) | |
593 (list item '(0 font-lock-keyword-face))) | |
594 ((numberp (cdr item)) | |
595 (list (car item) (list (cdr item) 'font-lock-keyword-face))) | |
596 ((symbolp (cdr item)) | |
597 (list (car item) (list 0 (cdr item)))) | |
598 ((nlistp (nth 1 item)) | |
599 (list (car item) (cdr item))) | |
600 (t | |
601 item)))) | |
602 keywords)))))) | |
603 | |
604 (defsubst font-lock-apply-highlight (highlight) | |
605 "Apply HIGHLIGHT following a match. See `font-lock-keywords'." | |
606 (let* ((match (nth 0 highlight)) | |
607 (beg (match-beginning match)) (end (match-end match)) | |
608 (override (nth 2 highlight))) | |
609 (cond ((not beg) | |
610 ;; No match but we might not signal an error | |
611 (or (nth 3 highlight) (error "Highlight %S failed" highlight))) | |
612 ((and (not override) (text-property-not-all beg end 'face nil)) | |
613 ;; Can't override and already fontified | |
614 nil) | |
615 ((not (eq override 'keep)) | |
616 ;; Can override but need not keep existing fontification | |
617 (put-text-property beg end 'face (eval (nth 1 highlight)))) | |
618 (t | |
619 ;; Can override but must keep existing fontification | |
620 (let ((pos (text-property-any beg end 'face nil)) next | |
621 (face (eval (nth 1 highlight)))) | |
622 (while pos | |
623 (setq next (next-single-property-change pos 'face nil end)) | |
624 (put-text-property pos next 'face face) | |
625 (setq pos (text-property-any next end 'face nil)))))))) | |
626 | |
627 (defun font-lock-hack-keywords (start end &optional loudly) | |
628 "Fontify according to `font-lock-keywords' between START and END." | |
629 (let ((case-fold-search font-lock-keywords-case-fold-search) | |
630 (keywords (cdr (if (eq (car-safe font-lock-keywords) t) | |
631 font-lock-keywords | |
632 (font-lock-compile-keywords)))) | |
633 (count 0) | |
634 (inhibit-read-only t) (buffer-undo-list t) | |
635 buffer-file-name buffer-file-truename | |
636 (modified (buffer-modified-p)) | |
637 (old-syntax (syntax-table)) | |
638 (bufname (buffer-name))) | |
639 (unwind-protect | |
640 (let (keyword matcher highlights lowdarks) | |
641 (if loudly (message "Fontifying %s... (regexps...)" bufname)) | |
642 (if font-lock-syntax-table (set-syntax-table font-lock-syntax-table)) | |
643 (while keywords | |
644 (setq keyword (car keywords) keywords (cdr keywords) | |
645 matcher (car keyword) highlights (cdr keyword)) | |
646 (goto-char start) | |
647 (while (if (stringp matcher) | |
648 (re-search-forward matcher end t) | |
649 (funcall matcher end)) | |
650 ;; An explicit `while' loop is slightly faster than a `mapcar'. | |
651 ;(mapcar 'font-lock-apply-highlight highlights) | |
652 (setq lowdarks highlights) | |
653 (while lowdarks | |
654 (font-lock-apply-highlight (car lowdarks)) | |
655 (setq lowdarks (cdr lowdarks)))) | |
656 (if loudly (message "Fontifying %s... (regexps...%s)" bufname | |
657 (make-string (setq count (1+ count)) ?.))))) | |
658 (set-syntax-table old-syntax) | |
659 (and (buffer-modified-p) | |
660 (not modified) | |
661 (set-buffer-modified-p nil))))) | |
662 | |
663 ;; The user level functions | |
664 | |
665 (defvar font-lock-mode nil) ; for modeline | |
666 | |
667 (defvar font-lock-fontified nil) ; whether we have hacked this buffer | |
668 (put 'font-lock-fontified 'permanent-local t) | |
669 | |
670 ;;;###autoload | |
671 (defun font-lock-mode (&optional arg) | |
672 "Toggle Font Lock mode. | |
673 With arg, turn Font Lock mode on if and only if arg is positive. | |
674 | |
675 When Font Lock mode is enabled, text is fontified as you type it: | |
676 | |
677 - Comments are displayed in `font-lock-comment-face'; | |
678 - Strings are displayed in `font-lock-string-face'; | |
679 - Certain other expressions are displayed in other faces according to the | |
680 value of the variable `font-lock-keywords'. | |
681 | |
682 You can enable Font Lock mode in any major mode automatically by turning on in | |
683 the major mode's hook. For example, put in your ~/.emacs: | |
684 | |
685 (add-hook 'c-mode-hook 'turn-on-font-lock) | |
686 | |
687 Or for any visited file with the following in your ~/.emacs: | |
688 | |
689 (add-hook 'find-file-hooks 'turn-on-font-lock) | |
690 | |
691 The default Font Lock mode faces and their attributes are defined in the | |
692 variable `font-lock-face-attributes', and Font Lock mode default settings in | |
693 the variable `font-lock-defaults-alist'. | |
694 | |
695 Where modes support different levels of fontification, you can use the variable | |
696 `font-lock-maximum-decoration' to specify which level you generally prefer. | |
697 When you turn Font Lock mode on/off the buffer is fontified/defontified, though | |
698 fontification occurs only if the buffer is less than `font-lock-maximum-size'. | |
699 To fontify a buffer without turning on Font Lock mode, and regardless of buffer | |
700 size, you can use \\[font-lock-fontify-buffer]." | |
701 (interactive "P") | |
702 (let ((on-p (if arg (> (prefix-numeric-value arg) 0) (not font-lock-mode)))) | |
703 (if (equal (buffer-name) " *Compiler Input*") ; hack for bytecomp... | |
704 (setq on-p nil)) | |
705 (if (not on-p) | |
706 (remove-hook 'after-change-functions 'font-lock-after-change-function) | |
707 (make-local-variable 'after-change-functions) | |
708 (add-hook 'after-change-functions 'font-lock-after-change-function)) | |
709 (set (make-local-variable 'font-lock-mode) on-p) | |
710 (cond (on-p | |
711 (font-lock-set-defaults) | |
712 (make-local-variable 'before-revert-hook) | |
713 (make-local-variable 'after-revert-hook) | |
714 ;; If buffer is reverted, must clean up the state. | |
715 (add-hook 'before-revert-hook 'font-lock-revert-setup) | |
716 (add-hook 'after-revert-hook 'font-lock-revert-cleanup) | |
717 (run-hooks 'font-lock-mode-hook) | |
718 (cond (font-lock-fontified | |
719 nil) | |
720 ((or (null font-lock-maximum-size) | |
721 (> font-lock-maximum-size (buffer-size))) | |
722 (font-lock-fontify-buffer)) | |
723 (font-lock-verbose | |
724 (message "Fontifying %s... buffer too big." (buffer-name))))) | |
725 (font-lock-fontified | |
726 (setq font-lock-fontified nil) | |
727 (remove-hook 'before-revert-hook 'font-lock-revert-setup) | |
728 (remove-hook 'after-revert-hook 'font-lock-revert-cleanup) | |
729 (font-lock-unfontify-region (point-min) (point-max)) | |
730 (font-lock-thing-lock-cleanup)) | |
731 (t | |
732 (remove-hook 'before-revert-hook 'font-lock-revert-setup) | |
733 (remove-hook 'after-revert-hook 'font-lock-revert-cleanup) | |
734 (font-lock-thing-lock-cleanup))) | |
735 (force-mode-line-update))) | |
736 | |
737 ;;;###autoload | |
738 (defun turn-on-font-lock () | |
739 "Unconditionally turn on Font Lock mode." | |
740 (font-lock-mode 1)) | |
741 | |
742 ;; Turn off other related packages if they're on. I prefer a hook. --sm. | |
743 ;; These explicit calls are easier to understand | |
744 ;; because people know what they will do. | |
745 ;; A hook is a mystery because it might do anything whatever. --rms. | |
746 (defun font-lock-thing-lock-cleanup () | |
747 (cond ((and (boundp 'fast-lock-mode) fast-lock-mode) | |
748 (fast-lock-mode -1)) | |
749 ((and (boundp 'lazy-lock-mode) lazy-lock-mode) | |
750 (lazy-lock-mode -1)))) | |
751 | |
752 ;; Do something special for these packages after fontifying. I prefer a hook. | |
753 (defun font-lock-after-fontify-buffer () | |
754 (cond ((and (boundp 'fast-lock-mode) fast-lock-mode) | |
755 (fast-lock-after-fontify-buffer)) | |
756 ((and (boundp 'lazy-lock-mode) lazy-lock-mode) | |
757 (lazy-lock-after-fontify-buffer)))) | |
758 | |
759 ;; If the buffer is about to be reverted, it won't be fontified afterward. | |
760 (defun font-lock-revert-setup () | |
761 (setq font-lock-fontified nil)) | |
762 | |
763 ;; If the buffer has just been reverted, normally that turns off | |
764 ;; Font Lock mode. So turn the mode back on if necessary. | |
765 (defun font-lock-revert-cleanup () | |
766 (font-lock-mode 1)) | |
767 | |
768 ;;;###autoload | |
769 (defun font-lock-fontify-buffer () | |
770 "Fontify the current buffer the way `font-lock-mode' would." | |
771 (interactive) | |
772 (let ((was-on font-lock-mode) | |
773 (verbose (and (or font-lock-verbose (interactive-p)) | |
774 (not (zerop (buffer-size))))) | |
775 (modified (buffer-modified-p))) | |
776 (set (make-local-variable 'font-lock-fontified) nil) | |
777 (if verbose (message "Fontifying %s..." (buffer-name))) | |
778 ;; Turn it on to run hooks and get the right `font-lock-keywords' etc. | |
779 (or was-on (font-lock-set-defaults)) | |
780 (condition-case nil | |
781 (save-excursion | |
782 (if font-lock-no-comments | |
783 (font-lock-unfontify-region (point-min) (point-max)) | |
784 (font-lock-fontify-region (point-min) (point-max) verbose)) | |
785 (font-lock-hack-keywords (point-min) (point-max) verbose) | |
786 (setq font-lock-fontified t)) | |
787 ;; We don't restore the old fontification, so it's best to unfontify. | |
788 (quit (font-lock-unfontify-region (point-min) (point-max)))) | |
789 (if verbose (message "Fontifying %s... %s." (buffer-name) | |
790 (if font-lock-fontified "done" "aborted"))) | |
791 (and (buffer-modified-p) | |
792 (not modified) | |
793 (set-buffer-modified-p nil)) | |
794 (font-lock-after-fontify-buffer))) | |
795 | |
796 (defun font-lock-choose-keywords (keywords level) | |
797 ;; Return LEVELth element of KEYWORDS. A LEVEL of nil is equal to a | |
798 ;; LEVEL of 0, a LEVEL of t is equal to (1- (length KEYWORDS)). | |
799 (cond ((symbolp keywords) | |
800 keywords) | |
801 ((numberp level) | |
802 (or (nth level keywords) (car (reverse keywords)))) | |
803 ((eq level t) | |
804 (car (reverse keywords))) | |
805 (t | |
806 (car keywords)))) | |
807 | |
808 (defun font-lock-set-defaults () | |
809 "Set fontification defaults appropriately for this mode. | |
810 Sets `font-lock-keywords', `font-lock-no-comments', `font-lock-syntax-table' | |
811 and `font-lock-keywords-case-fold-search' using `font-lock-defaults' (or, if | |
812 nil, using `font-lock-defaults-alist') and `font-lock-maximum-decoration'." | |
813 ;; Set face defaults. | |
814 (font-lock-make-faces) | |
815 ;; Set fontification defaults. | |
816 (or font-lock-keywords | |
817 (let ((defaults (or font-lock-defaults | |
818 (cdr (assq major-mode font-lock-defaults-alist))))) | |
819 ;; Keywords? | |
820 (setq font-lock-keywords | |
821 (font-lock-compile-keywords | |
822 (eval (font-lock-choose-keywords (nth 0 defaults) | |
823 font-lock-maximum-decoration)))) | |
824 ;; Syntactic? | |
825 (if (nth 1 defaults) | |
826 (set (make-local-variable 'font-lock-no-comments) t)) | |
827 ;; Case fold? | |
828 (if (nth 2 defaults) | |
829 (set (make-local-variable 'font-lock-keywords-case-fold-search) t)) | |
830 ;; Syntax table? | |
831 (if (nth 3 defaults) | |
832 (let ((slist (nth 3 defaults))) | |
833 (set (make-local-variable 'font-lock-syntax-table) | |
834 (copy-syntax-table (syntax-table))) | |
835 (while slist | |
836 (modify-syntax-entry (car (car slist)) (cdr (car slist)) | |
837 font-lock-syntax-table) | |
838 (setq slist (cdr slist))))) | |
839 ;; Syntactic cache function? | |
840 (if (nth 4 defaults) | |
841 (set (make-local-variable 'font-lock-beginning-of-syntax-function) | |
842 (nth 4 defaults)))))) | |
843 | |
844 ;;; Various information shared by several modes. | |
845 ;;; Information specific to a single mode should go in its load library. | 1029 ;;; Information specific to a single mode should go in its load library. |
846 | 1030 |
847 (defconst lisp-font-lock-keywords-1 | 1031 (defconst lisp-font-lock-keywords-1 |
848 (list | 1032 (list |
849 ;; Everything not a variable or type declaration is fontified as a function. | 1033 ;; Anything not a variable or type declaration is fontified as a function. |
850 ;; It would be cleaner to allow preceding whitespace, but it would also be | 1034 ;; It would be cleaner to allow preceding whitespace, but it would also be |
851 ;; about five times slower. | 1035 ;; about five times slower. |
852 (list (concat "^(\\(def\\(" | 1036 (list (concat "^(\\(def\\(" |
853 ;; Variable declarations. | 1037 ;; Variable declarations. |
854 "\\(const\\(\\|ant\\)\\|ine-key\\(\\|-after\\)\\|var\\)\\|" | 1038 "\\(const\\(\\|ant\\)\\|ine-key\\(\\|-after\\)\\|var\\)\\|" |
862 "\\([^ \t\n\)]+\\)?") | 1046 "\\([^ \t\n\)]+\\)?") |
863 '(1 font-lock-keyword-face) | 1047 '(1 font-lock-keyword-face) |
864 '(8 (cond ((match-beginning 3) font-lock-variable-name-face) | 1048 '(8 (cond ((match-beginning 3) font-lock-variable-name-face) |
865 ((match-beginning 6) font-lock-type-face) | 1049 ((match-beginning 6) font-lock-type-face) |
866 (t font-lock-function-name-face)) | 1050 (t font-lock-function-name-face)) |
867 nil t))) | 1051 nil t)) |
1052 ) | |
868 "Subdued level highlighting Lisp modes.") | 1053 "Subdued level highlighting Lisp modes.") |
869 | 1054 |
870 (defconst lisp-font-lock-keywords-2 | 1055 (defconst lisp-font-lock-keywords-2 |
871 (append lisp-font-lock-keywords-1 | 1056 (append lisp-font-lock-keywords-1 |
872 (let ((word-char "[-+a-zA-Z0-9_:*]")) | 1057 (list |
873 (list | 1058 ;; |
874 ;; | 1059 ;; Control structures. ELisp and CLisp combined. |
875 ;; Control structures. ELisp and CLisp combined. | |
876 ; (make-regexp | 1060 ; (make-regexp |
877 ; '("cond" "if" "while" "let\\*?" "prog[nv12*]?" "catch" "throw" | 1061 ; '("cond" "if" "while" "let\\*?" "prog[nv12*]?" "catch" "throw" |
878 ; "save-restriction" "save-excursion" "save-window-excursion" | 1062 ; "save-restriction" "save-excursion" "save-window-excursion" |
879 ; "save-selected-window" "save-match-data" "unwind-protect" | 1063 ; "save-selected-window" "save-match-data" "unwind-protect" |
880 ; "condition-case" "track-mouse" | 1064 ; "condition-case" "track-mouse" |
881 ; "eval-after-load" "eval-and-compile" "eval-when-compile" | 1065 ; "eval-after-load" "eval-and-compile" "eval-when-compile" |
882 ; "when" "unless" "do" "flet" "labels" "return" "return-from")) | 1066 ; "when" "unless" "do" "flet" "labels" "return" "return-from")) |
883 (cons | 1067 (cons |
884 (concat | 1068 (concat |
885 "(\\(" | 1069 "(\\(" |
886 "\\(c\\(atch\\|ond\\(\\|ition-case\\)\\)\\|do\\|" | 1070 "\\(c\\(atch\\|ond\\(\\|ition-case\\)\\)\\|do\\|" |
887 "eval-\\(a\\(fter-load\\|nd-compile\\)\\|when-compile\\)\\|flet\\|" | 1071 "eval-\\(a\\(fter-load\\|nd-compile\\)\\|when-compile\\)\\|flet\\|" |
888 "if\\|l\\(abels\\|et\\*?\\)\\|prog[nv12*]?\\|return\\(\\|-from\\)\\|" | 1072 "if\\|l\\(abels\\|et\\*?\\)\\|prog[nv12*]?\\|return\\(\\|-from\\)\\|" |
889 "save-\\(excursion\\|match-data\\|restriction\\|selected-window\\|" | 1073 "save-\\(excursion\\|match-data\\|restriction\\|selected-window\\|" |
890 "window-excursion\\)\\|t\\(hrow\\|rack-mouse\\)\\|" | 1074 "window-excursion\\)\\|t\\(hrow\\|rack-mouse\\)\\|" |
891 "un\\(less\\|wind-protect\\)\\|wh\\(en\\|ile\\)\\)" | 1075 "un\\(less\\|wind-protect\\)\\|wh\\(en\\|ile\\)\\)" |
892 "\\)\\>") 1) | 1076 "\\)\\>") 1) |
893 ;; | 1077 ;; |
894 ;; Function names in emacs-lisp docstrings (in the syntax that | 1078 ;; Words inside \\[] tend to be for `substitute-command-keys'. |
895 ;; `substitute-command-keys' understands). | 1079 '("\\\\\\\\\\[\\(\\sw+\\)]" 1 font-lock-reference-face prepend) |
896 (list (concat "\\\\\\\\\\[\\(" word-char "+\\)]") | 1080 ;; |
897 1 font-lock-reference-face t) | 1081 ;; Words inside `' tend to be symbol names. |
898 ;; | 1082 '("`\\(\\sw\\sw+\\)'" 1 font-lock-reference-face prepend) |
899 ;; Words inside `' which tend to be symbol names. | 1083 ;; |
900 (list (concat "`\\(" word-char word-char "+\\)'") | 1084 ;; CLisp `:' keywords as references. |
901 1 'font-lock-reference-face t) | 1085 '("\\<:\\sw+\\>" 0 font-lock-reference-face prepend) |
902 ;; | 1086 ;; |
903 ;; CLisp `:' keywords as references. | 1087 ;; ELisp and CLisp `&' keywords as types. |
904 (list (concat "\\<:" word-char "+\\>") 0 font-lock-reference-face t) | 1088 '("\\<\\&\\(optional\\|rest\\|whole\\)\\>" . font-lock-type-face) |
905 ;; | 1089 )) |
906 ;; ELisp and CLisp `&' keywords as types. | |
907 '("\\&\\(optional\\|rest\\|whole\\)\\>" . font-lock-type-face) | |
908 ))) | |
909 "Gaudy level highlighting for Lisp modes.") | 1090 "Gaudy level highlighting for Lisp modes.") |
910 | 1091 |
911 (defvar lisp-font-lock-keywords lisp-font-lock-keywords-1 | 1092 (defvar lisp-font-lock-keywords lisp-font-lock-keywords-1 |
912 "Default expressions to highlight in Lisp modes.") | 1093 "Default expressions to highlight in Lisp modes.") |
913 | 1094 |
914 | 1095 |
915 (defvar scheme-font-lock-keywords | 1096 (defvar scheme-font-lock-keywords |
916 (list | 1097 (eval-when-compile |
917 ;; | 1098 (list |
918 ;; Declarations. | 1099 ;; |
919 '("^[ \t]*(\\(define\\)\\>[ \t]*(?\\([^ \t\n\)]+\\)?" | 1100 ;; Declarations. Hannes Haug <hannes.haug@student.uni-tuebingen.de> says |
920 (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t)) | 1101 ;; this works for SOS, STklos, SCOOPS, Meroon and Tiny CLOS. |
921 ;; | 1102 (list (concat "(\\(define\\(" |
922 ;; Control structures. | 1103 ;; Function names. |
1104 "\\(\\|-\\(generic\\(\\|-procedure\\)\\|method\\)\\)\\|" | |
1105 ;; Macro names, as variable names. A bit dubious, this. | |
1106 "\\(-syntax\\)\\|" | |
1107 ;; Class names. | |
1108 "\\(-class\\)" | |
1109 "\\)\\)\\>" | |
1110 ;; Any whitespace and declared object. | |
1111 "[ \t]*(?" | |
1112 "\\(\\sw+\\)?") | |
1113 '(1 font-lock-keyword-face) | |
1114 '(8 (cond ((match-beginning 3) font-lock-function-name-face) | |
1115 ((match-beginning 6) font-lock-variable-name-face) | |
1116 (t font-lock-type-face)) | |
1117 nil t)) | |
1118 ;; | |
1119 ;; Control structures. | |
923 ;(make-regexp '("begin" "call-with-current-continuation" "call/cc" | 1120 ;(make-regexp '("begin" "call-with-current-continuation" "call/cc" |
924 ; "call-with-input-file" "call-with-output-file" "case" "cond" | 1121 ; "call-with-input-file" "call-with-output-file" "case" "cond" |
925 ; "define-syntax" "do" "else" "for-each" "if" "lambda" | 1122 ; "do" "else" "for-each" "if" "lambda" |
926 ; "let-syntax" "let\\*?" "letrec" "letrec-syntax" | 1123 ; "let\\*?" "let-syntax" "letrec" "letrec-syntax" |
927 ; ;; Stefan Monnier <stefan.monnier@epfl.ch> says don't bother. | 1124 ; ;; Hannes Haug <hannes.haug@student.uni-tuebingen.de> wants: |
1125 ; "and" "or" "delay" | |
1126 ; ;; Stefan Monnier <stefan.monnier@epfl.ch> says don't bother: | |
928 ; ;;"quasiquote" "quote" "unquote" "unquote-splicing" | 1127 ; ;;"quasiquote" "quote" "unquote" "unquote-splicing" |
929 ; "map" "syntax" "syntax-rules")) | 1128 ; "map" "syntax" "syntax-rules")) |
930 (cons | 1129 (cons |
931 (concat "(\\(" | 1130 (concat "(\\(" |
932 "begin\\|c\\(a\\(ll\\(-with-\\(current-continuation\\|" | 1131 "and\\|begin\\|c\\(a\\(ll\\(-with-\\(current-continuation\\|" |
933 "input-file\\|output-file\\)\\|/cc\\)\\|se\\)\\|ond\\)\\|" | 1132 "input-file\\|output-file\\)\\|/cc\\)\\|se\\)\\|ond\\)\\|" |
934 "d\\(efine-syntax\\|o\\)\\|else\\|for-each\\|if\\|" | 1133 "d\\(elay\\|o\\)\\|else\\|for-each\\|if\\|" |
935 "l\\(ambda\\|et\\(-syntax\\|\\*?\\|rec\\(\\|-syntax\\)\\)\\)\\|" | 1134 "l\\(ambda\\|et\\(-syntax\\|\\*?\\|rec\\(\\|-syntax\\)\\)\\)\\|" |
936 "map\\|syntax\\(\\|-rules\\)" | 1135 "map\\|or\\|syntax\\(\\|-rules\\)" |
937 "\\)\\>") 1)) | 1136 "\\)\\>") 1) |
938 "Default expressions to highlight in Scheme modes.") | 1137 ;; |
1138 ;; David Fox <fox@graphics.cs.nyu.edu> for SOS/STklos class specifiers. | |
1139 '("\\<<\\sw+>\\>" . font-lock-type-face) | |
1140 ;; | |
1141 ;; Scheme `:' keywords as references. | |
1142 '("\\<:\\sw+\\>" . font-lock-reference-face) | |
1143 )) | |
1144 "Default expressions to highlight in Scheme modes.") | |
939 | 1145 |
940 | 1146 |
941 (defconst c-font-lock-keywords-1 nil | 1147 (defconst c-font-lock-keywords-1 nil |
942 "Subdued level highlighting for C modes.") | 1148 "Subdued level highlighting for C modes.") |
943 | 1149 |
944 (defconst c-font-lock-keywords-2 nil | 1150 (defconst c-font-lock-keywords-2 nil |
1151 "Medium level highlighting for C modes.") | |
1152 | |
1153 (defconst c-font-lock-keywords-3 nil | |
945 "Gaudy level highlighting for C modes.") | 1154 "Gaudy level highlighting for C modes.") |
946 | 1155 |
947 (defconst c++-font-lock-keywords-1 nil | 1156 (defconst c++-font-lock-keywords-1 nil |
948 "Subdued level highlighting for C++ modes.") | 1157 "Subdued level highlighting for C++ modes.") |
949 | 1158 |
950 (defconst c++-font-lock-keywords-2 nil | 1159 (defconst c++-font-lock-keywords-2 nil |
1160 "Medium level highlighting for C++ modes.") | |
1161 | |
1162 (defconst c++-font-lock-keywords-3 nil | |
951 "Gaudy level highlighting for C++ modes.") | 1163 "Gaudy level highlighting for C++ modes.") |
1164 | |
1165 (defun font-lock-match-c++-style-declaration-item-and-skip-to-next (limit) | |
1166 ;; Match, and move over, any declaration/definition item after point. | |
1167 ;; The expect syntax of an item is "word" or "word::word", possibly ending | |
1168 ;; with optional whitespace and a "(". Everything following the item (but | |
1169 ;; belonging to it) is expected to by skip-able by `forward-sexp', and items | |
1170 ;; are expected to be separated with a "," or ";". | |
1171 (if (looking-at "[ \t*&]*\\(\\sw+\\)\\(::\\(\\sw+\\)\\)?[ \t]*\\((\\)?") | |
1172 (save-match-data | |
1173 (condition-case nil | |
1174 (save-restriction | |
1175 ;; Restrict ourselves to the end of the line. | |
1176 (end-of-line) | |
1177 (narrow-to-region (point-min) (min limit (point))) | |
1178 (goto-char (match-end 1)) | |
1179 ;; Move over any item value, etc., to the next item. | |
1180 (while (not (looking-at "[ \t]*\\([,;]\\|$\\)")) | |
1181 (goto-char (or (scan-sexps (point) 1) (point-max)))) | |
1182 (goto-char (match-end 0))) | |
1183 (error t))))) | |
952 | 1184 |
953 (let ((c-keywords | 1185 (let ((c-keywords |
954 ; ("break" "continue" "do" "else" "for" "if" "return" "switch" "while") | 1186 ; ("break" "continue" "do" "else" "for" "if" "return" "switch" "while") |
955 "break\\|continue\\|do\\|else\\|for\\|if\\|return\\|switch\\|while") | 1187 "break\\|continue\\|do\\|else\\|for\\|if\\|return\\|switch\\|while") |
956 (c-type-types | 1188 (c-type-types |
964 (c++-keywords | 1196 (c++-keywords |
965 ; ("break" "continue" "do" "else" "for" "if" "return" "switch" "while" | 1197 ; ("break" "continue" "do" "else" "for" "if" "return" "switch" "while" |
966 ; "asm" "catch" "delete" "new" "operator" "sizeof" "this" "throw" "try" | 1198 ; "asm" "catch" "delete" "new" "operator" "sizeof" "this" "throw" "try" |
967 ; "protected" "private" "public") | 1199 ; "protected" "private" "public") |
968 (concat "asm\\|break\\|c\\(atch\\|ontinue\\)\\|d\\(elete\\|o\\)\\|" | 1200 (concat "asm\\|break\\|c\\(atch\\|ontinue\\)\\|d\\(elete\\|o\\)\\|" |
969 "else\\|for\\|if\\|new\\|operator\\|" | 1201 "else\\|for\\|if\\|new\\|" |
970 "p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|return\\|" | 1202 "p\\(r\\(ivate\\|otected\\)\\|ublic\\)\\|return\\|" |
971 "s\\(izeof\\|witch\\)\\|t\\(h\\(is\\|row\\)\\|ry\\)\\|while")) | 1203 "s\\(izeof\\|witch\\)\\|t\\(h\\(is\\|row\\)\\|ry\\)\\|while")) |
972 (c++-type-types | 1204 (c++-type-types |
973 ; ("auto" "extern" "register" "static" "typedef" "struct" "union" "enum" | 1205 ; ("auto" "extern" "register" "static" "typedef" "struct" "union" "enum" |
974 ; "signed" "unsigned" "short" "long" "int" "char" "float" "double" | 1206 ; "signed" "unsigned" "short" "long" "int" "char" "float" "double" |
978 "double\\|e\\(num\\|xtern\\)\\|f\\(loat\\|riend\\)\\|" | 1210 "double\\|e\\(num\\|xtern\\)\\|f\\(loat\\|riend\\)\\|" |
979 "in\\(line\\|t\\)\\|long\\|register\\|" | 1211 "in\\(line\\|t\\)\\|long\\|register\\|" |
980 "s\\(hort\\|igned\\|t\\(atic\\|ruct\\)\\)\\|" | 1212 "s\\(hort\\|igned\\|t\\(atic\\|ruct\\)\\)\\|" |
981 "t\\(emplate\\|ypedef\\)\\|un\\(ion\\|signed\\)\\|" | 1213 "t\\(emplate\\|ypedef\\)\\|un\\(ion\\|signed\\)\\|" |
982 "v\\(irtual\\|o\\(id\\|latile\\)\\)")) ; 11 ()s deep. | 1214 "v\\(irtual\\|o\\(id\\|latile\\)\\)")) ; 11 ()s deep. |
983 (ctoken "[a-zA-Z0-9_:~]+")) | 1215 ) |
984 (setq c-font-lock-keywords-1 | 1216 (setq c-font-lock-keywords-1 |
985 (list | 1217 (list |
986 ;; | 1218 ;; |
987 ;; Fontify filenames in #include <...> preprocessor directives. | 1219 ;; These are all anchored at the beginning of line for speed. |
1220 ;; | |
1221 ;; Fontify function name definitions (GNU style; without type on line). | |
1222 (list (concat "^\\(\\sw+\\)[ \t]*(") 1 'font-lock-function-name-face) | |
1223 ;; | |
1224 ;; Fontify filenames in #include <...> preprocessor directives as strings. | |
988 '("^#[ \t]*include[ \t]+\\(<[^>\"\n]+>\\)" 1 font-lock-string-face) | 1225 '("^#[ \t]*include[ \t]+\\(<[^>\"\n]+>\\)" 1 font-lock-string-face) |
989 ;; | 1226 ;; |
990 ;; Fontify function macro names. | 1227 ;; Fontify function macro names. |
991 '("^#[ \t]*define[ \t]+\\(\\(\\sw+\\)(\\)" 2 font-lock-function-name-face) | 1228 '("^#[ \t]*define[ \t]+\\(\\(\\sw+\\)(\\)" 2 font-lock-function-name-face) |
992 ;; | 1229 ;; |
1230 ;; Fontify symbol names in #if ... defined preprocessor directives. | |
1231 '("^#[ \t]*if\\>" | |
1232 ("\\<\\(defined\\)\\>[ \t]*(?\\(\\sw+\\)?" nil nil | |
1233 (1 font-lock-reference-face) (2 font-lock-variable-name-face nil t))) | |
1234 ;; | |
993 ;; Fontify otherwise as symbol names, and the preprocessor directive names. | 1235 ;; Fontify otherwise as symbol names, and the preprocessor directive names. |
994 '("^\\(#[ \t]*[a-z]+\\)\\>[ \t]*\\(\\sw+\\)?" | 1236 '("^\\(#[ \t]*[a-z]+\\)\\>[ \t]*\\(\\sw+\\)?" |
995 (1 font-lock-reference-face) (2 font-lock-variable-name-face nil t)) | 1237 (1 font-lock-reference-face) (2 font-lock-variable-name-face nil t)) |
996 ;; | |
997 ;; Fontify function name definitions (without type on line). | |
998 (list (concat "^\\(" ctoken "\\)[ \t]*(") 1 'font-lock-function-name-face) | |
999 )) | 1238 )) |
1000 | 1239 |
1001 (setq c-font-lock-keywords-2 | 1240 (setq c-font-lock-keywords-2 |
1002 (append c-font-lock-keywords-1 | 1241 (append c-font-lock-keywords-1 |
1003 (list | 1242 (list |
1004 ;; | 1243 ;; |
1005 ;; Fontify all storage classes and type specifiers (before declarations). | 1244 ;; Simple regexps for speed. |
1245 ;; | |
1246 ;; Fontify all type specifiers. | |
1006 (cons (concat "\\<\\(" c-type-types "\\)\\>") 'font-lock-type-face) | 1247 (cons (concat "\\<\\(" c-type-types "\\)\\>") 'font-lock-type-face) |
1007 ;; | 1248 ;; |
1008 ;; Fontify variable/structure name declarations and definitions, or | |
1009 ;; function name declarations (plus definitions with type on same line). | |
1010 (list (concat "\\<\\(" c-type-types "\\)[ \t*]+" | |
1011 "\\(" ctoken "[ \t*]+\\)*" | |
1012 "\\(" ctoken "\\)[ \t]*\\((\\)?") | |
1013 9 | |
1014 '(if (match-beginning 10) | |
1015 font-lock-function-name-face | |
1016 font-lock-variable-name-face)) | |
1017 ;; | |
1018 ;; Fontify function/variable name declarations at the start of the line. | |
1019 ;; (Not everyone follows the GNU convention of function name at the start.) | |
1020 (list (concat "^" ctoken "[ \t*]+" | |
1021 "\\(" ctoken "[ \t*]+\\)*" | |
1022 "\\(" ctoken "\\)[ \t]*\\((\\)?") | |
1023 2 | |
1024 '(if (match-beginning 3) | |
1025 font-lock-function-name-face | |
1026 font-lock-variable-name-face)) | |
1027 ;; | |
1028 ;; Fontify variable names declared with structures, or typedef names. | |
1029 '("}[ \t*]*\\(\\sw+\\)[ \t]*[;,[]" 1 font-lock-variable-name-face) | |
1030 ;; | |
1031 ;; Fontify all builtin keywords (except case, default and goto; see below). | 1249 ;; Fontify all builtin keywords (except case, default and goto; see below). |
1032 (concat "\\<\\(" c-keywords "\\)\\>") | 1250 (cons (concat "\\<\\(" c-keywords "\\)\\>") 'font-lock-keyword-face) |
1033 ;; | 1251 ;; |
1034 ;; Fontify case/goto keywords and targets, and goto tags (incl "default:"). | 1252 ;; Fontify case/goto keywords and targets, and case default/goto tags. |
1035 '("\\<\\(case\\|goto\\)\\>[ \t]*\\([^ \t\n:;]+\\)?" | 1253 '("\\<\\(case\\|goto\\)\\>[ \t]*\\([^ \t\n:;]+\\)?" |
1036 (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)) | 1254 (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)) |
1037 '("^[ \t]*\\(\\sw+\\)[ \t]*:" 1 font-lock-reference-face) | 1255 '("^[ \t]*\\(\\sw+\\)[ \t]*:" 1 font-lock-reference-face) |
1038 ))) | 1256 ))) |
1039 | 1257 |
1040 (setq c++-font-lock-keywords-1 c-font-lock-keywords-1) | 1258 (setq c-font-lock-keywords-3 |
1259 (append c-font-lock-keywords-2 | |
1260 ;; | |
1261 ;; More complicated regexps for more complete highlighting for types. | |
1262 ;; We still have to fontify type specifiers individually, as C is so hairy. | |
1263 (list | |
1264 ;; | |
1265 ;; Fontify all storage classes and type specifiers, plus their items. | |
1266 (list (concat "\\<\\(" c-type-types "\\)\\>" | |
1267 "\\([ \t*&]+\\sw+\\>\\)*") | |
1268 ;; Fontify each declaration item. | |
1269 '(font-lock-match-c++-style-declaration-item-and-skip-to-next | |
1270 ;; Start with point after all type specifiers. | |
1271 (goto-char (or (match-beginning 8) (match-end 1))) | |
1272 ;; Finish with point after first type specifier. | |
1273 (goto-char (match-end 1)) | |
1274 ;; Fontify as a variable or function name. | |
1275 (1 (if (match-beginning 4) | |
1276 font-lock-function-name-face | |
1277 font-lock-variable-name-face)))) | |
1278 ;; | |
1279 ;; Fontify structures, or typedef names, plus their items. | |
1280 '("\\(}\\)[ \t*]*\\sw" | |
1281 (font-lock-match-c++-style-declaration-item-and-skip-to-next | |
1282 (goto-char (match-end 1)) nil | |
1283 (1 (if (match-beginning 4) | |
1284 font-lock-function-name-face | |
1285 font-lock-variable-name-face)))) | |
1286 ;; | |
1287 ;; Fontify anything at beginning of line as a declaration or definition. | |
1288 '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*" | |
1289 (1 font-lock-type-face) | |
1290 (font-lock-match-c++-style-declaration-item-and-skip-to-next | |
1291 (goto-char (or (match-beginning 2) (match-end 1))) nil | |
1292 (1 (if (match-beginning 4) | |
1293 font-lock-function-name-face | |
1294 font-lock-variable-name-face)))) | |
1295 ))) | |
1296 | |
1297 (setq c++-font-lock-keywords-1 | |
1298 (append | |
1299 ;; | |
1300 ;; The list `c-font-lock-keywords-1' less that for function names. | |
1301 (cdr c-font-lock-keywords-1) | |
1302 ;; | |
1303 ;; Fontify function name definitions, possibly incorporating class name. | |
1304 (list | |
1305 '("^\\(\\sw+\\)\\(::\\(\\sw+\\)\\)?[ \t]*(" | |
1306 (1 (if (match-beginning 2) | |
1307 font-lock-type-face | |
1308 font-lock-function-name-face)) | |
1309 (3 (if (match-beginning 2) font-lock-function-name-face) nil t)) | |
1310 ))) | |
1311 | |
1041 (setq c++-font-lock-keywords-2 | 1312 (setq c++-font-lock-keywords-2 |
1042 (append c++-font-lock-keywords-1 | 1313 (append c++-font-lock-keywords-1 |
1043 (list | 1314 (list |
1044 ;; We don't just add to the C keywords for subtle differences and speed. | 1315 ;; |
1045 ;; See the above comments for `c-font-lock-keywords-2'. | 1316 ;; The list `c-font-lock-keywords-2' for C++ plus operator overloading. |
1046 (cons (concat "\\<\\(" c++-type-types "\\)\\>") 'font-lock-type-face) | 1317 (cons (concat "\\<\\(" c++-type-types "\\)\\>") 'font-lock-type-face) |
1047 (list (concat "\\<\\(" c++-type-types "\\)[ \t*&]+" | 1318 ;; |
1048 "\\(" ctoken "[ \t*&]+\\)*" | 1319 ;; Fontify operator function name overloading. |
1049 "\\(" ctoken "\\)[ \t<>=!+-]*\\((\\)?") | 1320 '("\\<\\(operator\\)\\>[ \t]*\\([][)(><!=+-][][)(><!=+-]?\\)?" |
1050 14 | 1321 (1 font-lock-keyword-face) (2 font-lock-function-name-face nil t)) |
1051 '(if (match-beginning 15) | 1322 ;; |
1052 font-lock-function-name-face | 1323 ;; Fontify case/goto keywords and targets, and case default/goto tags. |
1053 font-lock-variable-name-face)) | |
1054 (list (concat "^" ctoken "[ \t*]+" | |
1055 "\\(" ctoken "[ \t*]+\\)*" | |
1056 "\\(" ctoken "\\)[ \t<>=!+-]*\\((\\)?") | |
1057 2 | |
1058 '(if (match-beginning 3) | |
1059 font-lock-function-name-face | |
1060 font-lock-variable-name-face)) | |
1061 '("}[ \t*]*\\(\\sw+\\)[ \t]*[;,[]" 1 font-lock-variable-name-face) | |
1062 (concat "\\<\\(" c++-keywords "\\)\\>") | |
1063 '("\\<\\(case\\|goto\\)\\>[ \t]*\\([^ \t\n:;]+\\)?" | 1324 '("\\<\\(case\\|goto\\)\\>[ \t]*\\([^ \t\n:;]+\\)?" |
1064 (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)) | 1325 (1 font-lock-keyword-face) (2 font-lock-reference-face nil t)) |
1065 '("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-reference-face)))) | 1326 '("^[ \t]*\\(\\sw+\\)[ \t]*:[^:]" 1 font-lock-reference-face) |
1327 ;; | |
1328 ;; Fontify other builtin keywords. | |
1329 (cons (concat "\\<\\(" c++-keywords "\\)\\>") 'font-lock-keyword-face) | |
1330 ))) | |
1331 | |
1332 (setq c++-font-lock-keywords-3 | |
1333 (append c++-font-lock-keywords-2 | |
1334 ;; | |
1335 ;; More complicated regexps for more complete highlighting for types. | |
1336 (list | |
1337 ;; | |
1338 ;; Fontify all storage classes and type specifiers, plus their items. | |
1339 (list (concat "\\<\\(" c++-type-types "\\)\\>" | |
1340 "\\([ \t*&]+\\sw+\\>\\)*") | |
1341 ;; Fontify each declaration item. | |
1342 '(font-lock-match-c++-style-declaration-item-and-skip-to-next | |
1343 ;; Start with point after all type specifiers. | |
1344 (goto-char (or (match-beginning 13) (match-end 1))) | |
1345 ;; Finish with point after first type specifier. | |
1346 (goto-char (match-end 1)) | |
1347 ;; Fontify as a variable or function name. | |
1348 (1 (cond ((match-beginning 2) font-lock-type-face) | |
1349 ((match-beginning 4) font-lock-function-name-face) | |
1350 (t font-lock-variable-name-face))) | |
1351 (3 (if (match-beginning 4) | |
1352 font-lock-function-name-face | |
1353 font-lock-variable-name-face) nil t))) | |
1354 ;; | |
1355 ;; Fontify structures, or typedef names, plus their items. | |
1356 '("\\(}\\)[ \t*]*\\sw" | |
1357 (font-lock-match-c++-style-declaration-item-and-skip-to-next | |
1358 (goto-char (match-end 1)) nil | |
1359 (1 (if (match-beginning 4) | |
1360 font-lock-function-name-face | |
1361 font-lock-variable-name-face)))) | |
1362 ;; | |
1363 ;; Fontify anything at beginning of line as a declaration or definition. | |
1364 '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*" | |
1365 (1 font-lock-type-face) | |
1366 (font-lock-match-c++-style-declaration-item-and-skip-to-next | |
1367 (goto-char (or (match-beginning 2) (match-end 1))) nil | |
1368 (1 (cond ((match-beginning 2) font-lock-type-face) | |
1369 ((match-beginning 4) font-lock-function-name-face) | |
1370 (t font-lock-variable-name-face))) | |
1371 (3 (if (match-beginning 4) | |
1372 font-lock-function-name-face | |
1373 font-lock-variable-name-face) nil t))) | |
1374 ))) | |
1066 ) | 1375 ) |
1067 | 1376 |
1068 (defvar c-font-lock-keywords c-font-lock-keywords-1 | 1377 (defvar c-font-lock-keywords c-font-lock-keywords-1 |
1069 "Default expressions to highlight in C mode.") | 1378 "Default expressions to highlight in C mode.") |
1070 | 1379 |
1088 '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}" | 1397 '(("\\\\\\(begin\\|end\\|newcommand\\){\\([a-zA-Z0-9\\*]+\\)}" |
1089 2 font-lock-function-name-face) | 1398 2 font-lock-function-name-face) |
1090 ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}" | 1399 ("\\\\\\(cite\\|label\\|pageref\\|ref\\){\\([^} \t\n]+\\)}" |
1091 2 font-lock-reference-face) | 1400 2 font-lock-reference-face) |
1092 ("^[ \t]*\\\\def\\\\\\(\\(\\w\\|@\\)+\\)" 1 font-lock-function-name-face) | 1401 ("^[ \t]*\\\\def\\\\\\(\\(\\w\\|@\\)+\\)" 1 font-lock-function-name-face) |
1093 ("\\\\\\([a-zA-Z@]+\\|.\\)" . font-lock-keyword-face) | 1402 "\\\\\\([a-zA-Z@]+\\|.\\)" |
1094 ;; It seems a bit dubious to use `bold' and `italic' faces since we might | 1403 ;; It seems a bit dubious to use `bold' and `italic' faces since we might |
1095 ;; not be able to display those fonts. | 1404 ;; not be able to display those fonts. |
1096 ;; LaTeX2e: \emph{This is emphasized}. | 1405 ;; LaTeX2e: \emph{This is emphasized}. |
1097 ("\\\\emph{\\([^}]+\\)}" 1 'italic keep) | 1406 ("\\\\emph{\\([^}]+\\)}" 1 'italic keep) |
1098 ;; LaTeX2e: \textbf{This is bold}, \textit{...}, \textsl{...} | 1407 ;; LaTeX2e: \textbf{This is bold}, \textit{...}, \textsl{...} |
1099 ("\\\\text\\(\\(bf\\)\\|it\\|sl\\){\\([^}]+\\)}" | 1408 ("\\\\text\\(\\(bf\\)\\|it\\|sl\\){\\([^}]+\\)}" |
1100 3 (if (match-beginning 2) 'bold 'italic) keep) | 1409 3 (if (match-beginning 2) 'bold 'italic) keep) |
1101 ;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for good tables. | 1410 ;; Old-style bf/em/it/sl. Stop at `\\' and un-escaped `&', for good tables. |
1102 ("\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)" | 1411 ("\\\\\\(\\(bf\\)\\|em\\|it\\|sl\\)\\>\\(\\([^}&\\]\\|\\\\[^\\]\\)+\\)" |
1103 3 (if (match-beginning 2) 'bold 'italic) keep)) | 1412 3 (if (match-beginning 2) 'bold 'italic) keep)) |
1104 "Additional expressions to highlight in TeX modes.") | 1413 "Default expressions to highlight in TeX modes.") |
1105 | 1414 |
1106 ;; Install ourselves: | 1415 ;; Install ourselves: |
1107 | 1416 |
1108 (or (assq 'font-lock-mode minor-mode-alist) | 1417 (or (assq 'font-lock-mode minor-mode-alist) |
1109 (setq minor-mode-alist (cons '(font-lock-mode " Font") minor-mode-alist))) | 1418 (setq minor-mode-alist (cons '(font-lock-mode " Font") minor-mode-alist))) |