Mercurial > emacs
comparison lisp/font-lock.el @ 26920:e510f839bc63
System for adding and removing keywords.
Both local (previously added keyword) and global keywords
can be removed.
(font-lock-remove-keywords): New user-level function.
(font-lock-update-removed-keyword-alist): New internal function.
(font-lock-removed-keywords-alist): New variable.
(font-lock-add-keywords): Updates `font-lock-removed-keywords-alist'.
Empty `font-lock-keywords-alist' when `append' is `set' to avoid
growing datastructures.
(font-lock-set-defaults): Removes keywords stored in
`font-lock-removed-keywords-alist' after local keywords added.
(c-keywords, c++-keywords): Better "case" support for
complex constant expressions, e.g. "case 1<<A_BIT_NO:".
(c-keywords): Only highlight preprocessor
directives when spelled correctly.
(font-lock-match-c++-structor-declaration,
c++-keywords): Fontify constructors and destructors with function
face inside C++ class declarations.
author | Gerd Moellmann <gerd@gnu.org> |
---|---|
date | Thu, 16 Dec 1999 15:03:34 +0000 |
parents | 11fddded9ceb |
children | d30c57a6b35c |
comparison
equal
deleted
inserted
replaced
26919:4335b1ee34bb | 26920:e510f839bc63 |
---|---|
504 where MAJOR-MODE is a symbol and FONT-LOCK-DEFAULTS is a list of default | 504 where MAJOR-MODE is a symbol and FONT-LOCK-DEFAULTS is a list of default |
505 settings. See the variable `font-lock-defaults', which takes precedence.") | 505 settings. See the variable `font-lock-defaults', which takes precedence.") |
506 | 506 |
507 (defvar font-lock-keywords-alist nil | 507 (defvar font-lock-keywords-alist nil |
508 "*Alist of `font-lock-keywords' local to a `major-mode'. | 508 "*Alist of `font-lock-keywords' local to a `major-mode'. |
509 This is normally set via `font-lock-add-keywords'.") | 509 This is normally set via `font-lock-add-keywords' and |
510 `font-lock-remove-keywords'.") | |
511 | |
512 (defvar font-lock-removed-keywords-alist nil | |
513 "*Alist of `font-lock-keywords' removed from `major-mode'. | |
514 This is normally set via `font-lock-add-keywords' and | |
515 `font-lock-remove-keywords'.") | |
510 | 516 |
511 (defvar font-lock-keywords-only nil | 517 (defvar font-lock-keywords-only nil |
512 "*Non-nil means Font Lock should not fontify comments or strings. | 518 "*Non-nil means Font Lock should not fontify comments or strings. |
513 This is normally set via `font-lock-defaults'.") | 519 This is normally set via `font-lock-defaults'.") |
514 | 520 |
752 (cond (mode | 758 (cond (mode |
753 ;; If MODE is non-nil, add the KEYWORDS and APPEND spec to | 759 ;; If MODE is non-nil, add the KEYWORDS and APPEND spec to |
754 ;; `font-lock-keywords-alist' so `font-lock-set-defaults' uses them. | 760 ;; `font-lock-keywords-alist' so `font-lock-set-defaults' uses them. |
755 (let ((spec (cons keywords append)) cell) | 761 (let ((spec (cons keywords append)) cell) |
756 (if (setq cell (assq mode font-lock-keywords-alist)) | 762 (if (setq cell (assq mode font-lock-keywords-alist)) |
757 (setcdr cell (append (cdr cell) (list spec))) | 763 (if (eq append 'set) |
758 (push (list mode spec) font-lock-keywords-alist)))) | 764 (setcdr cell (list spec)) |
765 (setcdr cell (append (cdr cell) (list spec)))) | |
766 (push (list mode spec) font-lock-keywords-alist))) | |
767 ;; Make sure that `font-lock-removed-keywords-alist' does not | |
768 ;; contain the new keywords. | |
769 (font-lock-update-removed-keyword-alist mode keywords append)) | |
759 (font-lock-mode | 770 (font-lock-mode |
760 ;; Otherwise if Font Lock mode is on, set or add the keywords now. | 771 ;; Otherwise if Font Lock mode is on, set or add the keywords now. |
761 (if (eq append 'set) | 772 (if (eq append 'set) |
762 (setq font-lock-keywords keywords) | 773 (setq font-lock-keywords keywords) |
763 (font-lock-remove-keywords nil keywords) | 774 (font-lock-remove-keywords mode keywords) |
764 (let ((old (if (eq (car-safe font-lock-keywords) t) | 775 (let ((old (if (eq (car-safe font-lock-keywords) t) |
765 (cdr font-lock-keywords) | 776 (cdr font-lock-keywords) |
766 font-lock-keywords))) | 777 font-lock-keywords))) |
767 (setq font-lock-keywords (if append | 778 (setq font-lock-keywords (if append |
768 (append old keywords) | 779 (append old keywords) |
769 (append keywords old)))))))) | 780 (append keywords old)))))))) |
770 | 781 |
782 (defun font-lock-update-removed-keyword-alist (major-mode keywords append) | |
783 ;; Update `font-lock-removed-keywords-alist' when adding new | |
784 ;; KEYWORDS to MAJOR-MODE. | |
785 ;; | |
786 ;; When font-lock is enabled first all keywords in the list | |
787 ;; `font-lock-keywords-alist' are added, then all keywords in the | |
788 ;; list `font-lock-removed-keywords-alist' are removed. If a | |
789 ;; keyword was once added, removed, and then added again it must be | |
790 ;; removed from the removed-keywords list. Otherwise the second add | |
791 ;; will not take effect. | |
792 (let ((cell (assq major-mode font-lock-removed-keywords-alist))) | |
793 (if cell | |
794 (if (eq append 'set) | |
795 ;; A new set of keywords is defined. Forget all about | |
796 ;; our old keywords that should be removed. | |
797 (setq font-lock-removed-keywords-alist | |
798 (delq cell font-lock-removed-keywords-alist)) | |
799 ;; Delete all previously removed keywords. | |
800 (dolist (kword keywords) | |
801 (setcdr cell (delete kword (cdr cell)))) | |
802 ;; Delete the major-mode cell if empty. | |
803 (if (null (cdr cell)) | |
804 (setq font-lock-removed-keywords-alist | |
805 (delq cell font-lock-removed-keywords-alist))))))) | |
806 | |
807 ;; Written by Anders Lindgren <andersl@andersl.com>. | |
808 ;; | |
809 ;; Case study: | |
810 ;; (I) The keywords are removed from a major mode. | |
811 ;; In this case the keyword could be local (i.e. added earlier by | |
812 ;; `font-lock-add-keywords'), global, or both. | |
813 ;; | |
814 ;; (a) In the local case we remove the keywords from the variable | |
815 ;; `font-lock-keywords-alist'. | |
816 ;; | |
817 ;; (b) The actual global keywords are not known at this time. | |
818 ;; All keywords are added to `font-lock-removed-keywords-alist', | |
819 ;; when font-lock is enabled those keywords are removed. | |
820 ;; | |
821 ;; Note that added keywords are taken out of the list of removed | |
822 ;; keywords. This ensure correct operation when the same keyword | |
823 ;; is added and removed several times. | |
824 ;; | |
825 ;; (II) The keywords are removed from the current buffer. | |
771 ;;;###autoload | 826 ;;;###autoload |
772 (defun font-lock-remove-keywords (mode keywords) | 827 (defun font-lock-remove-keywords (major-mode keywords) |
773 "Remove highlighting KEYWORDS from the current buffer. | 828 "Remove highlighting KEYWORDS for MAJOR-MODE. |
774 A non-nil MODE is currently unsupported." | 829 |
775 (setq font-lock-keywords (copy-list font-lock-keywords)) | 830 MAJOR-MODE should be a symbol, the major mode command name, such as `c-mode' |
831 or nil. If nil, highlighting keywords are removed for the current buffer." | |
776 (dolist (keyword keywords) | 832 (dolist (keyword keywords) |
777 (setq font-lock-keywords | 833 ;; Remove one keyword at the time. |
778 (delete keyword | 834 (cond (major-mode |
779 (delete (font-lock-compile-keyword keyword) | 835 (let ((top-cell (assq major-mode font-lock-keywords-alist))) |
780 font-lock-keywords))))) | 836 ;; If MAJOR-MODE is non-nil, remove the KEYWORD from |
781 | 837 ;; `font-lock-keywords-alist'. |
838 (when top-cell | |
839 (dolist (keyword-list-append-pair (cdr top-cell)) | |
840 ;; `keywords-list-append-pair' is a cons with a list of | |
841 ;; keywords in the car top-cell and the original append | |
842 ;; argument in the cdr top-cell. | |
843 (setcar keyword-list-append-pair | |
844 (delete keyword (car keyword-list-append-pair)))) | |
845 ;; Remove keyword list/append pair when the keyword list | |
846 ;; is empty and append doesn't specify `set'. (If it | |
847 ;; should be deleted then previously deleted keywords | |
848 ;; would appear again.) | |
849 (let ((cell top-cell)) | |
850 (while (cdr cell) | |
851 (if (and (null (car (car (cdr cell)))) | |
852 (not (eq (cdr (car (cdr cell))) 'set))) | |
853 (setcdr cell (cdr (cdr cell))) | |
854 (setq cell (cdr cell))))) | |
855 ;; Final cleanup, remove major mode cell if last keyword | |
856 ;; was deleted. | |
857 (if (null (cdr top-cell)) | |
858 (setq font-lock-keywords-alist | |
859 (delq top-cell font-lock-keywords-alist)))) | |
860 ;; Remember the keyword in case it is not local. | |
861 (let ((cell (assq major-mode font-lock-removed-keywords-alist))) | |
862 (if cell | |
863 (unless (member keyword (cdr cell)) | |
864 (nconc cell (list keyword))) | |
865 (push (cons major-mode (list keyword)) | |
866 font-lock-removed-keywords-alist))))) | |
867 (font-lock-mode | |
868 ;; Otherwise if Font Lock mode is on, remove it immediately. | |
869 (setq font-lock-keywords (delete keyword font-lock-keywords)) | |
870 ;; The keywords might be compiled. | |
871 (setq font-lock-keywords | |
872 (delete (font-lock-compile-keyword keyword) | |
873 font-lock-keywords)))))) | |
782 | 874 |
783 ;;; Global Font Lock mode. | 875 ;;; Global Font Lock mode. |
784 | 876 |
785 ;; A few people have hassled in the past for a way to make it easier to turn on | 877 ;; A few people have hassled in the past for a way to make it easier to turn on |
786 ;; Font Lock mode, without the user needing to know for which modes s/he has to | 878 ;; Font Lock mode, without the user needing to know for which modes s/he has to |
1607 (let* ((defaults (or font-lock-defaults | 1699 (let* ((defaults (or font-lock-defaults |
1608 (cdr (assq major-mode font-lock-defaults-alist)))) | 1700 (cdr (assq major-mode font-lock-defaults-alist)))) |
1609 (keywords | 1701 (keywords |
1610 (font-lock-choose-keywords (nth 0 defaults) | 1702 (font-lock-choose-keywords (nth 0 defaults) |
1611 (font-lock-value-in-major-mode font-lock-maximum-decoration))) | 1703 (font-lock-value-in-major-mode font-lock-maximum-decoration))) |
1612 (local (cdr (assq major-mode font-lock-keywords-alist)))) | 1704 (local (cdr (assq major-mode font-lock-keywords-alist))) |
1705 (removed-keywords | |
1706 (cdr-safe (assq major-mode font-lock-removed-keywords-alist)))) | |
1613 ;; Regexp fontification? | 1707 ;; Regexp fontification? |
1614 (set (make-local-variable 'font-lock-keywords) | 1708 (set (make-local-variable 'font-lock-keywords) |
1615 (font-lock-compile-keywords (font-lock-eval-keywords keywords))) | 1709 (font-lock-compile-keywords (font-lock-eval-keywords keywords))) |
1616 ;; Local fontification? | 1710 ;; Local fontification? |
1617 (while local | 1711 (while local |
1618 (font-lock-add-keywords nil (car (car local)) (cdr (car local))) | 1712 (font-lock-add-keywords nil (car (car local)) (cdr (car local))) |
1619 (setq local (cdr local))) | 1713 (setq local (cdr local))) |
1714 (when removed-keywords | |
1715 (font-lock-remove-keywords nil removed-keywords)) | |
1620 ;; Syntactic fontification? | 1716 ;; Syntactic fontification? |
1621 (when (nth 1 defaults) | 1717 (when (nth 1 defaults) |
1622 (set (make-local-variable 'font-lock-keywords-only) t)) | 1718 (set (make-local-variable 'font-lock-keywords-only) t)) |
1623 ;; Case fold during regexp fontification? | 1719 ;; Case fold during regexp fontification? |
1624 (when (nth 2 defaults) | 1720 (when (nth 2 defaults) |
2352 "float" "double" "void" "complex")))) | 2448 "float" "double" "void" "complex")))) |
2353 c-font-lock-extra-types) | 2449 c-font-lock-extra-types) |
2354 "\\|")) | 2450 "\\|")) |
2355 (c-type-names-depth | 2451 (c-type-names-depth |
2356 `(regexp-opt-depth (,@ c-type-names))) | 2452 `(regexp-opt-depth (,@ c-type-names))) |
2453 (c-preprocessor-directives | |
2454 (eval-when-compile | |
2455 (regexp-opt | |
2456 '("define" "elif" "else" "endif" "error" "file" "if" "ifdef" | |
2457 "ifndef" "include" "line" "pragma" "undef")))) | |
2458 (c-preprocessor-directives-depth | |
2459 (regexp-opt-depth c-preprocessor-directives)) | |
2357 ) | 2460 ) |
2358 (setq c-font-lock-keywords-1 | 2461 (setq c-font-lock-keywords-1 |
2359 (list | 2462 (list |
2360 ;; | 2463 ;; |
2361 ;; These are all anchored at the beginning of line for speed. | 2464 ;; These are all anchored at the beginning of line for speed. |
2378 '("^#[ \t]*\\(elif\\|if\\)\\>" | 2481 '("^#[ \t]*\\(elif\\|if\\)\\>" |
2379 ("\\<\\(defined\\)\\>[ \t]*(?\\(\\sw+\\)?" nil nil | 2482 ("\\<\\(defined\\)\\>[ \t]*(?\\(\\sw+\\)?" nil nil |
2380 (1 font-lock-builtin-face) (2 font-lock-variable-name-face nil t))) | 2483 (1 font-lock-builtin-face) (2 font-lock-variable-name-face nil t))) |
2381 ;; | 2484 ;; |
2382 ;; Fontify otherwise as symbol names, and the preprocessor directive names. | 2485 ;; Fontify otherwise as symbol names, and the preprocessor directive names. |
2383 '("^#[ \t]*\\(\\sw+\\)\\>[ \t!]*\\(\\sw+\\)?" | 2486 (list |
2384 (1 font-lock-builtin-face) (2 font-lock-variable-name-face nil t)) | 2487 (concat "^#[ \t]*\\(" c-preprocessor-directives |
2488 "\\)\\>[ \t!]*\\(\\sw+\\)?") | |
2489 '(1 font-lock-builtin-face) | |
2490 (list (+ 2 c-preprocessor-directives-depth) | |
2491 'font-lock-variable-name-face nil t)) | |
2385 )) | 2492 )) |
2386 | 2493 |
2387 (setq c-font-lock-keywords-2 | 2494 (setq c-font-lock-keywords-2 |
2388 (append c-font-lock-keywords-1 | 2495 (append c-font-lock-keywords-1 |
2389 (list | 2496 (list |
2396 ;; | 2503 ;; |
2397 ;; Fontify all builtin keywords (except case, default and goto; see below). | 2504 ;; Fontify all builtin keywords (except case, default and goto; see below). |
2398 (concat "\\<\\(" c-keywords "\\|" c-type-specs "\\)\\>") | 2505 (concat "\\<\\(" c-keywords "\\|" c-type-specs "\\)\\>") |
2399 ;; | 2506 ;; |
2400 ;; Fontify case/goto keywords and targets, and case default/goto tags. | 2507 ;; Fontify case/goto keywords and targets, and case default/goto tags. |
2401 '("\\<\\(case\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?" | 2508 '("\\<\\(case\\|goto\\)\\>" |
2402 (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) | 2509 (1 font-lock-keyword-face) |
2510 ("\\(-[0-9]+\\|\\sw+\\)" | |
2511 ;; Return limit of search. | |
2512 (save-excursion (skip-chars-forward "^:\n") (point)) | |
2513 nil | |
2514 (1 font-lock-constant-face nil t))) | |
2403 ;; Anders Lindgren <andersl@andersl.com> points out that it is quicker to | 2515 ;; Anders Lindgren <andersl@andersl.com> points out that it is quicker to |
2404 ;; use MATCH-ANCHORED to effectively anchor the regexp on the left. | 2516 ;; use MATCH-ANCHORED to effectively anchor the regexp on the left. |
2405 ;; This must come after the one for keywords and targets. | 2517 ;; This must come after the one for keywords and targets. |
2406 '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$" | 2518 '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:[ \t]*$" |
2407 (beginning-of-line) (end-of-line) | 2519 (beginning-of-line) (end-of-line) |
2508 ;; Move over any item value, etc., to the next item. | 2620 ;; Move over any item value, etc., to the next item. |
2509 (while (not (looking-at "[ \t]*\\(\\(,\\)\\|;\\|$\\)")) | 2621 (while (not (looking-at "[ \t]*\\(\\(,\\)\\|;\\|$\\)")) |
2510 (goto-char (or (scan-sexps (point) 1) (point-max)))) | 2622 (goto-char (or (scan-sexps (point) 1) (point-max)))) |
2511 (goto-char (match-end 2))) | 2623 (goto-char (match-end 2))) |
2512 (error t))))) | 2624 (error t))))) |
2625 | |
2626 (defun font-lock-match-c++-structor-declaration (limit) | |
2627 ;; Match C++ constructors and destructors inside class declarations. | |
2628 (let ((res nil) | |
2629 (regexp (concat "^\\s-+\\(\\(virtual\\|explicit\\)\\s-+\\)*~?\\(\\<" | |
2630 (mapconcat 'identity | |
2631 c++-font-lock-extra-types "\\|") | |
2632 "\\>\\)\\s-*(" | |
2633 ;; Don't match function pointer declarations, e.g.: | |
2634 ;; Foo (*fptr)(); | |
2635 "\\s-*[^*( \t]"))) | |
2636 (while (progn (setq res (re-search-forward regexp limit t)) | |
2637 (and res | |
2638 (save-excursion | |
2639 (beginning-of-line) | |
2640 (save-match-data | |
2641 (not (vectorp (c-at-toplevel-p)))))))) | |
2642 res)) | |
2513 | 2643 |
2514 (let* ((c++-keywords | 2644 (let* ((c++-keywords |
2515 (eval-when-compile | 2645 (eval-when-compile |
2516 (regexp-opt | 2646 (regexp-opt |
2517 '("break" "continue" "do" "else" "for" "if" "return" "switch" | 2647 '("break" "continue" "do" "else" "for" "if" "return" "switch" |
2597 (list (concat "\\<\\(operator\\)\\>[ \t]*\\(" c++-operators "\\)?") | 2727 (list (concat "\\<\\(operator\\)\\>[ \t]*\\(" c++-operators "\\)?") |
2598 '(1 font-lock-keyword-face) | 2728 '(1 font-lock-keyword-face) |
2599 '(2 font-lock-builtin-face nil t)) | 2729 '(2 font-lock-builtin-face nil t)) |
2600 ;; | 2730 ;; |
2601 ;; Fontify case/goto keywords and targets, and case default/goto tags. | 2731 ;; Fontify case/goto keywords and targets, and case default/goto tags. |
2602 '("\\<\\(case\\|goto\\)\\>[ \t]*\\(-?\\sw+\\)?" | 2732 '("\\<\\(case\\|goto\\)\\>" |
2603 (1 font-lock-keyword-face) (2 font-lock-constant-face nil t)) | 2733 (1 font-lock-keyword-face) |
2734 ("\\(-[0-9]+\\|\\sw+\\)[ \t]*\\(::\\)?" | |
2735 ;; Return limit of search. | |
2736 (save-excursion | |
2737 (while (progn | |
2738 (skip-chars-forward "^:\n") | |
2739 (looking-at "::")) | |
2740 (forward-char 2)) | |
2741 (point)) | |
2742 nil | |
2743 (1 (if (match-beginning 2) | |
2744 font-lock-type-face | |
2745 font-lock-constant-face) nil t))) | |
2604 ;; This must come after the one for keywords and targets. | 2746 ;; This must come after the one for keywords and targets. |
2605 '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:\\($\\|[^:]\\)" | 2747 '(":" ("^[ \t]*\\(\\sw+\\)[ \t]*:\\($\\|[^:]\\)" |
2606 (beginning-of-line) (end-of-line) | 2748 (beginning-of-line) (end-of-line) |
2607 (1 font-lock-constant-face))) | 2749 (1 font-lock-constant-face))) |
2608 ;; | 2750 ;; |
2690 (t font-lock-variable-name-face))) | 2832 (t font-lock-variable-name-face))) |
2691 (3 font-lock-type-face nil t) | 2833 (3 font-lock-type-face nil t) |
2692 (5 (if (match-beginning 6) | 2834 (5 (if (match-beginning 6) |
2693 font-lock-function-name-face | 2835 font-lock-function-name-face |
2694 font-lock-variable-name-face) nil t))) | 2836 font-lock-variable-name-face) nil t))) |
2837 ;; | |
2838 ;; Fontify constructors and destructors inside class declarations. | |
2839 '(font-lock-match-c++-structor-declaration | |
2840 (3 font-lock-function-name-face t)) | |
2695 ))) | 2841 ))) |
2696 ) | 2842 ) |
2697 | 2843 |
2698 (defvar c++-font-lock-keywords c++-font-lock-keywords-1 | 2844 (defvar c++-font-lock-keywords c++-font-lock-keywords-1 |
2699 "Default expressions to highlight in C++ mode. | 2845 "Default expressions to highlight in C++ mode. |