]> code.delx.au - gnu-emacs/blobdiff - lisp/font-lock.el
Added a few todo items.
[gnu-emacs] / lisp / font-lock.el
index f6b334832d0cb57dd0169da82479f74ab7577954..53f2df11d1d0056499fee2f44d100b1b195e1ba6 100644 (file)
@@ -1,7 +1,7 @@
 ;;; font-lock.el --- Electric font lock mode
 
 ;; Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;;   2000, 2001, 2002, 2003, 2004 2005 Free Software Foundation, Inc.
+;;   2000, 2001, 2002, 2003, 2004, 2005, 2006  Free Software Foundation, Inc.
 
 ;; Author: jwz, then rms, then sm
 ;; Maintainer: FSF
 ;;
 ;;  (add-hook 'foo-mode-hook
 ;;   (lambda ()
-;;     (make-local-variable 'font-lock-defaults)
-;;     (setq font-lock-defaults '(foo-font-lock-keywords t))))
+;;     (set (make-local-variable 'font-lock-defaults)
+;;          '(foo-font-lock-keywords t))))
 
 ;;; Adding Font Lock support for modes:
 
 ;;
 ;; and within `bar-mode' there could be:
 ;;
-;;  (make-local-variable 'font-lock-defaults)
-;;  (setq font-lock-defaults '(bar-font-lock-keywords nil t))
+;;  (set (make-local-variable 'font-lock-defaults)
+;;       '(bar-font-lock-keywords nil t))
 \f
 ;; What is fontification for?  You might say, "It's to make my code look nice."
 ;; I think it should be for adding information in the form of cues.  These cues
 ;; Define core `font-lock' group.
 (defgroup font-lock '((jit-lock custom-group))
   "Font Lock mode text highlighting package."
-  :link '(custom-manual "(emacs)Font Lock")
-  :link '(custom-manual "(elisp)Font Lock Mode")
+  :link '(custom-manual :tag "Emacs Manual" "(emacs)Font Lock")
+  :link '(custom-manual :tag "Elisp Manual" "(elisp)Font Lock Mode")
   :group 'faces)
 
 (defgroup font-lock-faces nil
@@ -723,8 +723,8 @@ see the variables `c-font-lock-extra-types', `c++-font-lock-extra-types',
                                          (append keywords old)))))
           ;; If the keywords were compiled before, compile them again.
           (if was-compiled
-              (set (make-local-variable 'font-lock-keywords)
-                   (font-lock-compile-keywords font-lock-keywords t)))))))
+              (setq font-lock-keywords
+                     (font-lock-compile-keywords font-lock-keywords t)))))))
 
 (defun font-lock-update-removed-keyword-alist (mode keywords how)
   "Update `font-lock-removed-keywords-alist' when adding new KEYWORDS to MODE."
@@ -830,8 +830,8 @@ happens, so the major mode can be corrected."
 
           ;; If the keywords were compiled before, compile them again.
           (if was-compiled
-              (set (make-local-variable 'font-lock-keywords)
-                   (font-lock-compile-keywords font-lock-keywords t)))))))
+              (setq font-lock-keywords
+                     (font-lock-compile-keywords font-lock-keywords t)))))))
 \f
 ;;; Font Lock Support mode.
 
@@ -980,6 +980,7 @@ The value of this variable is used when Font Lock mode is turned on."
 (defun font-lock-fontify-buffer ()
   "Fontify the current buffer the way the function `font-lock-mode' would."
   (interactive)
+  (font-lock-set-defaults)
   (let ((font-lock-verbose (or font-lock-verbose (interactive-p))))
     (funcall font-lock-fontify-buffer-function)))
 
@@ -987,6 +988,7 @@ The value of this variable is used when Font Lock mode is turned on."
   (funcall font-lock-unfontify-buffer-function))
 
 (defun font-lock-fontify-region (beg end &optional loudly)
+  (font-lock-set-defaults)
   (funcall font-lock-fontify-region-function beg end loudly))
 
 (defun font-lock-unfontify-region (beg end)
@@ -1000,9 +1002,6 @@ The value of this variable is used when Font Lock mode is turned on."
     (with-temp-message
        (when verbose
          (format "Fontifying %s..." (buffer-name)))
-      ;; Make sure we have the right `font-lock-keywords' etc.
-      (unless font-lock-mode
-       (font-lock-set-defaults))
       ;; Make sure we fontify etc. in the whole buffer.
       (save-restriction
        (widen)
@@ -1508,6 +1507,13 @@ Here each COMPILED is of the form (MATCHER HIGHLIGHT ...) as shown in the
 `font-lock-keywords' doc string.
 If REGEXP is non-nil, it means these keywords are used for
 `font-lock-keywords' rather than for `font-lock-syntactic-keywords'."
+  (if (not font-lock-set-defaults)
+      ;; This should never happen.  But some external packages sometimes
+      ;; call font-lock in unexpected and incorrect ways.  It's important to
+      ;; stop processing at this point, otherwise we may end up changing the
+      ;; global value of font-lock-keywords and break highlighting in many
+      ;; other buffers.
+      (error "Font-lock trying to use keywords before setting them up"))
   (if (eq (car-safe keywords) t)
       keywords
     (setq keywords
@@ -1574,9 +1580,9 @@ A LEVEL of nil is equal to a LEVEL of 0, a LEVEL of t is equal to
   (cond ((not (and (listp keywords) (symbolp (car keywords))))
         keywords)
        ((numberp level)
-        (or (nth level keywords) (car (reverse keywords))))
+        (or (nth level keywords) (car (last keywords))))
        ((eq level t)
-        (car (reverse keywords)))
+        (car (last keywords)))
        (t
         (car keywords))))
 
@@ -1642,8 +1648,8 @@ Sets various variables using `font-lock-defaults' (or, if nil, using
        (font-lock-remove-keywords nil removed-keywords))
       ;; Now compile the keywords.
       (unless (eq (car font-lock-keywords) t)
-       (set (make-local-variable 'font-lock-keywords)
-            (font-lock-compile-keywords font-lock-keywords t))))))
+       (setq font-lock-keywords
+              (font-lock-compile-keywords font-lock-keywords t))))))
 \f
 ;;; Colour etc. support.
 
@@ -1957,6 +1963,78 @@ This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item."
              (goto-char (or (scan-sexps (point) 1) (point-max))))
            (goto-char (match-end 2)))
        (error t)))))
+
+;; C preprocessor(cpp) is used outside of C, C++ and Objective-C source file.
+;; e.g. assembler code and GNU linker script in Linux kernel.
+;; `cpp-font-lock-keywords' is handy for modes for the files.
+;;
+;; Here we cannot use `regexp-opt' because because regex-opt is not preloaded
+;; while font-lock.el is preloaded to emacs. So values pre-calculated with 
+;; regexp-opt are used here.
+
+;; `cpp-font-lock-keywords-source-directives' is calculated from:
+;;
+;;         (regexp-opt
+;;          '("define"  "elif" "else" "endif" "error" "file" "if" "ifdef"
+;;            "ifndef" "include" "line" "pragma" "undef"))
+;;
+(defconst cpp-font-lock-keywords-source-directives
+  "define\\|e\\(?:l\\(?:if\\|se\\)\\|ndif\\|rror\\)\\|file\\|i\\(?:f\\(?:n?def\\)?\\|nclude\\)\\|line\\|pragma\\|undef"
+  "Regular expressoin used in `cpp-font-lock-keywords'.")
+
+;; `cpp-font-lock-keywords-source-depth' is calculated from:
+;;
+;;          (regexp-opt-depth (regexp-opt
+;;                    '("define"  "elif" "else" "endif" "error" "file" "if" "ifdef"
+;;                      "ifndef" "include" "line" "pragma" "undef")))
+;;
+(defconst cpp-font-lock-keywords-source-depth 0
+  "An integer representing regular expression depth of `cpp-font-lock-keywords-source-directives'.
+Used in `cpp-font-lock-keywords'.")
+
+(defconst cpp-font-lock-keywords
+  (let* ((directives cpp-font-lock-keywords-source-directives)
+        (directives-depth cpp-font-lock-keywords-source-depth))
+    (list
+     ;;
+     ;; Fontify error directives.
+     '("^#[ \t]*error[ \t]+\\(.+\\)" 1 font-lock-warning-face prepend)
+     ;;
+     ;; Fontify filenames in #include <...> preprocessor directives as strings.
+     '("^#[ \t]*\\(?:import\\|include\\)[ \t]*\\(<[^>\"\n]*>?\\)"
+       1 font-lock-string-face prepend)
+     ;;
+     ;; Fontify function macro names.
+     '("^#[ \t]*define[ \t]+\\([[:alpha:]_][[:alnum:]_$]*\\)(" 
+       (1 font-lock-function-name-face prepend)
+       ;;
+       ;; Macro arguments.
+       ((lambda (limit)
+         (re-search-forward
+          "\\(?:\\([[:alpha:]_][[:alnum:]_]*\\)[,]?\\)" 
+          (or (save-excursion (re-search-forward ")" limit t)) 
+              limit)
+          t)) 
+       nil nil (1 font-lock-variable-name-face prepend)))
+     ;;
+     ;; Fontify symbol names in #elif or #if ... defined preprocessor directives.
+     '("^#[ \t]*\\(?:elif\\|if\\)\\>"
+       ("\\<\\(defined\\)\\>[ \t]*(?\\([[:alpha:]_][[:alnum:]_]*\\)?" nil nil
+       (1 font-lock-builtin-face prepend) (2 font-lock-variable-name-face prepend t)))
+     ;;
+     ;; Fontify otherwise as symbol names, and the preprocessor directive names.
+     (list
+      (concat "^\\(#[ \t]*\\(?:" directives
+             "\\)\\)\\>[ \t!]*\\([[:alpha:]_][[:alnum:]_]*\\)?")
+      '(1 font-lock-preprocessor-face prepend)
+      (list (+ 2 directives-depth)
+           'font-lock-variable-name-face nil t))))
+    "Font lock keyords for C preprocessor directives.
+`c-mode', `c++-mode' and `objc-mode' have their own 
+font lock keyords for C preprocessor directives. This definition is for the
+other modes in which C preprocessor directives are used. e.g. `asm-mode' and
+`ld-script-mode'.")
+
 \f
 ;; Lisp.
 
@@ -1965,14 +2043,14 @@ This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item."
     `(;; Definitions.
       (,(concat "(\\(def\\("
                ;; Function declarations.
-               "\\(advice\\|varalias\\|alias\\|generic\\|macro\\*?\\|method\\|"
+               "\\(advice\\|alias\\|generic\\|macro\\*?\\|method\\|"
                "setf\\|subst\\*?\\|un\\*?\\|"
                "ine-\\(condition\\|"
                "\\(?:derived\\|\\(?:global-\\)?minor\\|generic\\)-mode\\|"
                "method-combination\\|setf-expander\\|skeleton\\|widget\\|"
                "function\\|\\(compiler\\|modify\\|symbol\\)-macro\\)\\)\\|"
                ;; Variable declarations.
-               "\\(const\\(ant\\)?\\|custom\\|face\\|parameter\\|var\\)\\|"
+               "\\(const\\(ant\\)?\\|custom\\|varalias\\|face\\|parameter\\|var\\)\\|"
                ;; Structure declarations.
                "\\(class\\|group\\|theme\\|package\\|struct\\|type\\)"
                "\\)\\)\\>"
@@ -2048,7 +2126,7 @@ This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item."
        ;; Constant values.
        ("\\<:\\sw+\\>" 0 font-lock-builtin-face)
        ;; ELisp and CLisp `&' keywords as types.
-       ("\\&\\sw+\\>" . font-lock-type-face)
+       ("\\<\\&\\sw+\\>" . font-lock-type-face)
        ;; ELisp regexp grouping constructs
        ((lambda (bound)
           (catch 'found