changeset 41226:170c7bb7fc74

(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.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 18 Nov 2001 02:10:01 +0000
parents 74219f3013c6
children ac4afb558628
files lisp/font-lock.el
diffstat 1 files changed, 184 insertions(+), 158 deletions(-) [+]
line wrap: on
line diff
--- 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 <andersl@andersl.com> 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'.")