diff options
| author | Simon Marshall | 1995-10-26 13:27:36 +0000 |
|---|---|---|
| committer | Simon Marshall | 1995-10-26 13:27:36 +0000 |
| commit | 9bfbb130d94c1f2a03bba82a8d46b19d4c879825 (patch) | |
| tree | b3b2cd6a240abe231fd2beea49583cca1a4dd99e | |
| parent | a9132c1f5f236d9088b2c09e3cdf4c58bd0cd674 (diff) | |
| download | emacs-9bfbb130d94c1f2a03bba82a8d46b19d4c879825.tar.gz emacs-9bfbb130d94c1f2a03bba82a8d46b19d4c879825.zip | |
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.
| -rw-r--r-- | lisp/font-lock.el | 1579 |
1 files changed, 944 insertions, 635 deletions
diff --git a/lisp/font-lock.el b/lisp/font-lock.el index 7ff0acd69a4..d64ca17e24b 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el | |||
| @@ -1,7 +1,7 @@ | |||
| 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 | ||
| @@ -30,22 +30,19 @@ | |||
| 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': |
| @@ -58,31 +55,83 @@ | |||
| 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. | ||
| 83 | |||
| 84 | ;; User variables. | ||
| 85 | |||
| 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.") | ||
| 61 | 111 | ||
| 62 | ;;; Code: | 112 | ;; Fontification variables: |
| 63 | 113 | ||
| 64 | (defvar font-lock-comment-face 'font-lock-comment-face | 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 | |||
| 79 | (defvar font-lock-type-face 'font-lock-type-face | ||
| 80 | "Face to use for data types.") | ||
| 81 | 131 | ||
| 82 | (defvar font-lock-reference-face 'font-lock-reference-face | 132 | (defvar font-lock-reference-face 'font-lock-reference-face |
| 83 | "Face to use for references.") | 133 | "Face to use for reference names.") |
| 84 | 134 | ||
| 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: |
| @@ -93,57 +142,111 @@ Each element should be of the form: | |||
| 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. |
| 106 | 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. | ||
| 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) |
| @@ -154,31 +257,33 @@ The value should look like the `cdr' of an item in `font-lock-defaults-alist'.") | |||
| 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 | ||
| @@ -191,31 +296,559 @@ This is normally set via `font-lock-defaults'.") | |||
| 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. |
| 308 | (defvar font-lock-cache-position nil) | ||
| 309 | (defvar font-lock-cache-state nil) | ||
| 310 | (make-variable-buffer-local 'font-lock-cache-position) | ||
| 311 | (make-variable-buffer-local 'font-lock-cache-state) | ||
| 312 | |||
| 313 | (defvar font-lock-mode nil) ; For the modeline. | ||
| 314 | (defvar font-lock-fontified nil) ; Whether we have fontified the buffer. | ||
| 315 | (put 'font-lock-fontified 'permanent-local t) | ||
| 201 | 316 | ||
| 202 | ;;;###autoload | 317 | ;;;###autoload |
| 203 | (defvar font-lock-maximum-decoration nil | 318 | (defvar font-lock-mode-hook nil |
| 204 | "*If non-nil, the maximum decoration for fontifying. | 319 | "Function or functions to run on entry to Font Lock mode.") |
| 205 | If nil, use the default decoration (typically the minimum available). | 320 | |
| 206 | If t, use the maximum decoration available. | 321 | ;; User functions. |
| 207 | If a number, use that level of decoration (or if not available the maximum).") | ||
| 208 | 322 | ||
| 209 | ;;;###autoload | 323 | ;;;###autoload |
| 210 | (defvar font-lock-maximum-size | 324 | (defun font-lock-mode (&optional arg) |
| 211 | (if font-lock-maximum-decoration (* 150 1024) (* 300 1024)) | 325 | "Toggle Font Lock mode. |
| 212 | "*If non-nil, the maximum size for buffers for fontifying. | 326 | With arg, turn Font Lock mode on if and only if arg is positive. |
| 213 | Only buffers less than this can be fontified when Font Lock mode is turned on. | 327 | |
| 214 | If nil, means size is irrelevant.") | 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))) | ||
| 215 | 394 | ||
| 216 | ;;;###autoload | 395 | ;;;###autoload |
| 217 | (defvar font-lock-mode-hook nil | 396 | (defun turn-on-font-lock () |
| 218 | "Function or functions to run on entry to Font Lock mode.") | 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 | ||
| @@ -392,461 +1025,12 @@ the face is also set; its value is the face name." | |||
| 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\\(" |
| @@ -864,15 +1048,15 @@ nil, using `font-lock-defaults-alist') and `font-lock-maximum-decoration'." | |||
| 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" |
| @@ -880,32 +1064,29 @@ nil, using `font-lock-defaults-alist') and `font-lock-maximum-decoration'." | |||
| 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 |
| @@ -913,43 +1094,94 @@ nil, using `font-lock-defaults-alist') and `font-lock-maximum-decoration'." | |||
| 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.") |
| 952 | 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))))) | ||
| 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") |
| @@ -966,7 +1198,7 @@ nil, using `font-lock-defaults-alist') and `font-lock-maximum-decoration'." | |||
| 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 |
| @@ -980,89 +1212,166 @@ nil, using `font-lock-defaults-alist') and `font-lock-maximum-decoration'." | |||
| 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. |
| 1006 | (cons (concat "\\<\\(" c-type-types "\\)\\>") 'font-lock-type-face) | ||
| 1007 | ;; | ||
| 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 | ;; | 1245 | ;; |
| 1018 | ;; Fontify function/variable name declarations at the start of the line. | 1246 | ;; Fontify all type specifiers. |
| 1019 | ;; (Not everyone follows the GNU convention of function name at the start.) | 1247 | (cons (concat "\\<\\(" c-type-types "\\)\\>") 'font-lock-type-face) |
| 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 | ;; | 1248 | ;; |
| 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 |
| @@ -1090,7 +1399,7 @@ nil, using `font-lock-defaults-alist') and `font-lock-maximum-decoration'." | |||
| 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}. |
| @@ -1101,7 +1410,7 @@ nil, using `font-lock-defaults-alist') and `font-lock-maximum-decoration'." | |||
| 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 | ||