Mercurial > hg > xemacs-beta
comparison lisp/font-lock.el @ 3655:6f7f27dd257f
[xemacs-hg @ 2006-11-01 23:14:31 by adrian]
xemacs-21.5-clean: Sync font-lock-add-keywords and font-lock-remove-keywords from GNU Emacs
-------------------- ChangeLog entries follow: --------------------
lisp/ChangeLog addition:
2006-11-02 Adrian Aichner <adrian@xemacs.org>
* font-lock.el: Sync font-lock-add-keywords and
font-lock-remove-keywords from GNU Emacs.
* font-lock.el (font-lock-keywords-alist): New.
* font-lock.el (font-lock-removed-keywords-alist): New.
* font-lock.el (font-lock-add-keywords): New.
* font-lock.el (font-lock-update-removed-keyword-alist): New.
* font-lock.el (font-lock-remove-keywords): New.
author | adrian |
---|---|
date | Wed, 01 Nov 2006 23:14:33 +0000 |
parents | bdc2d7488c19 |
children | 36e41bc4a8ab |
comparison
equal
deleted
inserted
replaced
3654:3003e38e1c10 | 3655:6f7f27dd257f |
---|---|
447 edit the buffer does not, since it considers text one line at a time. | 447 edit the buffer does not, since it considers text one line at a time. |
448 | 448 |
449 Be very careful composing regexps for this list; the wrong pattern can | 449 Be very careful composing regexps for this list; the wrong pattern can |
450 dramatically slow things down! | 450 dramatically slow things down! |
451 ") | 451 ") |
452 | |
453 (defvar font-lock-keywords-alist nil | |
454 "Alist of additional `font-lock-keywords' elements for major modes. | |
455 | |
456 Each element has the form (MODE KEYWORDS . HOW). | |
457 `font-lock-set-defaults' adds the elements in the list KEYWORDS to | |
458 `font-lock-keywords' when Font Lock is turned on in major mode MODE. | |
459 | |
460 If HOW is nil, KEYWORDS are added at the beginning of | |
461 `font-lock-keywords'. If it is `set', they are used to replace the | |
462 value of `font-lock-keywords'. If HOW is any other non-nil value, | |
463 they are added at the end. | |
464 | |
465 This is normally set via `font-lock-add-keywords' and | |
466 `font-lock-remove-keywords'.") | |
467 | |
468 (defvar font-lock-removed-keywords-alist nil | |
469 "Alist of `font-lock-keywords' elements to be removed for major modes. | |
470 | |
471 Each element has the form (MODE . KEYWORDS). `font-lock-set-defaults' | |
472 removes the elements in the list KEYWORDS from `font-lock-keywords' | |
473 when Font Lock is turned on in major mode MODE. | |
474 | |
475 This is normally set via `font-lock-add-keywords' and | |
476 `font-lock-remove-keywords'.") | |
477 | |
452 ;;;###autoload | 478 ;;;###autoload |
453 (make-variable-buffer-local 'font-lock-keywords) | 479 (make-variable-buffer-local 'font-lock-keywords) |
454 | 480 |
455 ;;;###autoload | 481 ;;;###autoload |
456 (defvar font-lock-syntactic-keywords nil | 482 (defvar font-lock-syntactic-keywords nil |
866 "Reset the font-lock patterns to a larger set of decorations." | 892 "Reset the font-lock patterns to a larger set of decorations." |
867 (and (not (eq t font-lock-maximum-decoration)) | 893 (and (not (eq t font-lock-maximum-decoration)) |
868 (setq font-lock-maximum-decoration t) | 894 (setq font-lock-maximum-decoration t) |
869 (font-lock-recompute-variables))) | 895 (font-lock-recompute-variables))) |
870 | 896 |
897 (defun font-lock-add-keywords (mode keywords &optional how) | |
898 "Add highlighting KEYWORDS for MODE. | |
899 | |
900 MODE should be a symbol, the major mode command name, such as `c-mode' | |
901 or nil. If nil, highlighting keywords are added for the current buffer. | |
902 KEYWORDS should be a list; see the variable `font-lock-keywords'. | |
903 By default they are added at the beginning of the current highlighting list. | |
904 If optional argument HOW is `set', they are used to replace the current | |
905 highlighting list. If HOW is any other non-nil value, they are added at the | |
906 end of the current highlighting list. | |
907 | |
908 For example: | |
909 | |
910 (font-lock-add-keywords 'c-mode | |
911 '((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 font-lock-warning-face prepend) | |
912 (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" . font-lock-keyword-face))) | |
913 | |
914 adds two fontification patterns for C mode, to fontify `FIXME:' words, even in | |
915 comments, and to fontify `and', `or' and `not' words as keywords. | |
916 | |
917 The above procedure will only add the keywords for C mode, not | |
918 for modes derived from C mode. To add them for derived modes too, | |
919 pass nil for MODE and add the call to c-mode-hook. | |
920 | |
921 For example: | |
922 | |
923 (add-hook 'c-mode-hook | |
924 (lambda () | |
925 (font-lock-add-keywords nil | |
926 '((\"\\\\\\=<\\\\(FIXME\\\\):\" 1 font-lock-warning-face prepend) | |
927 (\"\\\\\\=<\\\\(and\\\\|or\\\\|not\\\\)\\\\\\=>\" . | |
928 font-lock-keyword-face))))) | |
929 | |
930 The above procedure may fail to add keywords to derived modes if | |
931 some involved major mode does not follow the standard conventions. | |
932 File a bug report if this happens, so the major mode can be corrected. | |
933 | |
934 Note that some modes have specialized support for additional patterns, e.g., | |
935 see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types', | |
936 `objc-font-lock-extra-types' and `java-font-lock-extra-types'." | |
937 (cond (mode | |
938 ;; If MODE is non-nil, add the KEYWORDS and HOW spec to | |
939 ;; `font-lock-keywords-alist' so `font-lock-set-defaults' uses them. | |
940 (let ((spec (cons keywords how)) cell) | |
941 (if (setq cell (assq mode font-lock-keywords-alist)) | |
942 (if (eq how 'set) | |
943 (setcdr cell (list spec)) | |
944 (setcdr cell (append (cdr cell) (list spec)))) | |
945 (push (list mode spec) font-lock-keywords-alist))) | |
946 ;; Make sure that `font-lock-removed-keywords-alist' does not | |
947 ;; contain the new keywords. | |
948 (font-lock-update-removed-keyword-alist mode keywords how)) | |
949 (t | |
950 ;; Otherwise set or add the keywords now. | |
951 ;; This is a no-op if it has been done already in this buffer | |
952 ;; for the correct major mode. | |
953 (font-lock-set-defaults) | |
954 (let ((was-compiled (eq (car font-lock-keywords) t))) | |
955 ;; Bring back the user-level (uncompiled) keywords. | |
956 (if was-compiled | |
957 (setq font-lock-keywords (cadr font-lock-keywords))) | |
958 ;; Now modify or replace them. | |
959 (if (eq how 'set) | |
960 (setq font-lock-keywords keywords) | |
961 (font-lock-remove-keywords nil keywords) ;to avoid duplicates | |
962 (let ((old (if (eq (car-safe font-lock-keywords) t) | |
963 (cdr font-lock-keywords) | |
964 font-lock-keywords))) | |
965 (setq font-lock-keywords (if how | |
966 (append old keywords) | |
967 (append keywords old))))) | |
968 ;; If the keywords were compiled before, compile them again. | |
969 (if was-compiled | |
970 (setq font-lock-keywords | |
971 (font-lock-compile-keywords font-lock-keywords))))))) | |
972 | |
973 (defun font-lock-update-removed-keyword-alist (mode keywords how) | |
974 "Update `font-lock-removed-keywords-alist' when adding new KEYWORDS to MODE." | |
975 ;; When font-lock is enabled first all keywords in the list | |
976 ;; `font-lock-keywords-alist' are added, then all keywords in the | |
977 ;; list `font-lock-removed-keywords-alist' are removed. If a | |
978 ;; keyword was once added, removed, and then added again it must be | |
979 ;; removed from the removed-keywords list. Otherwise the second add | |
980 ;; will not take effect. | |
981 (let ((cell (assq mode font-lock-removed-keywords-alist))) | |
982 (if cell | |
983 (if (eq how 'set) | |
984 ;; A new set of keywords is defined. Forget all about | |
985 ;; our old keywords that should be removed. | |
986 (setq font-lock-removed-keywords-alist | |
987 (delq cell font-lock-removed-keywords-alist)) | |
988 ;; Delete all previously removed keywords. | |
989 (dolist (kword keywords) | |
990 (setcdr cell (delete kword (cdr cell)))) | |
991 ;; Delete the mode cell if empty. | |
992 (if (null (cdr cell)) | |
993 (setq font-lock-removed-keywords-alist | |
994 (delq cell font-lock-removed-keywords-alist))))))) | |
995 | |
996 ;; Written by Anders Lindgren <andersl@andersl.com>. | |
997 ;; | |
998 ;; Case study: | |
999 ;; (I) The keywords are removed from a major mode. | |
1000 ;; In this case the keyword could be local (i.e. added earlier by | |
1001 ;; `font-lock-add-keywords'), global, or both. | |
1002 ;; | |
1003 ;; (a) In the local case we remove the keywords from the variable | |
1004 ;; `font-lock-keywords-alist'. | |
1005 ;; | |
1006 ;; (b) The actual global keywords are not known at this time. | |
1007 ;; All keywords are added to `font-lock-removed-keywords-alist', | |
1008 ;; when font-lock is enabled those keywords are removed. | |
1009 ;; | |
1010 ;; Note that added keywords are taken out of the list of removed | |
1011 ;; keywords. This ensure correct operation when the same keyword | |
1012 ;; is added and removed several times. | |
1013 ;; | |
1014 ;; (II) The keywords are removed from the current buffer. | |
1015 (defun font-lock-remove-keywords (mode keywords) | |
1016 "Remove highlighting KEYWORDS for MODE. | |
1017 | |
1018 MODE should be a symbol, the major mode command name, such as `c-mode' | |
1019 or nil. If nil, highlighting keywords are removed for the current buffer. | |
1020 | |
1021 To make the removal apply to modes derived from MODE as well, | |
1022 pass nil for MODE and add the call to MODE-hook. This may fail | |
1023 for some derived modes if some involved major mode does not | |
1024 follow the standard conventions. File a bug report if this | |
1025 happens, so the major mode can be corrected." | |
1026 (cond (mode | |
1027 ;; Remove one keyword at the time. | |
1028 (dolist (keyword keywords) | |
1029 (let ((top-cell (assq mode font-lock-keywords-alist))) | |
1030 ;; If MODE is non-nil, remove the KEYWORD from | |
1031 ;; `font-lock-keywords-alist'. | |
1032 (when top-cell | |
1033 (dolist (keyword-list-how-pair (cdr top-cell)) | |
1034 ;; `keywords-list-how-pair' is a cons with a list of | |
1035 ;; keywords in the car top-cell and the original how | |
1036 ;; argument in the cdr top-cell. | |
1037 (setcar keyword-list-how-pair | |
1038 (delete keyword (car keyword-list-how-pair)))) | |
1039 ;; Remove keyword list/how pair when the keyword list | |
1040 ;; is empty and how doesn't specify `set'. (If it | |
1041 ;; should be deleted then previously deleted keywords | |
1042 ;; would appear again.) | |
1043 (let ((cell top-cell)) | |
1044 (while (cdr cell) | |
1045 (if (and (null (car (car (cdr cell)))) | |
1046 (not (eq (cdr (car (cdr cell))) 'set))) | |
1047 (setcdr cell (cdr (cdr cell))) | |
1048 (setq cell (cdr cell))))) | |
1049 ;; Final cleanup, remove major mode cell if last keyword | |
1050 ;; was deleted. | |
1051 (if (null (cdr top-cell)) | |
1052 (setq font-lock-keywords-alist | |
1053 (delq top-cell font-lock-keywords-alist)))) | |
1054 ;; Remember the keyword in case it is not local. | |
1055 (let ((cell (assq mode font-lock-removed-keywords-alist))) | |
1056 (if cell | |
1057 (unless (member keyword (cdr cell)) | |
1058 (nconc cell (list keyword))) | |
1059 (push (cons mode (list keyword)) | |
1060 font-lock-removed-keywords-alist)))))) | |
1061 (t | |
1062 ;; Otherwise remove it immediately. | |
1063 (font-lock-set-defaults) | |
1064 (let ((was-compiled (eq (car font-lock-keywords) t))) | |
1065 ;; Bring back the user-level (uncompiled) keywords. | |
1066 (if was-compiled | |
1067 (setq font-lock-keywords (cadr font-lock-keywords))) | |
1068 | |
1069 ;; Edit them. | |
1070 (setq font-lock-keywords (copy-sequence font-lock-keywords)) | |
1071 (dolist (keyword keywords) | |
1072 (setq font-lock-keywords | |
1073 (delete keyword font-lock-keywords))) | |
1074 | |
1075 ;; If the keywords were compiled before, compile them again. | |
1076 (if was-compiled | |
1077 (setq font-lock-keywords | |
1078 (font-lock-compile-keywords font-lock-keywords))))))) | |
871 | 1079 |
872 ;;;;;;;;;;;;;;;;;;;;;; actual code ;;;;;;;;;;;;;;;;;;;;;; | 1080 ;;;;;;;;;;;;;;;;;;;;;; actual code ;;;;;;;;;;;;;;;;;;;;;; |
873 | 1081 |
874 ;;; To fontify the whole buffer by language syntax, we go through it a | 1082 ;;; To fontify the whole buffer by language syntax, we go through it a |
875 ;;; character at a time, creating extents on the boundary of each syntactic | 1083 ;;; character at a time, creating extents on the boundary of each syntactic |