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