diff options
Diffstat (limited to 'lisp/progmodes/cc-fonts.el')
-rw-r--r-- | lisp/progmodes/cc-fonts.el | 649 |
1 files changed, 428 insertions, 221 deletions
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index d8643677192..c213f1f198e 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -723,6 +723,10 @@ casts and declarations are fontified. Used on level 2 and higher." (concat ".\\(" c-string-limit-regexp "\\)") '((c-font-lock-invalid-string))) + ;; Fontify C++ raw strings. + ,@(when (c-major-mode-is 'c++-mode) + '(c-font-lock-raw-strings)) + ;; Fontify keyword constants. ,@(when (c-lang-const c-constant-kwds) (let ((re (c-make-keywords-re nil (c-lang-const c-constant-kwds)))) @@ -895,7 +899,8 @@ casts and declarations are fontified. Used on level 2 and higher." (c-get-char-property (1- (point)) 'c-type))))) (when (memq prop '(c-decl-id-start c-decl-type-start)) (c-forward-syntactic-ws limit) - (c-font-lock-declarators limit t (eq prop 'c-decl-type-start)))) + (c-font-lock-declarators limit t (eq prop 'c-decl-type-start) + (c-bs-at-toplevel-p (point))))) (setq c-font-lock-context ;; (c-guess-font-lock-context) (save-excursion @@ -987,7 +992,7 @@ casts and declarations are fontified. Used on level 2 and higher." (goto-char pos))))) nil) -(defun c-font-lock-declarators (limit list types) +(defun c-font-lock-declarators (limit list types not-top) ;; Assuming the point is at the start of a declarator in a declaration, ;; fontify the identifier it declares. (If TYPES is set, it does this via ;; the macro `c-fontify-types-and-refs'.) @@ -997,7 +1002,9 @@ casts and declarations are fontified. Used on level 2 and higher." ;; additionally, mark the commas with c-type property 'c-decl-id-start or ;; 'c-decl-type-start (according to TYPES). Stop at LIMIT. ;; - ;; If TYPES is non-nil, fontify all identifiers as types. + ;; If TYPES is non-nil, fontify all identifiers as types. If NOT-TOP is + ;; non-nil, we are not at the top-level ("top-level" includes being directly + ;; inside a class or namespace, etc.). ;; ;; Nil is always returned. The function leaves point at the delimiter after ;; the last declarator it processes. @@ -1021,6 +1028,14 @@ casts and declarations are fontified. Used on level 2 and higher." (setq next-pos (point) id-start (car decl-res) id-face (if (and (eq (char-after) ?\() + (or (not (c-major-mode-is 'c++-mode)) + (not not-top) + (car (cddr (cddr decl-res))) ; Id is in + ; parens, etc. + (save-excursion + (forward-char) + (c-forward-syntactic-ws) + (looking-at "[*&]"))) (not (car (cddr decl-res))) ; brackets-after-id (or (not (c-major-mode-is 'c++-mode)) (save-excursion @@ -1162,7 +1177,8 @@ casts and declarations are fontified. Used on level 2 and higher." ;; `parse-sexp-lookup-properties' (when it exists). (parse-sexp-lookup-properties (cc-eval-when-compile - (boundp 'parse-sexp-lookup-properties)))) + (boundp 'parse-sexp-lookup-properties)) + )) ;; Below we fontify a whole declaration even when it crosses the limit, ;; to avoid gaps when jit/lazy-lock fontifies the file a block at a @@ -1194,13 +1210,14 @@ casts and declarations are fontified. Used on level 2 and higher." c-decl-start-re (eval c-maybe-decl-faces) - (lambda (match-pos inside-macro) + (lambda (match-pos inside-macro &optional toplev) ;; Note to maintainers: don't use `limit' inside this lambda form; ;; c-find-decl-spots sometimes narrows to less than `limit'. (setq start-pos (point)) (when ;; The result of the form below is true when we don't recognize a - ;; declaration or cast. + ;; declaration or cast, and we don't recognize a "non-decl", + ;; typically a brace list. (if (or (and (eq (get-text-property (point) 'face) 'font-lock-keyword-face) (looking-at c-not-decl-init-keywords)) @@ -1216,8 +1233,8 @@ casts and declarations are fontified. Used on level 2 and higher." ;; (e.g. "for ("). (let ((type (and (> match-pos (point-min)) (c-get-char-property (1- match-pos) 'c-type)))) - (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?<))) - (setq context nil + (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?< ?{))) + (setq context (and toplev 'top) c-restricted-<>-arglists nil)) ;; A control flow expression or a decltype ((and (eq (char-before match-pos) ?\() @@ -1238,6 +1255,37 @@ casts and declarations are fontified. Used on level 2 and higher." ((eq type 'c-decl-arg-start) (setq context 'decl c-restricted-<>-arglists nil)) + ;; We're inside (probably) a brace list. + ((eq type 'c-not-decl) + (setq context 'not-decl + c-restricted-<>-arglists nil)) + ;; Inside a C++11 lambda function arglist. + ((and (c-major-mode-is 'c++-mode) + (eq (char-before match-pos) ?\() + (save-excursion + (goto-char match-pos) + (c-backward-token-2) + (and + (c-safe (goto-char (scan-sexps (point) -1))) + (c-looking-at-c++-lambda-capture-list)))) + (setq context 'decl + c-restricted-<>-arglists nil) + (c-put-char-property (1- match-pos) 'c-type + 'c-decl-arg-start)) + ;; We're inside a brace list. + ((and (eq (char-before match-pos) ?{) + (save-excursion + (goto-char (1- match-pos)) + (consp + (c-looking-at-or-maybe-in-bracelist)))) + (setq context 'not-decl + c-restricted-<>-arglists nil) + (c-put-char-property (1- match-pos) 'c-type + 'c-not-decl)) + ;; We're inside an "ordinary" open brace. + ((eq (char-before match-pos) ?{) + (setq context (and toplev 'top) + c-restricted-<>-arglists nil)) ;; Inside an angle bracket arglist. ((or (eq type 'c-<>-arg-sep) (eq (char-before match-pos) ?<)) @@ -1263,6 +1311,13 @@ casts and declarations are fontified. Used on level 2 and higher." ;; multiline declaration. (c-put-char-property (1- match-pos) 'c-type 'c-decl-arg-start)) + ;; Got an open paren preceded by an arith operator. + ((and (eq (char-before match-pos) ?\() + (save-excursion + (and (zerop (c-backward-token-2 2)) + (looking-at c-arithmetic-op-regexp)))) + (setq context nil + c-restricted-<>-arglists nil)) (t (setq context 'arglist c-restricted-<>-arglists t)))) @@ -1283,182 +1338,132 @@ casts and declarations are fontified. Used on level 2 and higher." (c-forward-syntactic-ws)) ;; Now analyze the construct. - (setq decl-or-cast (c-forward-decl-or-cast-1 - match-pos context last-cast-end)) - - ;; Ensure that c-<>-arg-sep c-type properties are in place on the - ;; commas separating the arguments inside template/generic <..>s. - (when (and (eq (char-before match-pos) ?<) - (> match-pos max-<>-end)) - (save-excursion - (goto-char match-pos) - (c-backward-token-2) - (if (and - (eq (char-after) ?<) - (let ((c-restricted-<>-arglists - (save-excursion - (c-backward-token-2) - (and - (not (looking-at c-opt-<>-sexp-key)) - (progn (c-backward-syntactic-ws) - (memq (char-before) '(?\( ?,))) - (not (eq (c-get-char-property (1- (point)) - 'c-type) - 'c-decl-arg-start)))))) - (c-forward-<>-arglist nil))) - (setq max-<>-end (point))))) - - (cond - ((eq decl-or-cast 'cast) - ;; Save the position after the previous cast so we can feed - ;; it to `c-forward-decl-or-cast-1' in the next round. That - ;; helps it discover cast chains like "(a) (b) c". - (setq last-cast-end (point)) - (c-fontify-recorded-types-and-refs) - nil) - - (decl-or-cast - ;; We've found a declaration. - - ;; Set `max-type-decl-end' or `max-type-decl-end-before-token' - ;; under the assumption that we're after the first type decl - ;; expression in the declaration now. That's not really true; - ;; we could also be after a parenthesized initializer - ;; expression in C++, but this is only used as a last resort - ;; to slant ambiguous expression/declarations, and overall - ;; it's worth the risk to occasionally fontify an expression - ;; as a declaration in an initializer expression compared to - ;; getting ambiguous things in normal function prototypes - ;; fontified as expressions. - (if inside-macro - (when (> (point) max-type-decl-end-before-token) - (setq max-type-decl-end-before-token (point))) - (when (> (point) max-type-decl-end) - (setq max-type-decl-end (point)))) - - ;; Back up to the type to fontify the declarator(s). - (goto-char (car decl-or-cast)) - - (let ((decl-list - (if context - ;; Should normally not fontify a list of - ;; declarators inside an arglist, but the first - ;; argument in the ';' separated list of a "for" - ;; statement is an exception. - (when (eq (char-before match-pos) ?\() - (save-excursion - (goto-char (1- match-pos)) - (c-backward-syntactic-ws) - (and (c-simple-skip-symbol-backward) - (looking-at c-paren-stmt-key)))) - t))) - - ;; Fix the `c-decl-id-start' or `c-decl-type-start' property - ;; before the first declarator if it's a list. - ;; `c-font-lock-declarators' handles the rest. - (when decl-list - (save-excursion - (c-backward-syntactic-ws) - (unless (bobp) - (c-put-char-property (1- (point)) 'c-type - (if (cdr decl-or-cast) - 'c-decl-type-start - 'c-decl-id-start))))) - - (c-font-lock-declarators - (point-max) decl-list (cdr decl-or-cast))) - - ;; A declaration has been successfully identified, so do all the - ;; fontification of types and refs that've been recorded. - (c-fontify-recorded-types-and-refs) - nil) - - ;; Restore point, since at this point in the code it has been - ;; left undefined by c-forward-decl-or-cast-1 above. - ((progn (goto-char start-pos) nil)) - - ;; If point is inside a bracelist, there's no point checking it - ;; being at a declarator. - ((let ((paren-state (c-parse-state))) - (setq lbrace (c-cheap-inside-bracelist-p paren-state))) - ;; Move past this bracelist to prevent an endless loop. - (goto-char lbrace) - (unless (c-safe (progn (forward-list) t)) - (goto-char start-pos) - (c-forward-token-2)) - nil) - - ;; If point is just after a ")" which is followed by an - ;; identifier which isn't a label, or at the matching "(", we're - ;; at either a macro invocation, a cast, or a - ;; for/while/etc. statement. The cast case is handled above. - ;; None of these cases can contain a declarator. - ((or (and (eq (char-before match-pos) ?\)) - (c-on-identifier) - (save-excursion (not (c-forward-label)))) - (and (eq (char-after) ?\() - (save-excursion - (and - (progn (c-backward-token-2) (c-on-identifier)) - (save-excursion (not (c-forward-label))) - (progn (c-backward-token-2) - (eq (char-after) ?\()))))) - (c-forward-token-2) ; Must prevent looping. - nil) - - ((and (not c-enums-contain-decls) - ;; An optimization quickly to eliminate scans of long enum - ;; declarations in the next cond arm. - (let ((paren-state (c-parse-state))) - (and - (numberp (car paren-state)) + (if (eq context 'not-decl) + (progn + (setq decl-or-cast nil) + (if (c-syntactic-re-search-forward + "," (min limit (point-max)) 'at-limit t) + (c-put-char-property (1- (point)) 'c-type 'c-not-decl)) + nil) + (setq decl-or-cast + (c-forward-decl-or-cast-1 + match-pos context last-cast-end)) + + ;; Ensure that c-<>-arg-sep c-type properties are in place on the + ;; commas separating the arguments inside template/generic <..>s. + (when (and (eq (char-before match-pos) ?<) + (> match-pos max-<>-end)) + (save-excursion + (goto-char match-pos) + (c-backward-token-2) + (if (and + (eq (char-after) ?<) + (let ((c-restricted-<>-arglists + (save-excursion + (c-backward-token-2) + (and + (not (looking-at c-opt-<>-sexp-key)) + (progn (c-backward-syntactic-ws) + (memq (char-before) '(?\( ?,))) + (not (eq (c-get-char-property (1- (point)) + 'c-type) + 'c-decl-arg-start)))))) + (c-forward-<>-arglist nil))) + (setq max-<>-end (point))))) + + (cond + ((eq decl-or-cast 'cast) + ;; Save the position after the previous cast so we can feed + ;; it to `c-forward-decl-or-cast-1' in the next round. That + ;; helps it discover cast chains like "(a) (b) c". + (setq last-cast-end (point)) + (c-fontify-recorded-types-and-refs) + nil) + + (decl-or-cast + ;; We've found a declaration. + + ;; Set `max-type-decl-end' or `max-type-decl-end-before-token' + ;; under the assumption that we're after the first type decl + ;; expression in the declaration now. That's not really true; + ;; we could also be after a parenthesized initializer + ;; expression in C++, but this is only used as a last resort + ;; to slant ambiguous expression/declarations, and overall + ;; it's worth the risk to occasionally fontify an expression + ;; as a declaration in an initializer expression compared to + ;; getting ambiguous things in normal function prototypes + ;; fontified as expressions. + (if inside-macro + (when (> (point) max-type-decl-end-before-token) + (setq max-type-decl-end-before-token (point))) + (when (> (point) max-type-decl-end) + (setq max-type-decl-end (point)))) + + ;; Do we have an expression as the second or third clause of + ;; a "for" paren expression? + (if (save-excursion + (and + (car (cddr decl-or-cast)) ; maybe-expression flag. + (goto-char start-pos) + (c-go-up-list-backward) + (eq (char-after) ?\() + (progn (c-backward-syntactic-ws) + (c-simple-skip-symbol-backward)) + (looking-at c-paren-stmt-key) + (progn (goto-char match-pos) + (while (and (eq (char-before) ?\)) + (c-go-list-backward)) + (c-backward-syntactic-ws)) + (eq (char-before) ?\;)))) + ;; We've got an expression in "for" parens. Remove the + ;; "type" that would spuriously get fontified. + (let ((elt (and (consp c-record-type-identifiers) + (assq (cadr (cddr decl-or-cast)) + c-record-type-identifiers)))) + (when elt + (setq c-record-type-identifiers + (c-delq-from-dotted-list + elt c-record-type-identifiers))) + t) + ;; Back up to the type to fontify the declarator(s). + (goto-char (car decl-or-cast)) + + (let ((decl-list + (if (not (memq context '(nil top))) + ;; Should normally not fontify a list of + ;; declarators inside an arglist, but the first + ;; argument in the ';' separated list of a "for" + ;; statement is an exception. + (when (eq (char-before match-pos) ?\() + (save-excursion + (goto-char (1- match-pos)) + (c-backward-syntactic-ws) + (and (c-simple-skip-symbol-backward) + (looking-at c-paren-stmt-key)))) + t))) + + ;; Fix the `c-decl-id-start' or `c-decl-type-start' property + ;; before the first declarator if it's a list. + ;; `c-font-lock-declarators' handles the rest. + (when decl-list (save-excursion - (goto-char (car paren-state)) - (c-backward-over-enum-header))))) - (c-forward-token-2) - nil) + (c-backward-syntactic-ws) + (unless (bobp) + (c-put-char-property (1- (point)) 'c-type + (if (cadr decl-or-cast) + 'c-decl-type-start + 'c-decl-id-start))))) + + (c-font-lock-declarators + (min limit (point-max)) decl-list + (cadr decl-or-cast) (not toplev))) + + ;; A declaration has been successfully identified, so do all the + ;; fontification of types and refs that've been recorded. + (c-fontify-recorded-types-and-refs) + nil)) - (t - ;; Are we at a declarator? Try to go back to the declaration - ;; to check this. If we get there, check whether a "typedef" - ;; is there, then fontify the declarators accordingly. - (let ((decl-search-lim (c-determine-limit 1000)) - paren-state bod-res encl-pos is-typedef - c-recognize-knr-p) ; Strictly speaking, bogus, but it - ; speeds up lisp.h tremendously. - (save-excursion - (if (c-back-over-member-initializers) - t ; Can't be at a declarator - (unless (or (eobp) - (looking-at "\\s(\\|\\s)")) - (forward-char)) - (setq bod-res (car (c-beginning-of-decl-1 decl-search-lim))) - (if (and (eq bod-res 'same) - (save-excursion - (c-backward-syntactic-ws) - (eq (char-before) ?\}))) - (c-beginning-of-decl-1 decl-search-lim)) - - ;; We're now putatively at the declaration. - (setq paren-state (c-parse-state)) - ;; At top level or inside a "{"? - (if (or (not (setq encl-pos - (c-most-enclosing-brace paren-state))) - (eq (char-after encl-pos) ?\{)) - (progn - (when (looking-at c-typedef-key) ; "typedef" - (setq is-typedef t) - (goto-char (match-end 0)) - (c-forward-syntactic-ws)) - ;; At a real declaration? - (if (memq (c-forward-type t) '(t known found decltype)) - (progn - (c-font-lock-declarators (point-max) t is-typedef) - nil) - ;; False alarm. Return t to go on to the next check. - (goto-char start-pos) - t)) - t))))))) + (t t)))) ;; It was a false alarm. Check if we're in a label (or other ;; construct with `:' except bitfield) instead. @@ -1488,6 +1493,22 @@ casts and declarations are fontified. Used on level 2 and higher." nil))) +(defun c-font-lock-enum-body (limit) + ;; Fontify the identifiers of each enum we find by searching forward. + ;; + ;; This function will be called from font-lock for a region bounded by POINT + ;; and LIMIT, as though it were to identify a keyword for + ;; font-lock-keyword-face. It always returns NIL to inhibit this and + ;; prevent a repeat invocation. See elisp/lispref page "Search-based + ;; Fontification". + (while (search-forward-regexp c-enum-clause-introduction-re limit t) + (when (save-excursion + (backward-char) + (c-backward-over-enum-header)) + (c-forward-syntactic-ws) + (c-font-lock-declarators limit t nil t))) + nil) + (defun c-font-lock-enum-tail (limit) ;; Fontify an enum's identifiers when POINT is within the enum's brace ;; block. @@ -1512,9 +1533,52 @@ casts and declarations are fontified. Used on level 2 and higher." (c-put-char-property (1- (point)) 'c-type 'c-decl-id-start) (c-forward-syntactic-ws) - (c-font-lock-declarators limit t nil))) + (c-font-lock-declarators limit t nil t))) nil) +(defun c-font-lock-cut-off-declarators (limit) + ;; Fontify any declarators "cut off" from their declaring type at the start + ;; of the region being fontified. + ;; + ;; This function will be called from font-lock- for a region bounded by + ;; POINT and LIMIT, as though it were to identify a keyword for + ;; font-lock-keyword-face. It always returns NIL to inhibit this and + ;; prevent a repeat invocation. See elisp/lispref page "Search-based + ;; fontification". + (let ((decl-search-lim (c-determine-limit 1000)) + paren-state bod-res is-typedef encl-pos + (here (point)) + c-recognize-knr-p) ; Strictly speaking, bogus, but it + ; speeds up lisp.h tremendously. + (save-excursion + (when (not (c-back-over-member-initializers)) + (unless (or (eobp) + (looking-at "\\s(\\|\\s)")) + (forward-char)) + (c-syntactic-skip-backward "^;{}" decl-search-lim t) + (when (eq (char-before) ?}) + (c-go-list-backward) ; brace block of struct, etc.? + (c-syntactic-skip-backward "^;{}" decl-search-lim t)) + (when (or (bobp) + (memq (char-before) '(?\; ?{ ?}))) + (c-forward-syntactic-ws) + ;; We're now putatively at the declaration. + (setq paren-state (c-parse-state)) + ;; At top level or inside a "{"? + (if (or (not (setq encl-pos + (c-most-enclosing-brace paren-state))) + (eq (char-after encl-pos) ?\{)) + (progn + (when (looking-at c-typedef-key) ; "typedef" + (setq is-typedef t) + (goto-char (match-end 0)) + (c-forward-syntactic-ws)) + ;; At a real declaration? + (if (memq (c-forward-type t) '(t known found decltype)) + (c-font-lock-declarators + limit t is-typedef (not (c-bs-at-toplevel-p here))))))))) + nil)) + (defun c-font-lock-enclosing-decls (limit) ;; Fontify the declarators of (nested) declarations we're in the middle of. ;; This is mainly for when a jit-lock etc. chunk starts inside the brace @@ -1527,7 +1591,7 @@ casts and declarations are fontified. Used on level 2 and higher." ;; Fontification". (let* ((paren-state (c-parse-state)) (decl-search-lim (c-determine-limit 1000)) - decl-context in-typedef ps-elt) + in-typedef ps-elt) ;; Are we in any nested struct/union/class/etc. braces? (while paren-state (setq ps-elt (car paren-state) @@ -1535,15 +1599,158 @@ casts and declarations are fontified. Used on level 2 and higher." (when (and (atom ps-elt) (eq (char-after ps-elt) ?\{)) (goto-char ps-elt) - (setq decl-context (c-beginning-of-decl-1 decl-search-lim) - in-typedef (looking-at c-typedef-key)) - (if in-typedef (c-forward-token-2)) - (when (and c-opt-block-decls-with-vars-key - (looking-at c-opt-block-decls-with-vars-key)) - (goto-char ps-elt) - (when (c-safe (c-forward-sexp)) - (c-forward-syntactic-ws) - (c-font-lock-declarators limit t in-typedef))))))) + (c-syntactic-skip-backward "^;{}" decl-search-lim) + (when (or (bobp) + (memq (char-before) '(?\; ?}))) + (c-forward-syntactic-ws) + (setq in-typedef (looking-at c-typedef-key)) + (if in-typedef (c-forward-token-2)) + (when (and c-opt-block-decls-with-vars-key + (looking-at c-opt-block-decls-with-vars-key)) + (goto-char ps-elt) + (when (c-safe (c-forward-sexp)) + (c-forward-syntactic-ws) + (c-font-lock-declarators limit t in-typedef + (not (c-bs-at-toplevel-p (point))))))))))) + +(defun c-font-lock-raw-strings (limit) + ;; Fontify C++ raw strings. + ;; + ;; This function will be called from font-lock for a region bounded by POINT + ;; and LIMIT, as though it were to identify a keyword for + ;; font-lock-keyword-face. It always returns NIL to inhibit this and + ;; prevent a repeat invocation. See elisp/lispref page "Search-based + ;; Fontification". + (let* ((state (c-state-semi-pp-to-literal (point))) + (string-start (and (eq (cadr state) 'string) + (car (cddr state)))) + (raw-id (and string-start + (save-excursion + (goto-char string-start) + (and (eq (char-before) ?R) + (looking-at "\"\\([^ ()\\\n\r\t]\\{0,16\\}\\)(") + (match-string-no-properties 1)))))) + (while (< (point) limit) + (if raw-id + (progn + (if (search-forward-regexp (concat ")\\(" (regexp-quote raw-id) "\\)\"") + limit 'limit) + (c-put-font-lock-face (match-beginning 1) (point) 'default)) + (setq raw-id nil)) + + (when (search-forward-regexp + "R\\(\"\\)\\([^ ()\\\n\r\t]\\{0,16\\}\\)(" limit 'limit) + (when + (or (and (eobp) + (eq (c-get-char-property (1- (point)) 'face) + 'font-lock-warning-face)) + (eq (c-get-char-property (point) 'face) 'font-lock-string-face) + (and (equal (c-get-char-property (match-end 2) 'syntax-table) '(1)) + (equal (c-get-char-property (match-beginning 1) 'syntax-table) + '(1)))) + (let ((paren-prop (c-get-char-property (1- (point)) 'syntax-table))) + (if paren-prop + (progn + (c-put-font-lock-face (match-beginning 0) (match-end 0) + 'font-lock-warning-face) + (when + (and + (equal paren-prop '(15)) + (not (c-search-forward-char-property 'syntax-table '(15) limit))) + (goto-char limit))) + (c-put-font-lock-face (match-beginning 1) (match-end 2) 'default) + (setq raw-id (match-string-no-properties 2))))))))) + nil) + +(defun c-font-lock-c++-lambda-captures (limit) + ;; Fontify the lambda capture component of C++ lambda declarations. + ;; + ;; This function will be called from font-lock for a region bounded by POINT + ;; and LIMIT, as though it were to identify a keyword for + ;; font-lock-keyword-face. It always returns NIL to inhibit this and + ;; prevent a repeat invocation. See elisp/lispref page "Search-based + ;; Fontification". + (let (mode capture-default id-start id-end declaration sub-begin sub-end) + (while (and (< (point) limit) + (search-forward "[" limit t)) + (when (progn (backward-char) + (prog1 + (c-looking-at-c++-lambda-capture-list) + (forward-char))) + (c-forward-syntactic-ws) + (setq mode (and (memq (char-after) '(?= ?&)) + (char-after))) + ;; Is the first element of the list a bare "=" or "&"? + (when mode + (forward-char) + (c-forward-syntactic-ws) + (if (memq (char-after) '(?, ?\])) + (progn + (setq capture-default mode) + (when (eq (char-after) ?,) + (forward-char) + (c-forward-syntactic-ws))) + (c-backward-token-2))) + + ;; Go round the following loop once per captured item. We use "\\s)" + ;; rather than "\\]" here to avoid infinite looping in this situation: + ;; "unsigned items [] { [ }". The second "[" triggers this function, + ;; but if we don't match the "}" with an "\\s)", the + ;; `c-syntactic-re-search-forward' at the end of the loop fails to + ;; move forward over it, leaving point stuck at the "}". + (while (and (not (looking-at "\\s)")) + (< (point) limit)) + (if (eq (char-after) ?&) + (progn (setq mode ?&) + (forward-char) + (c-forward-syntactic-ws)) + (setq mode ?=)) + (if (c-on-identifier) + (progn + (setq id-start (point)) + (forward-char) + (c-end-of-current-token) + (setq id-end (point)) + (c-forward-syntactic-ws) + + (setq declaration (eq (char-after) ?=)) + (when declaration + (forward-char) ; over "=" + (c-forward-syntactic-ws) + (setq sub-begin (point))) + (if (or (and (< (point) limit) + (c-syntactic-re-search-forward "," limit t t)) + (and (c-go-up-list-forward nil limit) + (eq (char-before) ?\]))) + (backward-char) + (goto-char limit)) + (when declaration + (save-excursion + (setq sub-end (point)) + (goto-char sub-begin) + (c-font-lock-c++-lambda-captures sub-end))) + + (c-put-font-lock-face id-start id-end + (cond + (declaration + 'font-lock-variable-name-face) + ((and capture-default + (eq mode capture-default)) + 'font-lock-warning-face) + ((eq mode ?=) font-lock-constant-face) + (t 'font-lock-variable-name-face)))) + (c-syntactic-re-search-forward "," limit 'bound t)) + + (c-forward-syntactic-ws) + (when (eq (char-after) ?,) + (forward-char) + (c-forward-syntactic-ws))) + + (setq capture-default nil) + (if (< (point) limit) + (forward-char))))) ; over the terminating "]" or other close paren. + nil) + (c-lang-defconst c-simple-decl-matchers "Simple font lock matchers for types and declarations. These are used @@ -1572,7 +1779,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." (eval . (list ,(c-make-font-lock-search-function 'c-known-type-key '(1 'font-lock-type-face t) - '((c-font-lock-declarators limit t nil) + '((c-font-lock-declarators limit t nil nil) (save-match-data (goto-char (match-end 1)) (c-forward-syntactic-ws)) @@ -1594,7 +1801,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." "\\)")) `(,type-match 'font-lock-type-face t) - `((c-font-lock-declarators limit t nil) + `((c-font-lock-declarators limit t nil nil) (save-match-data (goto-char (match-end ,type-match)) (c-forward-syntactic-ws)) @@ -1606,7 +1813,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." (concat "\\<\\(" (regexp-opt (c-lang-const c-typeless-decl-kwds)) "\\)\\>") - '((c-font-lock-declarators limit t nil) + '((c-font-lock-declarators limit t nil nil) (save-match-data (goto-char (match-end 1)) (c-forward-syntactic-ws)) @@ -1648,6 +1855,10 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." 'c-type 'c-decl-end))) c-font-lock-objc-methods)) + ;; Fontify declarators which have been cut off from their declaring + ;; types at the start of the region. + c-font-lock-cut-off-declarators + ;; Fontify all declarations, casts and normal labels. c-font-lock-declarations @@ -1658,6 +1869,9 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." ,@(when (c-lang-const c-recognize-<>-arglists) `(c-font-lock-<>-arglists)) + ,@(when (c-major-mode-is 'c++-mode) + `(c-font-lock-c++-lambda-captures)) + ;; The first two rules here mostly find occurrences that ;; `c-font-lock-declarations' has found already, but not ;; declarations containing blocks in the type (see note below). @@ -1699,10 +1913,18 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." (unless (c-skip-comments-and-strings limit) (c-forward-syntactic-ws) ;; Handle prefix declaration specifiers. - (when (or (looking-at c-prefix-spec-kwds-re) - (and (c-major-mode-is 'java-mode) - (looking-at "@[A-Za-z0-9]+"))) - (c-forward-keyword-clause 1)) + (while + (or + (when (or (looking-at c-prefix-spec-kwds-re) + (and (c-major-mode-is 'java-mode) + (looking-at "@[A-Za-z0-9]+"))) + (c-forward-keyword-clause 1) + t) + (when (and c-opt-cpp-prefix + (looking-at + c-noise-macro-with-parens-name-re)) + (c-forward-noise-clause) + t))) ,(if (c-major-mode-is 'c++-mode) `(when (and (c-forward-type) (eq (char-after) ?=)) @@ -1814,29 +2036,14 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." generic casts and declarations are fontified. Used on level 2 and higher." - t `(,@(when (c-lang-const c-brace-id-list-kwds) + t `(,@(when (c-lang-const c-brace-list-decl-kwds) ;; Fontify the remaining identifiers inside an enum list when we start ;; inside it. `(c-font-lock-enum-tail ;; Fontify the identifiers inside enum lists. (The enum type ;; name is handled by `c-simple-decl-matchers' or ;; `c-complex-decl-matchers' below. - (,(c-make-font-lock-search-function - (concat - "\\<\\(" - (c-make-keywords-re nil (c-lang-const c-brace-id-list-kwds)) - "\\)\\>" - ;; Disallow various common punctuation chars that can't come - ;; before the '{' of the enum list, to avoid searching too far. - "[^][{}();/#=]*" - "{") - '((c-font-lock-declarators limit t nil) - (save-match-data - (goto-char (match-end 0)) - (c-put-char-property (1- (point)) 'c-type - 'c-decl-id-start) - (c-forward-syntactic-ws)) - (goto-char (match-end 0))))))) + c-font-lock-enum-body)) ;; Fontify labels after goto etc. ,@(when (c-lang-const c-before-label-kwds) @@ -2229,7 +2436,7 @@ need for `c++-font-lock-extra-types'.") limit "[-+]" nil - (lambda (match-pos inside-macro) + (lambda (match-pos inside-macro &optional top-level) (forward-char) (c-font-lock-objc-method)))) nil) @@ -2401,10 +2608,10 @@ need for `pike-font-lock-extra-types'.") 'font-lock-comment-face) ;; Handle the case when the fontified region starts inside a ;; comment. - (let ((range (c-literal-limits))) + (let ((start (c-literal-start))) (setq region-beg (point)) - (when range - (goto-char (car range))) + (when start + (goto-char start)) (when (looking-at prefix) (setq comment-beg (point))))) |