# HG changeset patch # User Stefan Monnier # Date 1006049401 0 # Node ID 170c7bb7fc74e52328db8b2da0c3f7ff6401f9cb # Parent 74219f3013c685245686c15333d42931d56f4220 (font-lock-compile-keywords): New arg `regexp'. If set and if applicable, add a regexp to highlight defun-like text inside comments and strings. (font-lock-fontify-keywords-region): Pass that new arg. (font-lock-set-defaults): Move the code to set `font-lock-keywords' to the end and pass that new arg. (c-font-lock-keywords-2): Fix regex for labels. (font-lock-match-c++-style-declaration-item-and-skip-to-next): Make it work when LIMIT is several lines further. (c-font-lock-keywords-3, c++-font-lock-keywords-3) (objc-font-lock-keywords-3, java-font-lock-keywords-3): Use backquote and make the regexes for `int a, b, c;' work on multiple lines. diff -r 74219f3013c6 -r 170c7bb7fc74 lisp/font-lock.el --- a/lisp/font-lock.el Sun Nov 18 01:44:08 2001 +0000 +++ b/lisp/font-lock.el Sun Nov 18 02:10:01 2001 +0000 @@ -1631,7 +1631,8 @@ "Fontify according to `font-lock-keywords' between START and END. START should be at the beginning of a line." (unless (eq (car font-lock-keywords) t) - (setq font-lock-keywords (font-lock-compile-keywords font-lock-keywords))) + (setq font-lock-keywords + (font-lock-compile-keywords font-lock-keywords t))) (let ((case-fold-search font-lock-keywords-case-fold-search) (keywords (cdr font-lock-keywords)) (bufname (buffer-name)) (count 0) @@ -1677,13 +1678,33 @@ ;; Various functions. -(defun font-lock-compile-keywords (keywords) +(defun font-lock-compile-keywords (keywords &optional regexp) "Compile KEYWORDS into the form (t KEYWORD ...). Here KEYWORD is of the form (MATCHER HIGHLIGHT ...) as shown in the -`font-lock-keywords' doc string." +`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 (eq (car-safe keywords) t) keywords - (cons t (mapcar 'font-lock-compile-keyword keywords)))) + (setq keywords (cons t (mapcar 'font-lock-compile-keyword keywords))) + (if (and regexp + (eq (or syntax-begin-function + font-lock-beginning-of-syntax-function) + 'beginning-of-defun) + (not beginning-of-defun-function)) + ;; Try to detect when a string or comment contains something that + ;; looks like a defun and would thus confuse font-lock. + (nconc keywords + `((,(if defun-prompt-regexp + (concat "^\\(?:" defun-prompt-regexp "\\)?\\s(") + "^\\s(") + (0 + (if (memq (get-text-property (point) 'face) + '(font-lock-string-face font-lock-doc-face + font-lock-comment-face)) + font-lock-warning-face) + prepend))))) + keywords)) (defun font-lock-compile-keyword (keyword) (cond ((nlistp keyword) ; MATCHER @@ -1753,15 +1774,6 @@ (local (cdr (assq major-mode font-lock-keywords-alist))) (removed-keywords (cdr-safe (assq major-mode font-lock-removed-keywords-alist)))) - ;; Regexp fontification? - (set (make-local-variable 'font-lock-keywords) - (font-lock-compile-keywords (font-lock-eval-keywords keywords))) - ;; Local fontification? - (while local - (font-lock-add-keywords nil (car (car local)) (cdr (car local))) - (setq local (cdr local))) - (when removed-keywords - (font-lock-remove-keywords nil removed-keywords)) ;; Syntactic fontification? (when (nth 1 defaults) (set (make-local-variable 'font-lock-keywords-only) t)) @@ -1785,7 +1797,18 @@ (nth 4 defaults))) ;; Variable alist? (dolist (x (nthcdr 5 defaults)) - (set (make-local-variable (car x)) (cdr x)))))) + (set (make-local-variable (car x)) (cdr x))) + ;; Setup `font-lock-keywords' last because its value might depend + ;; on other settings (e.g. font-lock-compile-keywords uses + ;; font-lock-beginning-of-syntax-function). + (set (make-local-variable 'font-lock-keywords) + (font-lock-compile-keywords (font-lock-eval-keywords keywords) t)) + ;; Local fontification? + (while local + (font-lock-add-keywords nil (car (car local)) (cdr (car local))) + (setq local (cdr local))) + (when removed-keywords + (font-lock-remove-keywords nil removed-keywords))))) ;;; Colour etc. support. @@ -2344,7 +2367,10 @@ ;; Anders Lindgren points out that it is quicker ;; to use MATCH-ANCHORED to effectively anchor the regexp on the left. ;; This must come after the one for keywords and targets. - '(":" ("\\(\\sw+\\)[ \t]*:" + ;; Note: the lack of `:' in the first char-range prevents `bar' from being + ;; highlighted in "foo: bar:". But adding `:' would break cases like + ;; "test1 ? test2 ? foo : bar : baz". + '(":" ("\\(?:^\\|[{};]\\)[ \t]*\\(\\sw+\\)[ \t]*:" (beginning-of-line) (end-of-line) (1 font-lock-constant-face))) )) @@ -2362,47 +2388,47 @@ (list (concat "\\<\\(" ,c-type-names "\\)\\>" "\\([ \t*&]+\\sw+\\>\\)*") ;; Fontify each declaration item. - (list 'font-lock-match-c-style-declaration-item-and-skip-to-next - ;; Start with point after all type specifiers. - (list 'goto-char (list 'or - (list 'match-beginning - (+ ,c-type-names-depth 2)) - '(match-end 1))) - ;; Finish with point after first type specifier. - '(goto-char (match-end 1)) - ;; Fontify as a variable or function name. - '(1 (if (match-beginning 2) - font-lock-function-name-face - font-lock-variable-name-face))))) + `(font-lock-match-c-style-declaration-item-and-skip-to-next + ;; Start with point after all type specifiers. + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (or (match-beginning + ,(+ ,c-type-names-depth 2)) + (match-end 1)))) + ;; Finish with point after first type specifier. + (goto-char (match-end 1)) + ;; Fontify as a variable or function name. + (1 (if (match-beginning 2) + font-lock-function-name-face + font-lock-variable-name-face))))) ;; ;; Fontify all storage specs and types, plus their items. - `(eval . - (list (concat "\\<\\(" ,c-type-specs "\\)\\>" - "[ \t]*\\(\\sw+\\)?") - (list 1 'font-lock-keyword-face) - (list ,(+ c-type-specs-depth 2) 'font-lock-type-face nil t) - (list 'font-lock-match-c-style-declaration-item-and-skip-to-next - nil - ;; Finish with point after the variable name if - ;; there is one. - `(if (match-end 2) - (goto-char (match-end 2))) - ;; Fontify as a variable or function name. - '(1 (if (match-beginning 2) - font-lock-function-name-face - font-lock-variable-name-face) nil t)))) + `(,(concat "\\<\\(" c-type-specs "\\)\\>" "[ \t]*\\(\\sw+\\)?") + (1 font-lock-keyword-face) + (,(+ c-type-specs-depth 2) font-lock-type-face nil t) + (font-lock-match-c-style-declaration-item-and-skip-to-next + (save-excursion (skip-chars-forward "^;{}") (point)) + ;; Finish with point after the variable name if + ;; there is one. + (if (match-end 2) + (goto-char (match-end 2))) + ;; Fontify as a variable or function name. + (1 (if (match-beginning 2) + font-lock-function-name-face + font-lock-variable-name-face) nil t))) ;; ;; Fontify structures, or typedef names, plus their items. '("\\(}\\)[ \t*]*\\sw" (font-lock-match-c-style-declaration-item-and-skip-to-next - (goto-char (match-end 1)) nil + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (match-end 1))) nil (1 font-lock-type-face))) ;; ;; Fontify anything at beginning of line as a declaration or definition. '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*" (1 font-lock-type-face) (font-lock-match-c-style-declaration-item-and-skip-to-next - (goto-char (or (match-beginning 2) (match-end 1))) nil + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (or (match-beginning 2) (match-end 1)))) nil (1 (if (match-beginning 2) font-lock-function-name-face font-lock-variable-name-face)))) @@ -2441,13 +2467,13 @@ (when (looking-at (eval-when-compile (concat ;; Skip any leading whitespace. - "[ \t*&]*" + "[ \t\n*&]*" ;; This is `c++-type-spec' from below. (Hint hint!) "\\(\\sw+\\)" ; The instance? - "\\([ \t]*<\\(\\(?:[^<>\n]\\|<[^>\n]+>\\)+\\)[ \t*&]*>\\)?" ; Or template? - "\\([ \t]*::[ \t*~]*\\(\\sw+\\)\\)*" ; Or member? + "\\([ \t\n]*<\\(\\(?:[^<>]\\|<[^>]+>\\)+\\)[ \t\n*&]*>\\)?" ; Or template? + "\\([ \t\n]*::[ \t\n*~]*\\(\\sw+\\)\\)*" ; Or member? ;; Match any trailing parenthesis. - "[ \t]*\\((\\)?"))) + "[ \t\n]*\\((\\)?"))) (save-match-data (condition-case nil (save-restriction @@ -2455,7 +2481,7 @@ (narrow-to-region (point-min) limit) (goto-char (match-end 1)) ;; Move over any item value, etc., to the next item. - (while (not (looking-at "[ \t]*\\(\\(,\\)\\|;\\|$\\)")) + (while (not (looking-at "[ \t\n]*\\(\\(,\\)\\|;\\|\\'\\)")) (goto-char (or (scan-sexps (point) 1) (point-max)))) (goto-char (match-end 2))) (error t))))) @@ -2609,74 +2635,75 @@ (list (concat "\\<\\(" ,c++-type-names "\\)\\>" ,c++-type-suffix "\\([ \t*&]+" ,c++-type-spec "\\)*") ;; The name of any template type. - (list (+ ,c++-type-names-depth 3) 'font-lock-type-face nil t) + `(,(+ ,c++-type-names-depth 3) font-lock-type-face nil t) ;; Fontify each declaration item. - (list 'font-lock-match-c++-style-declaration-item-and-skip-to-next - ;; Start with point after all type specifiers. - (list 'goto-char (list 'or (list 'match-beginning - (+ ,c++-type-depth 2)) - '(match-end 1))) - ;; Finish with point after first type specifier. - '(goto-char (match-end 1)) - ;; Fontify as a variable or function name. - '(1 (cond ((or (match-beginning 2) (match-beginning 4)) - font-lock-type-face) - ((and (match-beginning 6) (c-at-toplevel-p)) - font-lock-function-name-face) - (t - font-lock-variable-name-face))) - '(3 font-lock-type-face nil t) - '(5 (if (match-beginning 6) - font-lock-function-name-face - font-lock-variable-name-face) nil t)))) + `(font-lock-match-c++-style-declaration-item-and-skip-to-next + ;; Start with point after all type specifiers. + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (or (match-beginning + ,(+ ,c++-type-depth 2)) + (match-end 1)))) + ;; Finish with point after first type specifier. + (goto-char (match-end 1)) + ;; Fontify as a variable or function name. + (1 (cond ((or (match-beginning 2) (match-beginning 4)) + font-lock-type-face) + ((and (match-beginning 6) (c-at-toplevel-p)) + font-lock-function-name-face) + (t + font-lock-variable-name-face))) + (3 font-lock-type-face nil t) + (5 (if (match-beginning 6) + font-lock-function-name-face + font-lock-variable-name-face) nil t)))) ;; ;; Fontify all storage specs and types, plus their items. - `(eval . - (list (concat "\\<" ,c++-type-specs "\\>" ,c++-type-suffix - "[ \t]*\\(" ,c++-type-spec "\\)?") - ;; The name of any template type. - (list ,(+ c++-type-specs-depth 2) 'font-lock-type-face nil t) - ;; The name of any type. - (list (+ ,c++-type-specs-depth ,c++-type-suffix-depth 2) - 'font-lock-type-face nil t) - ;; Fontify each declaration item. - (list 'font-lock-match-c++-style-declaration-item-and-skip-to-next - ;; Start with point after all type specifiers. - nil - ;; Finish with point after first type specifier. - nil - ;; Fontify as a variable or function name. - '(1 (cond ((or (match-beginning 2) (match-beginning 4)) - font-lock-type-face) - ((and (match-beginning 6) (c-at-toplevel-p)) - font-lock-function-name-face) - (t - font-lock-variable-name-face))) - '(3 font-lock-type-face nil t) - '(5 (if (match-beginning 6) - font-lock-function-name-face - font-lock-variable-name-face) nil t)) - )) + `(,(concat "\\<" c++-type-specs "\\>" c++-type-suffix + "[ \t]*\\(" c++-type-spec "\\)?") + ;; The name of any template type. + (,(+ c++-type-specs-depth 2) 'font-lock-type-face nil t) + ;; The name of any type. + (,(+ c++-type-specs-depth c++-type-suffix-depth 2) + font-lock-type-face nil t) + ;; Fontify each declaration item. + (font-lock-match-c++-style-declaration-item-and-skip-to-next + ;; Start with point after all type specifiers. + (save-excursion (skip-chars-forward "^;{}") (point)) + ;; Finish with point after first type specifier. + nil + ;; Fontify as a variable or function name. + (1 (cond ((or (match-beginning 2) (match-beginning 4)) + font-lock-type-face) + ((and (match-beginning 6) (c-at-toplevel-p)) + font-lock-function-name-face) + (t + font-lock-variable-name-face))) + (3 font-lock-type-face nil t) + (5 (if (match-beginning 6) + font-lock-function-name-face + font-lock-variable-name-face) nil t))) ;; ;; Fontify structures, or typedef names, plus their items. '("\\(}\\)[ \t*]*\\sw" (font-lock-match-c++-style-declaration-item-and-skip-to-next - (goto-char (match-end 1)) nil + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (match-end 1))) nil (1 font-lock-type-face))) ;; ;; Fontify anything at beginning of line as a declaration or definition. - (list (concat "^\\(" c++-type-spec "[ \t*&]*\\)+") - '(font-lock-match-c++-style-declaration-item-and-skip-to-next - (goto-char (match-beginning 1)) - (goto-char (match-end 1)) - (1 (cond ((or (match-beginning 2) (match-beginning 4)) - font-lock-type-face) - ((match-beginning 6) font-lock-function-name-face) - (t font-lock-variable-name-face))) - (3 font-lock-type-face nil t) - (5 (if (match-beginning 6) - font-lock-function-name-face - font-lock-variable-name-face) nil t))) + `(,(concat "^\\(" c++-type-spec "[ \t*&]*\\)+") + (font-lock-match-c++-style-declaration-item-and-skip-to-next + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (match-beginning 1))) + (goto-char (match-end 1)) + (1 (cond ((or (match-beginning 2) (match-beginning 4)) + font-lock-type-face) + ((match-beginning 6) font-lock-function-name-face) + (t font-lock-variable-name-face))) + (3 font-lock-type-face nil t) + (5 (if (match-beginning 6) + font-lock-function-name-face + font-lock-variable-name-face) nil t))) ;; ;; Fontify constructors and destructors inside class declarations. '(font-lock-match-c++-structor-declaration @@ -2791,45 +2818,44 @@ (list (concat "\\<\\(" ,objc-type-names "\\)\\>" "\\([ \t*&]+\\sw+\\>\\)*") ;; Fontify each declaration item. - (list 'font-lock-match-c-style-declaration-item-and-skip-to-next - ;; Start with point after all type specifiers. - (list 'goto-char - (list 'or (list 'match-beginning - (+ ,objc-type-names-depth 2)) - '(match-end 1))) - ;; Finish with point after first type specifier. - '(goto-char (match-end 1)) - ;; Fontify as a variable or function name. - '(1 (if (match-beginning 2) - font-lock-function-name-face - font-lock-variable-name-face))))) + `(font-lock-match-c-style-declaration-item-and-skip-to-next + ;; Start with point after all type specifiers. + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (or (match-beginning + ,(+ ,objc-type-names-depth 2)) + (match-end 1)))) + ;; Finish with point after first type specifier. + (goto-char (match-end 1)) + ;; Fontify as a variable or function name. + (1 (if (match-beginning 2) + font-lock-function-name-face + font-lock-variable-name-face))))) ;; ;; Fontify all storage specs and types, plus their items. - `(eval . - (list (concat "\\<\\(" ,objc-type-specs "[ \t]*\\)+\\>" - "[ \t]*\\(\\sw+\\)?") - ;; The name of any type. - (list ,(+ objc-type-specs-depth 2) 'font-lock-type-face nil t) - ;; Fontify each declaration item. - (list 'font-lock-match-c++-style-declaration-item-and-skip-to-next - nil nil - ;; Fontify as a variable or function name. - '(1 (if (match-beginning 2) - font-lock-function-name-face - font-lock-variable-name-face))) - )) + `(,(concat "\\<\\(" objc-type-specs "[ \t]*\\)+\\>" "[ \t]*\\(\\sw+\\)?") + ;; The name of any type. + (,(+ objc-type-specs-depth 2) font-lock-type-face nil t) + ;; Fontify each declaration item. + (font-lock-match-c++-style-declaration-item-and-skip-to-next + (save-excursion (skip-chars-forward "^;{}") (point)) nil + ;; Fontify as a variable or function name. + (1 (if (match-beginning 2) + font-lock-function-name-face + font-lock-variable-name-face)))) ;; ;; Fontify structures, or typedef names, plus their items. '("\\(}\\)[ \t*]*\\sw" (font-lock-match-c-style-declaration-item-and-skip-to-next - (goto-char (match-end 1)) nil + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (match-end 1))) nil (1 font-lock-type-face))) ;; ;; Fontify anything at beginning of line as a declaration or definition. '("^\\(\\sw+\\)\\>\\([ \t*]+\\sw+\\>\\)*" (1 font-lock-type-face) (font-lock-match-c-style-declaration-item-and-skip-to-next - (goto-char (or (match-beginning 2) (match-end 1))) nil + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (or (match-beginning 2) (match-end 1)))) nil (1 (if (match-beginning 2) font-lock-function-name-face font-lock-variable-name-face)))) @@ -2949,32 +2975,32 @@ "\\([ \t]*\\[[ \t]*\\]\\)*" "\\([ \t]*\\sw\\)") ;; Fontify each declaration item. - (list 'font-lock-match-c-style-declaration-item-and-skip-to-next - ;; Start and finish with point after the type specifier. - (list 'goto-char (list 'match-beginning - (+ ,java-type-names-depth 3))) - (list 'goto-char (list 'match-beginning - (+ ,java-type-names-depth 3))) - ;; Fontify as a variable or function name. - '(1 (if (match-beginning 2) - font-lock-function-name-face - font-lock-variable-name-face))))) + `(font-lock-match-c-style-declaration-item-and-skip-to-next + ;; Start and finish with point after the type specifier. + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (match-beginning ,(+ ,java-type-names-depth 3)))) + (goto-char (match-beginning ,(+ ,java-type-names-depth 3))) + ;; Fontify as a variable or function name. + (1 (if (match-beginning 2) + font-lock-function-name-face + font-lock-variable-name-face))))) ;; ;; Fontify those that are eventually followed by an item or items. - (list (concat "\\<\\(" java-type-specs "\\)\\>" - "\\([ \t]+\\sw+\\>" - "\\([ \t]*\\[[ \t]*\\]\\)*" - "\\)*") - ;; Fontify each declaration item. - '(font-lock-match-c-style-declaration-item-and-skip-to-next - ;; Start with point after all type specifiers. - (goto-char (or (match-beginning 5) (match-end 1))) - ;; Finish with point after first type specifier. - (goto-char (match-end 1)) - ;; Fontify as a variable or function name. - (1 (if (match-beginning 2) - font-lock-function-name-face - font-lock-variable-name-face)))) + `(,(concat "\\<\\(" java-type-specs "\\)\\>" + "\\([ \t]+\\sw+\\>" + "\\([ \t]*\\[[ \t]*\\]\\)*" + "\\)*") + ;; Fontify each declaration item. + (font-lock-match-c-style-declaration-item-and-skip-to-next + ;; Start with point after all type specifiers. + (prog1 (progn (skip-chars-forward "^;{}") (point)) + (goto-char (or (match-beginning 5) (match-end 1)))) + ;; Finish with point after first type specifier. + (goto-char (match-end 1)) + ;; Fontify as a variable or function name. + (1 (if (match-beginning 2) + font-lock-function-name-face + font-lock-variable-name-face)))) )) "Gaudy level highlighting for Java mode. See also `java-font-lock-extra-types'.")