aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerd Moellmann1999-12-16 15:05:06 +0000
committerGerd Moellmann1999-12-16 15:05:06 +0000
commit76f5e2afd48a91c1a2740e4d10648acf9397d638 (patch)
treed2ab7587fe99ffb6e803d995846b2d99eba4db2b
parent031999fb8042b73f8fb6aab649c0356b860f7955 (diff)
downloademacs-76f5e2afd48a91c1a2740e4d10648acf9397d638.tar.gz
emacs-76f5e2afd48a91c1a2740e4d10648acf9397d638.zip
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.
-rw-r--r--lisp/ChangeLog26
-rw-r--r--lisp/font-lock.el186
2 files changed, 192 insertions, 20 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index b071b169886..9dcd3a6c359 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,29 @@
11999-11-16 Anders Lindgren <AndersL@andersl.com>
2
3 * font-lock.el: System for adding and removing keywords.
4 Both local (previously added keyword) and global keywords
5 can be removed.
6 (font-lock-remove-keywords): New user-level function.
7 (font-lock-update-removed-keyword-alist): New internal function.
8 (font-lock-removed-keywords-alist): New variable.
9 (font-lock-add-keywords): Updates `font-lock-removed-keywords-alist'.
10 Empty `font-lock-keywords-alist' when `append' is `set' to avoid
11 growing datastructures.
12 (font-lock-set-defaults): Removes keywords stored in
13 `font-lock-removed-keywords-alist' after local keywords added.
14
151999-12-16 Anders Lindgren <andersl@andersl.com>
16
17 * font-lock.el (c-keywords, c++-keywords): Better "case" support for
18 complex constant expressions, e.g. "case 1<<A_BIT_NO:".
19
20 * font-lock.el (c-keywords): Only highlight preprocessor
21 directives when spelled correctly.
22
23 * font-lock.el (font-lock-match-c++-structor-declaration,
24 c++-keywords): Fontify constructors and destructors with function
25 face inside C++ class declarations.
26
11999-12-16 Gerd Moellmann <gerd@gnu.org> 271999-12-16 Gerd Moellmann <gerd@gnu.org>
2 28
3 * progmodes/sh-script.el (sh-mode): If there is no #!-line, use 29 * progmodes/sh-script.el (sh-mode): If there is no #!-line, use
diff --git a/lisp/font-lock.el b/lisp/font-lock.el
index cf612452105..c0dab76b0c8 100644
--- a/lisp/font-lock.el
+++ b/lisp/font-lock.el
@@ -506,7 +506,13 @@ 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'.
509This is normally set via `font-lock-add-keywords'.") 509This 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'.
514This 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.
@@ -754,13 +760,18 @@ see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types',
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)))
@@ -768,17 +779,98 @@ see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types',
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.
774A non-nil MODE is currently unsupported."
775 (setq font-lock-keywords (copy-list font-lock-keywords))
776 (dolist (keyword keywords)
777 (setq font-lock-keywords
778 (delete keyword
779 (delete (font-lock-compile-keyword keyword)
780 font-lock-keywords)))))
781 829
830MAJOR-MODE should be a symbol, the major mode command name, such as `c-mode'
831or nil. If nil, highlighting keywords are removed for the current buffer."
832 (dolist (keyword keywords)
833 ;; Remove one keyword at the time.
834 (cond (major-mode
835 (let ((top-cell (assq major-mode font-lock-keywords-alist)))
836 ;; If MAJOR-MODE is non-nil, remove the KEYWORD from
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
@@ -1609,7 +1701,9 @@ Sets various variables using `font-lock-defaults' (or, if nil, using
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)))
@@ -1617,6 +1711,8 @@ Sets various variables using `font-lock-defaults' (or, if nil, using
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))
@@ -2354,6 +2450,13 @@ See also `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
@@ -2380,8 +2483,12 @@ See also `c-font-lock-extra-types'.")
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
@@ -2398,8 +2505,13 @@ See also `c-font-lock-extra-types'.")
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.
@@ -2511,6 +2623,24 @@ See also `c++-font-lock-extra-types'.")
2511 (goto-char (match-end 2))) 2623 (goto-char (match-end 2)))
2512 (error t))))) 2624 (error t)))))
2513 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))
2643
2514(let* ((c++-keywords 2644(let* ((c++-keywords
2515 (eval-when-compile 2645 (eval-when-compile
2516 (regexp-opt 2646 (regexp-opt
@@ -2599,8 +2729,20 @@ See also `c++-font-lock-extra-types'.")
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)
@@ -2692,6 +2834,10 @@ See also `c++-font-lock-extra-types'.")
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