comparison lisp/font-lock.el @ 460:223736d75acb r21-2-45

Import from CVS: tag r21-2-45
author cvs
date Mon, 13 Aug 2007 11:43:24 +0200
parents 3078fd1074e8
children 0784d089fdc9
comparison
equal deleted inserted replaced
459:9d4fd877b885 460:223736d75acb
311 (radio :tag "Size" 311 (radio :tag "Size"
312 (const :tag "none" nil) 312 (const :tag "none" nil)
313 (integer :tag "size"))))) 313 (integer :tag "size")))))
314 :group 'font-lock) 314 :group 'font-lock)
315 315
316 ;;;###autoload
317 (defcustom font-lock-fontify-string-delimiters nil
318 "*If non-nil, apply font-lock-string-face to string delimiters as well as
319 string text when fontifying."
320 :type 'boolean
321 :group 'font-lock)
316 322
317 ;; Fontification variables: 323 ;; Fontification variables:
318 324
319 ;;;###autoload 325 ;;;###autoload
320 (defvar font-lock-keywords nil 326 (defvar font-lock-keywords nil
436 dramatically slow things down! 442 dramatically slow things down!
437 ") 443 ")
438 ;;;###autoload 444 ;;;###autoload
439 (make-variable-buffer-local 'font-lock-keywords) 445 (make-variable-buffer-local 'font-lock-keywords)
440 446
447 ;;;###autoload
448 (defvar font-lock-syntactic-keywords nil
449 "A list of the syntactic keywords to highlight.
450 Can be the list or the name of a function or variable whose value is the list.
451 See `font-lock-keywords' for a description of the form of this list;
452 the differences are listed below. MATCH-HIGHLIGHT should be of the form:
453
454 (MATCH SYNTAX OVERRIDE LAXMATCH)
455
456 where SYNTAX can be of the form (SYNTAX-CODE . MATCHING-CHAR), the name of a
457 syntax table, or an expression whose value is such a form or a syntax table.
458 OVERRIDE cannot be `prepend' or `append'.
459
460 For example, an element of the form highlights syntactically:
461
462 (\"\\\\$\\\\(#\\\\)\" 1 (1 . nil))
463
464 a hash character when following a dollar character, with a SYNTAX-CODE of
465 1 (meaning punctuation syntax). Assuming that the buffer syntax table does
466 specify hash characters to have comment start syntax, the element will only
467 highlight hash characters that do not follow dollar characters as comments
468 syntactically.
469
470 (\"\\\\('\\\\).\\\\('\\\\)\"
471 (1 (7 . ?'))
472 (2 (7 . ?')))
473
474 both single quotes which surround a single character, with a SYNTAX-CODE of
475 7 (meaning string quote syntax) and a MATCHING-CHAR of a single quote (meaning
476 a single quote matches a single quote). Assuming that the buffer syntax table
477 does not specify single quotes to have quote syntax, the element will only
478 highlight single quotes of the form 'c' as strings syntactically.
479 Other forms, such as foo'bar or 'fubar', will not be highlighted as strings.
480
481 This is normally set via `font-lock-defaults'."
482 )
483 ;;;###autoload
484 (make-variable-buffer-local 'font-lock-syntactic-keywords)
485
441 (defvar font-lock-defaults nil 486 (defvar font-lock-defaults nil
442 "The defaults font Font Lock mode for the current buffer. 487 "The defaults font Font Lock mode for the current buffer.
443 Normally, do not set this directly. If you are writing a major mode, 488 Normally, do not set this directly. If you are writing a major mode,
444 put a property of `font-lock-defaults' on the major-mode symbol with 489 put a property of `font-lock-defaults' on the major-mode symbol with
445 the desired value. 490 the desired value.
509 "Non-nil means use this syntax table for fontifying. 554 "Non-nil means use this syntax table for fontifying.
510 If this is nil, the major mode's syntax table is used. 555 If this is nil, the major mode's syntax table is used.
511 This is normally set via `font-lock-defaults'.") 556 This is normally set via `font-lock-defaults'.")
512 (make-variable-buffer-local 'font-lock-syntax-table) 557 (make-variable-buffer-local 'font-lock-syntax-table)
513 558
514 ;; These are used in the FSF version in syntactic font-locking. 559 ;; These record the parse state at a particular position, always the start of a
515 ;; We do this all in C. 560 ;; line. Used to make `font-lock-fontify-syntactically-region' faster.
516 ;;; These record the parse state at a particular position, always the 561 ;; Previously, `font-lock-cache-position' was just a buffer position. However,
517 ;;; start of a line. Used to make 562 ;; under certain situations, this occasionally resulted in mis-fontification.
518 ;;; `font-lock-fontify-syntactically-region' faster. 563 ;; I think the "situations" were deletion with Lazy Lock mode's deferral. sm.
519 ;(defvar font-lock-cache-position nil) 564 (defvar font-lock-cache-state nil)
520 ;(defvar font-lock-cache-state nil) 565 (defvar font-lock-cache-position nil)
521 ;(make-variable-buffer-local 'font-lock-cache-position) 566 (make-variable-buffer-local 'font-lock-cache-state)
522 ;(make-variable-buffer-local 'font-lock-cache-state) 567 (make-variable-buffer-local 'font-lock-cache-position)
523 568
524 ;; If this is nil, we only use the beginning of the buffer if we can't use 569 ;; If this is nil, we only use the beginning of the buffer if we can't use
525 ;; `font-lock-cache-position' and `font-lock-cache-state'. 570 ;; `font-lock-cache-position' and `font-lock-cache-state'.
526 (defvar font-lock-beginning-of-syntax-function nil 571 (defvar font-lock-beginning-of-syntax-function nil
527 "Non-nil means use this function to move back outside of a syntactic block. 572 "Non-nil means use this function to move back outside of a syntactic block.
942 (put-nonduplicable-text-property start end 'font-lock t)) 987 (put-nonduplicable-text-property start end 'font-lock t))
943 988
944 (defsubst font-lock-remove-face (start end) 989 (defsubst font-lock-remove-face (start end)
945 ;; Remove any syntax highlighting on the characters in the range. 990 ;; Remove any syntax highlighting on the characters in the range.
946 (put-nonduplicable-text-property start end 'face nil) 991 (put-nonduplicable-text-property start end 'face nil)
947 (put-nonduplicable-text-property start end 'font-lock nil)) 992 (put-nonduplicable-text-property start end 'font-lock nil)
993 (if lookup-syntax-properties
994 (put-nonduplicable-text-property start end 'syntax-table nil)))
995
996 (defsubst font-lock-set-syntax (start end syntax)
997 ;; Set the face on the characters in the range.
998 (put-nonduplicable-text-property start end 'syntax-table syntax)
999 (put-nonduplicable-text-property start end 'font-lock t))
948 1000
949 (defsubst font-lock-any-faces-p (start end) 1001 (defsubst font-lock-any-faces-p (start end)
950 ;; Return non-nil if we've put any syntax highlighting on 1002 ;; Return non-nil if we've put any syntax highlighting on
951 ;; the characters in the range. 1003 ;; the characters in the range.
952 ;; 1004 ;;
1082 (unwind-protect 1134 (unwind-protect
1083 (progn 1135 (progn
1084 ;; Use the fontification syntax table, if any. 1136 ;; Use the fontification syntax table, if any.
1085 (if font-lock-syntax-table (set-syntax-table font-lock-syntax-table)) 1137 (if font-lock-syntax-table (set-syntax-table font-lock-syntax-table))
1086 ;; Now do the fontification. 1138 ;; Now do the fontification.
1087 (if font-lock-keywords-only 1139 (font-lock-unfontify-region beg end)
1088 (font-lock-unfontify-region beg end) 1140 (when font-lock-syntactic-keywords
1141 (font-lock-fontify-syntactic-keywords-region beg end))
1142 (unless font-lock-keywords-only
1089 (font-lock-fontify-syntactically-region beg end loudly)) 1143 (font-lock-fontify-syntactically-region beg end loudly))
1090 (font-lock-fontify-keywords-region beg end loudly)) 1144 (font-lock-fontify-keywords-region beg end loudly))
1091 ;; Clean up. 1145 ;; Clean up.
1092 (set-syntax-table old-syntax-table) 1146 (set-syntax-table old-syntax-table)
1093 (and (not modified) (buffer-modified-p) (set-buffer-modified-p nil))))) 1147 (and (not modified) (buffer-modified-p) (set-buffer-modified-p nil)))))
1220 font-lock-range-table))))))) 1274 font-lock-range-table)))))))
1221 font-lock-pending-extent-table))) 1275 font-lock-pending-extent-table)))
1222 1276
1223 ;; Syntactic fontification functions. 1277 ;; Syntactic fontification functions.
1224 1278
1225 ;; Note: Here is the FSF version. Our version is much faster because
1226 ;; of the C support we provide. This may be useful for reference,
1227 ;; however, and perhaps there is something useful here that should
1228 ;; be merged into our version.
1229 ;;
1230 ;(defun font-lock-fontify-syntactically-region (start end &optional loudly)
1231 ; "Put proper face on each string and comment between START and END.
1232 ;START should be at the beginning of a line."
1233 ; (let ((synstart (if comment-start-skip
1234 ; (concat "\\s\"\\|" comment-start-skip)
1235 ; "\\s\""))
1236 ; (comstart (if comment-start-skip
1237 ; (concat "\\s<\\|" comment-start-skip)
1238 ; "\\s<"))
1239 ; state prev prevstate)
1240 ; (if loudly (message "Fontifying %s... (syntactically...)" (buffer-name)))
1241 ; (save-restriction
1242 ; (widen)
1243 ; (goto-char start)
1244 ; ;;
1245 ; ;; Find the state at the `beginning-of-line' before `start'.
1246 ; (if (eq start font-lock-cache-position)
1247 ; ;; Use the cache for the state of `start'.
1248 ; (setq state font-lock-cache-state)
1249 ; ;; Find the state of `start'.
1250 ; (if (null font-lock-beginning-of-syntax-function)
1251 ; ;; Use the state at the previous cache position, if any, or
1252 ; ;; otherwise calculate from `point-min'.
1253 ; (if (or (null font-lock-cache-position)
1254 ; (< start font-lock-cache-position))
1255 ; (setq state (parse-partial-sexp (point-min) start))
1256 ; (setq state (parse-partial-sexp font-lock-cache-position start
1257 ; nil nil font-lock-cache-state)))
1258 ; ;; Call the function to move outside any syntactic block.
1259 ; (funcall font-lock-beginning-of-syntax-function)
1260 ; (setq state (parse-partial-sexp (point) start)))
1261 ; ;; Cache the state and position of `start'.
1262 ; (setq font-lock-cache-state state
1263 ; font-lock-cache-position start))
1264 ; ;;
1265 ; ;; If the region starts inside a string, show the extent of it.
1266 ; (if (nth 3 state)
1267 ; (let ((beg (point)))
1268 ; (while (and (re-search-forward "\\s\"" end 'move)
1269 ; (nth 3 (parse-partial-sexp beg (point)
1270 ; nil nil state))))
1271 ; (put-text-property beg (point) 'face font-lock-string-face)
1272 ; (setq state (parse-partial-sexp beg (point) nil nil state))))
1273 ; ;;
1274 ; ;; Likewise for a comment.
1275 ; (if (or (nth 4 state) (nth 7 state))
1276 ; (let ((beg (point)))
1277 ; (save-restriction
1278 ; (narrow-to-region (point-min) end)
1279 ; (condition-case nil
1280 ; (progn
1281 ; (re-search-backward comstart (point-min) 'move)
1282 ; (forward-comment 1)
1283 ; ;; forward-comment skips all whitespace,
1284 ; ;; so go back to the real end of the comment.
1285 ; (skip-chars-backward " \t"))
1286 ; (error (goto-char end))))
1287 ; (put-text-property beg (point) 'face font-lock-comment-face)
1288 ; (setq state (parse-partial-sexp beg (point) nil nil state))))
1289 ; ;;
1290 ; ;; Find each interesting place between here and `end'.
1291 ; (while (and (< (point) end)
1292 ; (setq prev (point) prevstate state)
1293 ; (re-search-forward synstart end t)
1294 ; (progn
1295 ; ;; Clear out the fonts of what we skip over.
1296 ; (remove-text-properties prev (point) '(face nil))
1297 ; ;; Verify the state at that place
1298 ; ;; so we don't get fooled by \" or \;.
1299 ; (setq state (parse-partial-sexp prev (point)
1300 ; nil nil state))))
1301 ; (let ((here (point)))
1302 ; (if (or (nth 4 state) (nth 7 state))
1303 ; ;;
1304 ; ;; We found a real comment start.
1305 ; (let ((beg (match-beginning 0)))
1306 ; (goto-char beg)
1307 ; (save-restriction
1308 ; (narrow-to-region (point-min) end)
1309 ; (condition-case nil
1310 ; (progn
1311 ; (forward-comment 1)
1312 ; ;; forward-comment skips all whitespace,
1313 ; ;; so go back to the real end of the comment.
1314 ; (skip-chars-backward " \t"))
1315 ; (error (goto-char end))))
1316 ; (put-text-property beg (point) 'face
1317 ; font-lock-comment-face)
1318 ; (setq state (parse-partial-sexp here (point) nil nil state)))
1319 ; (if (nth 3 state)
1320 ; ;;
1321 ; ;; We found a real string start.
1322 ; (let ((beg (match-beginning 0)))
1323 ; (while (and (re-search-forward "\\s\"" end 'move)
1324 ; (nth 3 (parse-partial-sexp here (point)
1325 ; nil nil state))))
1326 ; (put-text-property beg (point) 'face font-lock-string-face)
1327 ; (setq state (parse-partial-sexp here (point)
1328 ; nil nil state))))))
1329 ; ;;
1330 ; ;; Make sure `prev' is non-nil after the loop
1331 ; ;; only if it was set on the very last iteration.
1332 ; (setq prev nil)))
1333 ; ;;
1334 ; ;; Clean up.
1335 ; (and prev (remove-text-properties prev end '(face nil)))))
1336
1337 (defun font-lock-lisp-like (mode) 1279 (defun font-lock-lisp-like (mode)
1338 ;; Note: (or (get mode 'font-lock-lisp-like) (string-match ...)) is 1280 ;; Note: (or (get mode 'font-lock-lisp-like) (string-match ...)) is
1339 ;; not enough because the property needs to be able to specify a nil 1281 ;; not enough because the property needs to be able to specify a nil
1340 ;; value. 1282 ;; value.
1341 (if (plist-member (symbol-plist mode) 'font-lock-lisp-like) 1283 (if (plist-member (symbol-plist mode) 'font-lock-lisp-like)
1342 (get mode 'font-lock-lisp-like) 1284 (get mode 'font-lock-lisp-like)
1343 ;; If the property is not specified, guess. Similar logic exists 1285 ;; If the property is not specified, guess. Similar logic exists
1344 ;; in add-log, but I think this encompasses more modes. 1286 ;; in add-log, but I think this encompasses more modes.
1345 (string-match "lisp\\|scheme" (symbol-name mode)))) 1287 (string-match "lisp\\|scheme" (symbol-name mode))))
1346 1288
1289 ;; fontify-syntactically-region used to use syntactically-sectionize, which
1290 ;; was supposedly much faster than the FSF version because it was written in
1291 ;; C. However, the FSF version uses parse-partial-sexp, which is also
1292 ;; written in C, and the benchmarking I did showed the
1293 ;; syntactically-sectionize code to be slower overall. So here's the FSF
1294 ;; version, modified to support font-lock-doc-string-face.
1295 ;; -- mct 2000-12-29
1347 (defun font-lock-fontify-syntactically-region (start end &optional loudly) 1296 (defun font-lock-fontify-syntactically-region (start end &optional loudly)
1348 "Put proper face on each string and comment between START and END. 1297 "Put proper face on each string and comment between START and END.
1349 START should be at the beginning of a line." 1298 START should be at the beginning of a line."
1350 (if font-lock-keywords-only 1299 (if font-lock-keywords-only
1351 nil 1300 nil
1301
1302 ;; #### Shouldn't this just be using 'loudly??
1352 (when (and font-lock-verbose 1303 (when (and font-lock-verbose
1353 (>= (- end start) font-lock-message-threshold)) 1304 (>= (- end start) font-lock-message-threshold))
1354 (progress-feedback-with-label 'font-lock 1305 (progress-feedback-with-label 'font-lock
1355 "Fontifying %s... (syntactically)" 5 1306 "Fontifying %s... (syntactically)" 5
1356 (buffer-name))) 1307 (buffer-name)))
1357 (font-lock-unfontify-region start end loudly)
1358 (goto-char start) 1308 (goto-char start)
1359 (if (> end (point-max)) (setq end (point-max))) 1309
1360 (let ((lisp-like (font-lock-lisp-like major-mode))) 1310 (let ((lisp-like (font-lock-lisp-like major-mode))
1361 (syntactically-sectionize 1311 (cache (marker-position font-lock-cache-position))
1362 #'(lambda (s e context depth) 1312 state string beg depth)
1363 (let (face) 1313 ;;
1364 (cond ((eq context 'string) 1314 ;; Find the state at the `beginning-of-line' before `start'.
1365 (setq face 1315 (if (eq start cache)
1366 ;; #### It would be nice if we handled 1316 ;; Use the cache for the state of `start'.
1367 ;; Python and other non-Lisp languages with 1317 (setq state font-lock-cache-state)
1368 ;; docstrings correctly. 1318 ;; Find the state of `start'.
1369 (if (and lisp-like (= depth 1)) 1319 (if (null font-lock-beginning-of-syntax-function)
1370 ;; really we should only use this if 1320 ;; Use the state at the previous cache position, if any, or
1371 ;; in position 3 depth 1, but that's 1321 ;; otherwise calculate from `point-min'.
1372 ;; too expensive to compute. 1322 (if (or (null cache) (< start cache))
1373 'font-lock-doc-string-face 1323 (setq state (parse-partial-sexp (point-min) start))
1374 'font-lock-string-face))) 1324 (setq state (parse-partial-sexp cache start nil nil
1375 ((or (eq context 'comment) 1325 font-lock-cache-state)))
1376 (eq context 'block-comment)) 1326 ;; Call the function to move outside any syntactic block.
1377 (setq face 'font-lock-comment-face) 1327 (funcall font-lock-beginning-of-syntax-function)
1378 ; ;; Don't fontify whitespace at the beginning of lines; 1328 (setq state (parse-partial-sexp (point) start)))
1379 ; ;; otherwise comment blocks may not line up with code. 1329 ;; Cache the state and position of `start'.
1380 ; ;; (This is sometimes a good idea, sometimes not; in any 1330 (setq font-lock-cache-state state)
1381 ; ;; event it should be in C for speed --jwz) 1331 (set-marker font-lock-cache-position start))
1382 ; (save-excursion 1332 ;;
1383 ; (goto-char s) 1333 ;; If the region starts inside a string or comment, show the extent of it.
1384 ; (while (prog1 (search-forward "\n" (1- e) 'move) 1334 (when (or (nth 3 state) (nth 4 state))
1385 ; (setq face 'font-lock-comment-face) 1335 (setq string (nth 3 state) beg (point))
1386 ; (setq e (point))) 1336 (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table))
1387 ; (skip-chars-forward " \t\n") 1337 (font-lock-set-face beg (point) (if string
1388 ; (setq s (point))) 1338 font-lock-string-face
1389 )) 1339 font-lock-comment-face)))
1390 (font-lock-set-face s e face))) 1340 ;;
1391 start end) 1341 ;; Find each interesting place between here and `end'.
1392 ))) 1342 (while (and (< (point) end)
1343 (progn
1344 (setq state (parse-partial-sexp (point) end nil nil state
1345 'syntax-table))
1346 (or (nth 3 state) (nth 4 state))))
1347 (setq depth (nth 0 state) string (nth 3 state) beg (nth 8 state))
1348 (setq state (parse-partial-sexp (point) end nil nil state 'syntax-table))
1349 (if string
1350 ;; #### It would be nice if we handled Python and other
1351 ;; non-Lisp languages with docstrings correctly.
1352 (let ((face (if (and lisp-like (= depth 1))
1353 'font-lock-doc-string-face
1354 'font-lock-string-face)))
1355 (if font-lock-fontify-string-delimiters
1356 (font-lock-set-face beg (point) face)
1357 (font-lock-set-face (+ beg 1) (- (point) 1) face)))
1358 (font-lock-set-face beg (point)
1359 font-lock-comment-face))))))
1393 1360
1394 ;;; Additional text property functions. 1361 ;;; Additional text property functions.
1395 1362
1396 ;; The following three text property functions are not generally available (and 1363 ;; The following three text property functions are not generally available (and
1397 ;; it's not certain that they should be) so they are inlined for speed. 1364 ;; it's not certain that they should be) so they are inlined for speed.
1470 (put-text-property 1437 (put-text-property
1471 start next prop 1438 start next prop
1472 (font-lock-unique (append (if (listp prev) prev (list prev)) val)) 1439 (font-lock-unique (append (if (listp prev) prev (list prev)) val))
1473 object) 1440 object)
1474 (setq start next)))) 1441 (setq start next))))
1442
1443 ;;; Syntactic regexp fontification functions (taken from FSF Emacs 20.7.1)
1444
1445 ;; These syntactic keyword pass functions are identical to those keyword pass
1446 ;; functions below, with the following exceptions; (a) they operate on
1447 ;; `font-lock-syntactic-keywords' of course, (b) they are all `defun' as speed
1448 ;; is less of an issue, (c) eval of property value does not occur JIT as speed
1449 ;; is less of an issue, (d) OVERRIDE cannot be `prepend' or `append' as it
1450 ;; makes no sense for `syntax-table' property values, (e) they do not do it
1451 ;; LOUDLY as it is not likely to be intensive.
1452
1453 (defun font-lock-apply-syntactic-highlight (highlight)
1454 "Apply HIGHLIGHT following a match.
1455 HIGHLIGHT should be of the form MATCH-HIGHLIGHT,
1456 see `font-lock-syntactic-keywords'."
1457 (let* ((match (nth 0 highlight))
1458 (start (match-beginning match)) (end (match-end match))
1459 (value (nth 1 highlight))
1460 (override (nth 2 highlight)))
1461 (unless (numberp (car-safe value))
1462 (setq value (eval value)))
1463 (cond ((not start)
1464 ;; No match but we might not signal an error.
1465 (or (nth 3 highlight)
1466 (error "No match %d in highlight %S" match highlight)))
1467 ((not override)
1468 ;; Cannot override existing fontification.
1469 (or (map-extents 'extent-property (current-buffer)
1470 start end 'syntax-table)
1471 (font-lock-set-syntax start end value)))
1472 ((eq override t)
1473 ;; Override existing fontification.
1474 (font-lock-set-syntax start end value))
1475 ((eq override 'keep)
1476 ;; Keep existing fontification.
1477 (font-lock-fillin-text-property start end
1478 'syntax-table 'font-lock value)))))
1479
1480 (defun font-lock-fontify-syntactic-anchored-keywords (keywords limit)
1481 "Fontify according to KEYWORDS until LIMIT.
1482 KEYWORDS should be of the form MATCH-ANCHORED, see `font-lock-keywords',
1483 LIMIT can be modified by the value of its PRE-MATCH-FORM."
1484 (let ((matcher (nth 0 keywords)) (lowdarks (nthcdr 3 keywords)) highlights
1485 ;; Evaluate PRE-MATCH-FORM.
1486 (pre-match-value (eval (nth 1 keywords))))
1487 ;; Set LIMIT to value of PRE-MATCH-FORM or the end of line.
1488 (if (and (numberp pre-match-value) (> pre-match-value (point)))
1489 (setq limit pre-match-value)
1490 (save-excursion (end-of-line) (setq limit (point))))
1491 (save-match-data
1492 ;; Find an occurrence of `matcher' before `limit'.
1493 (while (if (stringp matcher)
1494 (re-search-forward matcher limit t)
1495 (funcall matcher limit))
1496 ;; Apply each highlight to this instance of `matcher'.
1497 (setq highlights lowdarks)
1498 (while highlights
1499 (font-lock-apply-syntactic-highlight (car highlights))
1500 (setq highlights (cdr highlights)))))
1501 ;; Evaluate POST-MATCH-FORM.
1502 (eval (nth 2 keywords))))
1503
1504 (defun font-lock-fontify-syntactic-keywords-region (start end)
1505 "Fontify according to `font-lock-syntactic-keywords' between START and END.
1506 START should be at the beginning of a line."
1507 ;; ;; If `font-lock-syntactic-keywords' is a symbol, get the real keywords.
1508 (when (symbolp font-lock-syntactic-keywords)
1509 (setq font-lock-syntactic-keywords (font-lock-eval-keywords
1510 font-lock-syntactic-keywords)))
1511 ;; If `font-lock-syntactic-keywords' is not compiled, compile it.
1512 (unless (eq (car font-lock-syntactic-keywords) t)
1513 (setq font-lock-syntactic-keywords (font-lock-compile-keywords
1514 font-lock-syntactic-keywords)))
1515 ;; Get down to business.
1516 (let ((case-fold-search font-lock-keywords-case-fold-search)
1517 (keywords (cdr font-lock-syntactic-keywords))
1518 keyword matcher highlights)
1519 (while keywords
1520 ;; Find an occurrence of `matcher' from `start' to `end'.
1521 (setq keyword (car keywords) matcher (car keyword))
1522 (goto-char start)
1523 (while (if (stringp matcher)
1524 (re-search-forward matcher end t)
1525 (funcall matcher end))
1526 ;; Apply each highlight to this instance of `matcher', which may be
1527 ;; specific highlights or more keywords anchored to `matcher'.
1528 (setq highlights (cdr keyword))
1529 (while highlights
1530 (if (numberp (car (car highlights)))
1531 (font-lock-apply-syntactic-highlight (car highlights))
1532 (font-lock-fontify-syntactic-anchored-keywords (car highlights)
1533 end))
1534 (setq highlights (cdr highlights)))
1535 )
1536 (setq keywords (cdr keywords)))))
1475 1537
1476 ;;; Regexp fontification functions. 1538 ;;; Regexp fontification functions.
1477 1539
1478 (defsubst font-lock-apply-highlight (highlight) 1540 (defsubst font-lock-apply-highlight (highlight)
1479 "Apply HIGHLIGHT following a match. 1541 "Apply HIGHLIGHT following a match.
1634 ((nlistp (nth 1 keyword)) ; Specified (MATCHER . HIGHLIGHT) 1696 ((nlistp (nth 1 keyword)) ; Specified (MATCHER . HIGHLIGHT)
1635 (list (car keyword) (cdr keyword))) 1697 (list (car keyword) (cdr keyword)))
1636 (t ; Hopefully (MATCHER HIGHLIGHT ...) 1698 (t ; Hopefully (MATCHER HIGHLIGHT ...)
1637 keyword))) 1699 keyword)))
1638 1700
1701 (defun font-lock-eval-keywords (keywords)
1702 ;; Evalulate KEYWORDS if a function (funcall) or variable (eval) name.
1703 (if (listp keywords)
1704 keywords
1705 (font-lock-eval-keywords (if (fboundp keywords)
1706 (funcall keywords)
1707 (eval keywords)))))
1708
1639 (defun font-lock-choose-keywords (keywords level) 1709 (defun font-lock-choose-keywords (keywords level)
1640 ;; Return LEVELth element of KEYWORDS. A LEVEL of nil is equal to a 1710 ;; Return LEVELth element of KEYWORDS. A LEVEL of nil is equal to a
1641 ;; LEVEL of 0, a LEVEL of t is equal to (1- (length KEYWORDS)). 1711 ;; LEVEL of 0, a LEVEL of t is equal to (1- (length KEYWORDS)).
1642 (let ((level (if (not (consp level)) 1712 (let ((level (if (not (consp level))
1643 level 1713 level
1711 ;; as in FSF Emacs. 1781 ;; as in FSF Emacs.
1712 font-lock-defaults 1782 font-lock-defaults
1713 (font-lock-find-font-lock-defaults major-mode))) 1783 (font-lock-find-font-lock-defaults major-mode)))
1714 (keywords (font-lock-choose-keywords 1784 (keywords (font-lock-choose-keywords
1715 (nth 0 defaults) font-lock-maximum-decoration))) 1785 (nth 0 defaults) font-lock-maximum-decoration)))
1716 1786
1717 ;; Keywords? 1787 ;; Keywords?
1718 (setq font-lock-keywords (if (fboundp keywords) 1788 (setq font-lock-keywords (if (fboundp keywords)
1719 (funcall keywords) 1789 (funcall keywords)
1720 (eval keywords))) 1790 (eval keywords)))
1721 (or font-lock-keywords 1791 (or font-lock-keywords
1777 ;; older way: 1847 ;; older way:
1778 ;; defaults not specified at all, so use `beginning-of-defun'. 1848 ;; defaults not specified at all, so use `beginning-of-defun'.
1779 (setq font-lock-beginning-of-syntax-function 1849 (setq font-lock-beginning-of-syntax-function
1780 'beginning-of-defun))))) 1850 'beginning-of-defun)))))
1781 1851
1852 (setq font-lock-cache-position (make-marker))
1782 (setq font-lock-defaults-computed t))) 1853 (setq font-lock-defaults-computed t)))
1783 1854
1784 1855
1785 ;;;;;;;;;;;;;;;;;;;;;; keywords ;;;;;;;;;;;;;;;;;;;;;; 1856 ;;;;;;;;;;;;;;;;;;;;;; keywords ;;;;;;;;;;;;;;;;;;;;;;
1786 1857