X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/28aa81489da5e780d3b811e17a5508af4e1d2728..49011d46973dde1c699484fbd3607df10ee78145:/lisp/font-lock.el diff --git a/lisp/font-lock.el b/lisp/font-lock.el index f6b334832d..d3017e3b3f 100644 --- a/lisp/font-lock.el +++ b/lisp/font-lock.el @@ -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 @@ -153,8 +153,8 @@ ;; ;; (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: @@ -174,8 +174,8 @@ ;; ;; 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)) ;; 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 @@ -212,8 +212,8 @@ ;; 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 @@ -281,12 +281,6 @@ If a number, only buffers greater than this size have fontification messages." (other :tag "always" t) (integer :tag "size")) :group 'font-lock) - -(defcustom font-lock-lines-before 0 - "*Number of lines before the changed text to include in refontification." - :type 'integer - :group 'font-lock - :version "22.1") ;; Originally these variable values were face names such as `bold' etc. @@ -723,8 +717,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 +824,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))))))) ;;; Font Lock Support mode. @@ -980,6 +974,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 +982,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 +996,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) @@ -1040,7 +1033,7 @@ a very meaningful entity to highlight.") (when font-lock-syntax-table (set-syntax-table font-lock-syntax-table)) (goto-char beg) - (setq beg (line-beginning-position (- 1 font-lock-lines-before))) + (setq beg (line-beginning-position)) ;; check to see if we should expand the beg/end area for ;; proper multiline matches (when (and (> beg (point-min)) @@ -1091,13 +1084,17 @@ what properties to clear before refontifying a region.") ;; Called when any modification is made to buffer text. (defun font-lock-after-change-function (beg end old-len) (let ((inhibit-point-motion-hooks t) - (inhibit-quit t)) + (inhibit-quit t) + (region (font-lock-extend-region beg end old-len))) (save-excursion (save-match-data - ;; Rescan between start of lines enclosing the region. - (font-lock-fontify-region - (progn (goto-char beg) (forward-line 0) (point)) - (progn (goto-char end) (forward-line 1) (point))))))) + (if region + ;; Fontify the region the major mode has specified. + (setq beg (car region) end (cdr region)) + ;; Fontify the whole lines which enclose the region. + (setq beg (progn (goto-char beg) (line-beginning-position)) + end (progn (goto-char end) (line-beginning-position 2)))) + (font-lock-fontify-region beg end))))) (defun font-lock-fontify-block (&optional arg) "Fontify some lines the way `font-lock-fontify-buffer' would. @@ -1508,6 +1505,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 +1578,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 +1646,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)))))) ;;; Colour etc. support. @@ -1957,6 +1961,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'.") + ;; Lisp. @@ -1965,14 +2041,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\\)" "\\)\\)\\>" @@ -2042,13 +2118,13 @@ This function could be MATCHER in a MATCH-ANCHORED `font-lock-keywords' item." ;; Erroneous structures. ("(\\(abort\\|assert\\|warn\\|check-type\\|cerror\\|error\\|signal\\)\\>" 1 font-lock-warning-face) ;; Words inside \\[] tend to be for `substitute-command-keys'. - ("\\\\\\\\\\[\\(\\sw+\\)]" 1 font-lock-constant-face prepend) + ("\\\\\\\\\\[\\(\\sw+\\)\\]" 1 font-lock-constant-face prepend) ;; Words inside `' tend to be symbol names. ("`\\(\\sw\\sw+\\)'" 1 font-lock-constant-face prepend) ;; 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