mirror of
git://git.sv.gnu.org/emacs.git
synced 2025-12-09 07:40:39 -08:00
Enhance fontification of declarators to take account of the
presence/absence of "typedef". cc-engine.el (c-forward-type): New &optional param "brace-block-too". (c-forward-decl-or-cast-1): cdr of return value now indicates the presence of either or both of a "struct"-like keyword and "typedef". cc-fonts.el (c-complex-decl-matchers): Remove the heuristic fontification of declarators which follow a "}". (c-font-lock-declarations): Fontify declarators according to the presence/absence of "typedef". cc-langs.el (c-typedef-kwds c-typedef-key): New lang variable for "typedef". (c-typedef-decl-key): New lang variable built from c-typedef-decl-kwds.
This commit is contained in:
parent
eef3ab9443
commit
e15f8aaa0e
4 changed files with 311 additions and 148 deletions
|
|
@ -1,3 +1,24 @@
|
||||||
|
2010-10-09 Alan Mackenzie <acm@muc.de>
|
||||||
|
|
||||||
|
Enhance fontification of declarators to take account of the
|
||||||
|
presence/absence of "typedef".
|
||||||
|
|
||||||
|
* cc-engine.el (c-forward-type): New &optional param
|
||||||
|
"brace-block-too".
|
||||||
|
(c-forward-decl-or-cast-1): cdr of return value now indicates the
|
||||||
|
presence of either or both of a "struct"-like keyword and
|
||||||
|
"typedef".
|
||||||
|
|
||||||
|
* cc-fonts.el (c-complex-decl-matchers): Remove the heuristic
|
||||||
|
fontification of declarators which follow a "}".
|
||||||
|
(c-font-lock-declarations): Fontify declarators according to the
|
||||||
|
presence/absence of "typedef".
|
||||||
|
|
||||||
|
* cc-langs.el (c-typedef-kwds c-typedef-key): New lang variable
|
||||||
|
for "typedef".
|
||||||
|
(c-typedef-decl-key): New lang variable built from
|
||||||
|
c-typedef-decl-kwds.
|
||||||
|
|
||||||
2010-10-09 Lars Magne Ingebrigtsen <larsi@gnus.org>
|
2010-10-09 Lars Magne Ingebrigtsen <larsi@gnus.org>
|
||||||
|
|
||||||
* ibuffer.el (ibuffer-mode-map): Don't redefine the cursor keys,
|
* ibuffer.el (ibuffer-mode-map): Don't redefine the cursor keys,
|
||||||
|
|
|
||||||
|
|
@ -5646,17 +5646,23 @@ comment at the start of cc-engine.el for more info."
|
||||||
|
|
||||||
(defun c-forward-name ()
|
(defun c-forward-name ()
|
||||||
;; Move forward over a complete name if at the beginning of one,
|
;; Move forward over a complete name if at the beginning of one,
|
||||||
;; stopping at the next following token. If the point is not at
|
;; stopping at the next following token. A keyword, as such,
|
||||||
;; something that are recognized as name then it stays put. A name
|
;; doesn't count as a name. If the point is not at something that
|
||||||
;; could be something as simple as "foo" in C or something as
|
;; is recognized as a name then it stays put.
|
||||||
|
;;
|
||||||
|
;; A name could be something as simple as "foo" in C or something as
|
||||||
;; complex as "X<Y<class A<int>::B, BIT_MAX >> b>, ::operator<> ::
|
;; complex as "X<Y<class A<int>::B, BIT_MAX >> b>, ::operator<> ::
|
||||||
;; Z<(a>b)> :: operator const X<&foo>::T Q::G<unsigned short
|
;; Z<(a>b)> :: operator const X<&foo>::T Q::G<unsigned short
|
||||||
;; int>::*volatile const" in C++ (this function is actually little
|
;; int>::*volatile const" in C++ (this function is actually little
|
||||||
;; more than a `looking-at' call in all modes except those that,
|
;; more than a `looking-at' call in all modes except those that,
|
||||||
;; like C++, have `c-recognize-<>-arglists' set). Return nil if no
|
;; like C++, have `c-recognize-<>-arglists' set).
|
||||||
;; name is found, 'template if it's an identifier ending with an
|
;;
|
||||||
;; angle bracket arglist, 'operator of it's an operator identifier,
|
;; Return
|
||||||
;; or t if it's some other kind of name.
|
;; o - nil if no name is found;
|
||||||
|
;; o - 'template if it's an identifier ending with an angle bracket
|
||||||
|
;; arglist;
|
||||||
|
;; o - 'operator of it's an operator identifier;
|
||||||
|
;; o - t if it's some other kind of name.
|
||||||
;;
|
;;
|
||||||
;; This function records identifier ranges on
|
;; This function records identifier ranges on
|
||||||
;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
|
;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
|
||||||
|
|
@ -5808,16 +5814,28 @@ comment at the start of cc-engine.el for more info."
|
||||||
(goto-char pos)
|
(goto-char pos)
|
||||||
res))
|
res))
|
||||||
|
|
||||||
(defun c-forward-type ()
|
(defun c-forward-type (&optional brace-block-too)
|
||||||
;; Move forward over a type spec if at the beginning of one,
|
;; Move forward over a type spec if at the beginning of one,
|
||||||
;; stopping at the next following token. Return t if it's a known
|
;; stopping at the next following token. The keyword "typedef"
|
||||||
;; type that can't be a name or other expression, 'known if it's an
|
;; isn't part of a type spec here.
|
||||||
;; otherwise known type (according to `*-font-lock-extra-types'),
|
;;
|
||||||
;; 'prefix if it's a known prefix of a type, 'found if it's a type
|
;; BRACE-BLOCK-TOO, when non-nil, means move over the brace block in
|
||||||
;; that matches one in `c-found-types', 'maybe if it's an identfier
|
;; constructs like "struct foo {...} bar ;" or "struct {...} bar;".
|
||||||
;; that might be a type, or nil if it can't be a type (the point
|
;; The current (2009-03-10) intention is to convert all uses of
|
||||||
;; isn't moved then). The point is assumed to be at the beginning
|
;; `c-forward-type' to call with this parameter set, then to
|
||||||
;; of a token.
|
;; eliminate it.
|
||||||
|
;;
|
||||||
|
;; Return
|
||||||
|
;; o - t if it's a known type that can't be a name or other
|
||||||
|
;; expression;
|
||||||
|
;; o - 'known if it's an otherwise known type (according to
|
||||||
|
;; `*-font-lock-extra-types');
|
||||||
|
;; o - 'prefix if it's a known prefix of a type;
|
||||||
|
;; o - 'found if it's a type that matches one in `c-found-types';
|
||||||
|
;; o - 'maybe if it's an identfier that might be a type; or
|
||||||
|
;; o - nil if it can't be a type (the point isn't moved then).
|
||||||
|
;;
|
||||||
|
;; The point is assumed to be at the beginning of a token.
|
||||||
;;
|
;;
|
||||||
;; Note that this function doesn't skip past the brace definition
|
;; Note that this function doesn't skip past the brace definition
|
||||||
;; that might be considered part of the type, e.g.
|
;; that might be considered part of the type, e.g.
|
||||||
|
|
@ -5836,32 +5854,39 @@ comment at the start of cc-engine.el for more info."
|
||||||
|
|
||||||
;; Skip leading type modifiers. If any are found we know it's a
|
;; Skip leading type modifiers. If any are found we know it's a
|
||||||
;; prefix of a type.
|
;; prefix of a type.
|
||||||
(when c-opt-type-modifier-key
|
(when c-opt-type-modifier-key ; e.g. "const" "volatile", but NOT "typedef"
|
||||||
(while (looking-at c-opt-type-modifier-key)
|
(while (looking-at c-opt-type-modifier-key)
|
||||||
(goto-char (match-end 1))
|
(goto-char (match-end 1))
|
||||||
(c-forward-syntactic-ws)
|
(c-forward-syntactic-ws)
|
||||||
(setq res 'prefix)))
|
(setq res 'prefix)))
|
||||||
|
|
||||||
(cond
|
(cond
|
||||||
((looking-at c-type-prefix-key)
|
((looking-at c-type-prefix-key) ; e.g. "struct", "class", but NOT
|
||||||
;; Looking at a keyword that prefixes a type identifier,
|
; "typedef".
|
||||||
;; e.g. "class".
|
|
||||||
(goto-char (match-end 1))
|
(goto-char (match-end 1))
|
||||||
(c-forward-syntactic-ws)
|
(c-forward-syntactic-ws)
|
||||||
(setq pos (point))
|
(setq pos (point))
|
||||||
(if (memq (setq name-res (c-forward-name)) '(t template))
|
|
||||||
(progn
|
(setq name-res (c-forward-name))
|
||||||
(when (eq name-res t)
|
(setq res (not (null name-res)))
|
||||||
;; In many languages the name can be used without the
|
(when (eq name-res t)
|
||||||
;; prefix, so we add it to `c-found-types'.
|
;; In many languages the name can be used without the
|
||||||
(c-add-type pos (point))
|
;; prefix, so we add it to `c-found-types'.
|
||||||
(when (and c-record-type-identifiers
|
(c-add-type pos (point))
|
||||||
c-last-identifier-range)
|
(when (and c-record-type-identifiers
|
||||||
(c-record-type-id c-last-identifier-range)))
|
c-last-identifier-range)
|
||||||
(setq res t))
|
(c-record-type-id c-last-identifier-range)))
|
||||||
;; Invalid syntax.
|
(when (and brace-block-too
|
||||||
(goto-char start)
|
(memq res '(t nil))
|
||||||
(setq res nil)))
|
(eq (char-after) ?\{)
|
||||||
|
(save-excursion
|
||||||
|
(c-safe
|
||||||
|
(progn (c-forward-sexp)
|
||||||
|
(c-forward-syntactic-ws)
|
||||||
|
(setq pos (point))))))
|
||||||
|
(goto-char pos)
|
||||||
|
(setq res t))
|
||||||
|
(unless res (goto-char start))) ; invalid syntax
|
||||||
|
|
||||||
((progn
|
((progn
|
||||||
(setq pos nil)
|
(setq pos nil)
|
||||||
|
|
@ -5951,14 +5976,13 @@ comment at the start of cc-engine.el for more info."
|
||||||
(setq res nil)))))
|
(setq res nil)))))
|
||||||
|
|
||||||
(when res
|
(when res
|
||||||
;; Skip trailing type modifiers. If any are found we know it's
|
;; Skip trailing type modifiers. If any are found we know it's
|
||||||
;; a type.
|
;; a type.
|
||||||
(when c-opt-type-modifier-key
|
(when c-opt-type-modifier-key
|
||||||
(while (looking-at c-opt-type-modifier-key)
|
(while (looking-at c-opt-type-modifier-key) ; e.g. "const", "volatile"
|
||||||
(goto-char (match-end 1))
|
(goto-char (match-end 1))
|
||||||
(c-forward-syntactic-ws)
|
(c-forward-syntactic-ws)
|
||||||
(setq res t)))
|
(setq res t)))
|
||||||
|
|
||||||
;; Step over any type suffix operator. Do not let the existence
|
;; Step over any type suffix operator. Do not let the existence
|
||||||
;; of these alter the classification of the found type, since
|
;; of these alter the classification of the found type, since
|
||||||
;; these operators typically are allowed in normal expressions
|
;; these operators typically are allowed in normal expressions
|
||||||
|
|
@ -5968,7 +5992,7 @@ comment at the start of cc-engine.el for more info."
|
||||||
(goto-char (match-end 1))
|
(goto-char (match-end 1))
|
||||||
(c-forward-syntactic-ws)))
|
(c-forward-syntactic-ws)))
|
||||||
|
|
||||||
(when c-opt-type-concat-key
|
(when c-opt-type-concat-key ; Only/mainly for pike.
|
||||||
;; Look for a trailing operator that concatenates the type
|
;; Look for a trailing operator that concatenates the type
|
||||||
;; with a following one, and if so step past that one through
|
;; with a following one, and if so step past that one through
|
||||||
;; a recursive call. Note that we don't record concatenated
|
;; a recursive call. Note that we don't record concatenated
|
||||||
|
|
@ -6119,11 +6143,15 @@ comment at the start of cc-engine.el for more info."
|
||||||
;; car ^ ^ point
|
;; car ^ ^ point
|
||||||
;; Foo::Foo (int b) : Base (b) {}
|
;; Foo::Foo (int b) : Base (b) {}
|
||||||
;; car ^ ^ point
|
;; car ^ ^ point
|
||||||
;;
|
;;
|
||||||
;; The cdr of the return value is non-nil iff a `c-typedef-decl-kwds'
|
;; The cdr of the return value is non-nil when a
|
||||||
;; specifier (e.g. class, struct, enum, typedef) is found in the
|
;; `c-typedef-decl-kwds' specifier is found in the declaration.
|
||||||
;; declaration, i.e. the declared identifier(s) are types.
|
;; Specifically it is a dotted pair (A . B) where B is t when a
|
||||||
;;
|
;; `c-typedef-kwds' ("typedef") is present, and A is t when some
|
||||||
|
;; other `c-typedef-decl-kwds' (e.g. class, struct, enum)
|
||||||
|
;; specifier is present. I.e., (some of) the declared
|
||||||
|
;; identifier(s) are types.
|
||||||
|
;;
|
||||||
;; If a cast is parsed:
|
;; If a cast is parsed:
|
||||||
;;
|
;;
|
||||||
;; The point is left at the first token after the closing paren of
|
;; The point is left at the first token after the closing paren of
|
||||||
|
|
@ -6181,9 +6209,11 @@ comment at the start of cc-engine.el for more info."
|
||||||
;; If `backup-at-type' is nil then the other variables have
|
;; If `backup-at-type' is nil then the other variables have
|
||||||
;; undefined values.
|
;; undefined values.
|
||||||
backup-at-type backup-type-start backup-id-start
|
backup-at-type backup-type-start backup-id-start
|
||||||
;; Set if we've found a specifier that makes the defined
|
;; Set if we've found a specifier (apart from "typedef") that makes
|
||||||
;; identifier(s) types.
|
;; the defined identifier(s) types.
|
||||||
at-type-decl
|
at-type-decl
|
||||||
|
;; Set if we've a "typedef" keyword.
|
||||||
|
at-typedef
|
||||||
;; Set if we've found a specifier that can start a declaration
|
;; Set if we've found a specifier that can start a declaration
|
||||||
;; where there's no type.
|
;; where there's no type.
|
||||||
maybe-typeless
|
maybe-typeless
|
||||||
|
|
@ -6223,12 +6253,14 @@ comment at the start of cc-engine.el for more info."
|
||||||
|
|
||||||
;; Look for a specifier keyword clause.
|
;; Look for a specifier keyword clause.
|
||||||
(when (looking-at c-prefix-spec-kwds-re)
|
(when (looking-at c-prefix-spec-kwds-re)
|
||||||
|
(if (looking-at c-typedef-key)
|
||||||
|
(setq at-typedef t))
|
||||||
(setq kwd-sym (c-keyword-sym (match-string 1)))
|
(setq kwd-sym (c-keyword-sym (match-string 1)))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(c-forward-keyword-clause 1)
|
(c-forward-keyword-clause 1)
|
||||||
(setq kwd-clause-end (point))))
|
(setq kwd-clause-end (point))))
|
||||||
|
|
||||||
(when (setq found-type (c-forward-type))
|
(when (setq found-type (c-forward-type t)) ; brace-block-too
|
||||||
;; Found a known or possible type or a prefix of a known type.
|
;; Found a known or possible type or a prefix of a known type.
|
||||||
|
|
||||||
(when at-type
|
(when at-type
|
||||||
|
|
@ -6293,6 +6325,8 @@ comment at the start of cc-engine.el for more info."
|
||||||
(setq backup-maybe-typeless t)))
|
(setq backup-maybe-typeless t)))
|
||||||
|
|
||||||
(when (c-keyword-member kwd-sym 'c-typedef-decl-kwds)
|
(when (c-keyword-member kwd-sym 'c-typedef-decl-kwds)
|
||||||
|
;; This test only happens after we've scanned a type.
|
||||||
|
;; So, with valid syntax, kwd-sym can't be 'typedef.
|
||||||
(setq at-type-decl t))
|
(setq at-type-decl t))
|
||||||
(when (c-keyword-member kwd-sym 'c-typeless-decl-kwds)
|
(when (c-keyword-member kwd-sym 'c-typeless-decl-kwds)
|
||||||
(setq maybe-typeless t))
|
(setq maybe-typeless t))
|
||||||
|
|
@ -6892,7 +6926,9 @@ comment at the start of cc-engine.el for more info."
|
||||||
(goto-char type-start)
|
(goto-char type-start)
|
||||||
(c-forward-type))))
|
(c-forward-type))))
|
||||||
|
|
||||||
(cons id-start at-type-decl))
|
(cons id-start
|
||||||
|
(and (or at-type-decl at-typedef)
|
||||||
|
(cons at-type-decl at-typedef))))
|
||||||
|
|
||||||
(t
|
(t
|
||||||
;; False alarm. Restore the recorded ranges.
|
;; False alarm. Restore the recorded ranges.
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@
|
||||||
;; bit of the overhead compared to a real matcher. The main reason
|
;; bit of the overhead compared to a real matcher. The main reason
|
||||||
;; is however to pass the real search limit to the anchored
|
;; is however to pass the real search limit to the anchored
|
||||||
;; matcher(s), since most (if not all) font-lock implementations
|
;; matcher(s), since most (if not all) font-lock implementations
|
||||||
;; arbitrarily limits anchored matchers to the same line, and also
|
;; arbitrarily limit anchored matchers to the same line, and also
|
||||||
;; to insulate against various other irritating differences between
|
;; to insulate against various other irritating differences between
|
||||||
;; the different (X)Emacs font-lock packages.
|
;; the different (X)Emacs font-lock packages.
|
||||||
;;
|
;;
|
||||||
|
|
@ -310,7 +310,7 @@
|
||||||
;; covered by the font-lock context.)
|
;; covered by the font-lock context.)
|
||||||
|
|
||||||
;; Note: Replace `byte-compile' with `eval' to debug the generated
|
;; Note: Replace `byte-compile' with `eval' to debug the generated
|
||||||
;; lambda easier.
|
;; lambda more easily.
|
||||||
(byte-compile
|
(byte-compile
|
||||||
`(lambda (limit)
|
`(lambda (limit)
|
||||||
(let (;; The font-lock package in Emacs is known to clobber
|
(let (;; The font-lock package in Emacs is known to clobber
|
||||||
|
|
@ -721,16 +721,26 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
|
|
||||||
;; Clear the list of found types if we start from the start of the
|
;; Clear the list of found types if we start from the start of the
|
||||||
;; buffer, to make it easier to get rid of misspelled types and
|
;; buffer, to make it easier to get rid of misspelled types and
|
||||||
;; variables that has gotten recognized as types in malformed code.
|
;; variables that have gotten recognized as types in malformed code.
|
||||||
(when (bobp)
|
(when (bobp)
|
||||||
(c-clear-found-types))
|
(c-clear-found-types))
|
||||||
|
|
||||||
;; Clear the c-type char properties in the region to recalculate
|
;; Clear the c-type char properties which mark the region, to recalculate
|
||||||
;; them properly. This is necessary e.g. to handle constructs that
|
;; them properly. The most interesting properties are those put on the
|
||||||
;; might been required as declarations temporarily during editing.
|
;; closest token before the region.
|
||||||
;; The interesting properties are anyway those put on the closest
|
(save-excursion
|
||||||
;; token before the region.
|
(let ((pos (point)))
|
||||||
(c-clear-char-properties (point) limit 'c-type)
|
(c-backward-syntactic-ws)
|
||||||
|
(c-clear-char-properties
|
||||||
|
(if (and (not (bobp))
|
||||||
|
(memq (c-get-char-property (1- (point)) 'c-type)
|
||||||
|
'(c-decl-arg-start
|
||||||
|
c-decl-end
|
||||||
|
c-decl-id-start
|
||||||
|
c-decl-type-start)))
|
||||||
|
(1- (point))
|
||||||
|
pos)
|
||||||
|
limit 'c-type)))
|
||||||
|
|
||||||
;; Update `c-state-cache' to the beginning of the region. This will
|
;; Update `c-state-cache' to the beginning of the region. This will
|
||||||
;; make `c-beginning-of-syntax' go faster when it's used later on,
|
;; make `c-beginning-of-syntax' go faster when it's used later on,
|
||||||
|
|
@ -739,6 +749,8 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
|
|
||||||
;; Check if the fontified region starts inside a declarator list so
|
;; Check if the fontified region starts inside a declarator list so
|
||||||
;; that `c-font-lock-declarators' should be called at the start.
|
;; that `c-font-lock-declarators' should be called at the start.
|
||||||
|
;; The declared identifiers are font-locked correctly as types, if
|
||||||
|
;; that is what they are.
|
||||||
(let ((prop (save-excursion
|
(let ((prop (save-excursion
|
||||||
(c-backward-syntactic-ws)
|
(c-backward-syntactic-ws)
|
||||||
(unless (bobp)
|
(unless (bobp)
|
||||||
|
|
@ -831,12 +843,19 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defun c-font-lock-declarators (limit list types)
|
(defun c-font-lock-declarators (limit list types)
|
||||||
;; Assuming the point is at the start of a declarator in a
|
;; Assuming the point is at the start of a declarator in a declaration,
|
||||||
;; declaration, fontify it. If LIST is non-nil, fontify also all
|
;; fontify the identifier it declares. (If TYPES is set, it does this via
|
||||||
;; following declarators in a comma separated list (e.g. "foo" and
|
;; the macro `c-fontify-types-and-refs'.)
|
||||||
;; "bar" in "int foo = 17, bar;"). Stop at LIMIT. If TYPES is
|
;;
|
||||||
;; non-nil, fontify all identifiers as types. Nil is always
|
;; If LIST is non-nil, also fontify the ids in any following declarators in
|
||||||
;; returned.
|
;; a comma separated list (e.g. "foo" and "*bar" in "int foo = 17, *bar;");
|
||||||
|
;; 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.
|
||||||
|
;;
|
||||||
|
;; Nil is always returned. The function leaves point at the delimiter after
|
||||||
|
;; the last declarator it processes.
|
||||||
;;
|
;;
|
||||||
;; This function might do hidden buffer changes.
|
;; This function might do hidden buffer changes.
|
||||||
|
|
||||||
|
|
@ -848,18 +867,31 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
c-last-identifier-range
|
c-last-identifier-range
|
||||||
(separator-prop (if types 'c-decl-type-start 'c-decl-id-start)))
|
(separator-prop (if types 'c-decl-type-start 'c-decl-id-start)))
|
||||||
|
|
||||||
(while (and
|
;; The following `while' fontifies a single declarator id each time round.
|
||||||
|
;; It loops only when LIST is non-nil.
|
||||||
|
(while
|
||||||
|
;; Inside the following "condition form", we move forward over the
|
||||||
|
;; declarator's identifier up as far as any opening bracket (for array
|
||||||
|
;; size) or paren (for parameters of function-type) or brace (for
|
||||||
|
;; array/struct initialisation) or "=" or terminating delimiter
|
||||||
|
;; (e.g. "," or ";" or "}").
|
||||||
|
(and
|
||||||
pos
|
pos
|
||||||
(< (point) limit)
|
(< (point) limit)
|
||||||
|
|
||||||
|
;; The following form moves forward over the declarator's
|
||||||
|
;; identifier (and what precedes it), returning t. If there
|
||||||
|
;; wasn't one, it returns nil, terminating the `while'.
|
||||||
(let (got-identifier)
|
(let (got-identifier)
|
||||||
(setq paren-depth 0)
|
(setq paren-depth 0)
|
||||||
;; Skip over type decl prefix operators. (Note similar
|
;; Skip over type decl prefix operators, one for each iteration
|
||||||
;; code in `c-forward-decl-or-cast-1'.)
|
;; of the while. These are, e.g. "*" in "int *foo" or "(" and
|
||||||
|
;; "*" in "int (*foo) (void)" (Note similar code in
|
||||||
|
;; `c-forward-decl-or-cast-1'.)
|
||||||
(while (and (looking-at c-type-decl-prefix-key)
|
(while (and (looking-at c-type-decl-prefix-key)
|
||||||
(if (and (c-major-mode-is 'c++-mode)
|
(if (and (c-major-mode-is 'c++-mode)
|
||||||
(match-beginning 2))
|
(match-beginning 3))
|
||||||
;; If the second submatch matches in C++ then
|
;; If the third submatch matches in C++ then
|
||||||
;; we're looking at an identifier that's a
|
;; we're looking at an identifier that's a
|
||||||
;; prefix only if it specifies a member pointer.
|
;; prefix only if it specifies a member pointer.
|
||||||
(progn
|
(progn
|
||||||
|
|
@ -882,7 +914,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
(goto-char (match-end 1)))
|
(goto-char (match-end 1)))
|
||||||
(c-forward-syntactic-ws))
|
(c-forward-syntactic-ws))
|
||||||
|
|
||||||
;; If we didn't pass the identifier above already, do it now.
|
;; If we haven't passed the identifier already, do it now.
|
||||||
(unless got-identifier
|
(unless got-identifier
|
||||||
(setq id-start (point))
|
(setq id-start (point))
|
||||||
(c-forward-name))
|
(c-forward-name))
|
||||||
|
|
@ -890,12 +922,14 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
|
|
||||||
(/= id-end pos))
|
(/= id-end pos))
|
||||||
|
|
||||||
;; Skip out of the parens surrounding the identifier.
|
;; Skip out of the parens surrounding the identifier. If closing
|
||||||
|
;; parens are missing, this form returns nil.
|
||||||
(or (= paren-depth 0)
|
(or (= paren-depth 0)
|
||||||
(c-safe (goto-char (scan-lists (point) 1 paren-depth))))
|
(c-safe (goto-char (scan-lists (point) 1 paren-depth))))
|
||||||
|
|
||||||
(<= (point) limit)
|
(<= (point) limit)
|
||||||
|
|
||||||
|
;; Skip over any trailing bit, such as "__attribute__".
|
||||||
(progn
|
(progn
|
||||||
(when (looking-at c-decl-hangon-key)
|
(when (looking-at c-decl-hangon-key)
|
||||||
(c-forward-keyword-clause 1))
|
(c-forward-keyword-clause 1))
|
||||||
|
|
@ -936,7 +970,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
id-face)))
|
id-face)))
|
||||||
|
|
||||||
(goto-char next-pos)
|
(goto-char next-pos)
|
||||||
(setq pos nil)
|
(setq pos nil) ; So as to terminate the enclosing `while' form.
|
||||||
(when list
|
(when list
|
||||||
;; Jump past any initializer or function prototype to see if
|
;; Jump past any initializer or function prototype to see if
|
||||||
;; there's a ',' to continue at.
|
;; there's a ',' to continue at.
|
||||||
|
|
@ -944,11 +978,11 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
(cond ((eq id-face 'font-lock-function-name-face)
|
(cond ((eq id-face 'font-lock-function-name-face)
|
||||||
;; Skip a parenthesized initializer (C++) or a function
|
;; Skip a parenthesized initializer (C++) or a function
|
||||||
;; prototype.
|
;; prototype.
|
||||||
(if (c-safe (c-forward-sexp 1) t)
|
(if (c-safe (c-forward-sexp 1) t) ; over the parameter list.
|
||||||
(c-forward-syntactic-ws limit)
|
(c-forward-syntactic-ws limit)
|
||||||
(goto-char limit)))
|
(goto-char limit))) ; unbalanced parens
|
||||||
|
|
||||||
(got-init
|
(got-init ; "=" sign OR opening "(", "[", or "{"
|
||||||
;; Skip an initializer expression. If we're at a '='
|
;; Skip an initializer expression. If we're at a '='
|
||||||
;; then accept a brace list directly after it to cope
|
;; then accept a brace list directly after it to cope
|
||||||
;; with array initializers. Otherwise stop at braces
|
;; with array initializers. Otherwise stop at braces
|
||||||
|
|
@ -956,7 +990,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
(and (if (and (eq got-init ?=)
|
(and (if (and (eq got-init ?=)
|
||||||
(= (c-forward-token-2 1 nil limit) 0)
|
(= (c-forward-token-2 1 nil limit) 0)
|
||||||
(looking-at "{"))
|
(looking-at "{"))
|
||||||
(c-safe (c-forward-sexp) t)
|
(c-safe (c-forward-sexp) t) ; over { .... }
|
||||||
t)
|
t)
|
||||||
;; FIXME: Should look for c-decl-end markers here;
|
;; FIXME: Should look for c-decl-end markers here;
|
||||||
;; we might go far into the following declarations
|
;; we might go far into the following declarations
|
||||||
|
|
@ -971,7 +1005,7 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
(c-put-char-property (point) 'c-type separator-prop)
|
(c-put-char-property (point) 'c-type separator-prop)
|
||||||
(forward-char)
|
(forward-char)
|
||||||
(c-forward-syntactic-ws limit)
|
(c-forward-syntactic-ws limit)
|
||||||
(setq pos (point))))))
|
(setq pos (point)))))) ; acts to make the `while' form continue.
|
||||||
nil)
|
nil)
|
||||||
|
|
||||||
(defconst c-font-lock-maybe-decl-faces
|
(defconst c-font-lock-maybe-decl-faces
|
||||||
|
|
@ -984,27 +1018,29 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
font-lock-keyword-face))
|
font-lock-keyword-face))
|
||||||
|
|
||||||
(defun c-font-lock-declarations (limit)
|
(defun c-font-lock-declarations (limit)
|
||||||
|
;; Fontify all the declarations, casts and labels from the point to LIMIT.
|
||||||
|
;; Assumes that strings and comments have been fontified already.
|
||||||
|
;;
|
||||||
;; This function will be called from font-lock for a region bounded by POINT
|
;; 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
|
;; and LIMIT, as though it were to identify a keyword for
|
||||||
;; font-lock-keyword-face. It always returns NIL to inhibit this and
|
;; font-lock-keyword-face. It always returns NIL to inhibit this and
|
||||||
;; prevent a repeat invocation. See elisp/lispref page "Search-based
|
;; prevent a repeat invocation. See elisp/lispref page "Search-based
|
||||||
;; Fontification".
|
;; Fontification".
|
||||||
;;
|
;;
|
||||||
;; Fontify all the declarations, casts and labels from the point to LIMIT.
|
|
||||||
;; Assumes that strings and comments have been fontified already.
|
|
||||||
;;
|
|
||||||
;; This function might do hidden buffer changes.
|
;; This function might do hidden buffer changes.
|
||||||
|
|
||||||
;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
|
;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
|
||||||
|
|
||||||
(save-restriction
|
(save-restriction
|
||||||
(let (;; The position where `c-find-decl-spots' stopped.
|
(let (;; The position where `c-find-decl-spots' last stopped.
|
||||||
start-pos
|
start-pos
|
||||||
;; 'decl if we're in an arglist containing declarations (but
|
;; o - 'decl if we're in an arglist containing declarations
|
||||||
;; if `c-recognize-paren-inits' is set it might also be an
|
;; (but if `c-recognize-paren-inits' is set it might also be
|
||||||
;; initializer arglist), '<> if the arglist is of angle
|
;; an initializer arglist);
|
||||||
;; bracket type, 'arglist if it's some other arglist, or nil
|
;; o - '<> if the arglist is of angle bracket type;
|
||||||
;; if not in an arglist at all.
|
;; o - 'arglist if it's some other arglist;
|
||||||
|
;; o - nil, if not in an arglist at all. This includes the
|
||||||
|
;; parenthesised condition which follows "if", "while", etc.
|
||||||
context
|
context
|
||||||
;; The position of the next token after the closing paren of
|
;; The position of the next token after the closing paren of
|
||||||
;; the last detected cast.
|
;; the last detected cast.
|
||||||
|
|
@ -1082,57 +1118,106 @@ casts and declarations are fontified. Used on level 2 and higher."
|
||||||
;; can't start a declaration.
|
;; can't start a declaration.
|
||||||
t
|
t
|
||||||
|
|
||||||
;; Set `context'. Look for "<" for the sake of C++-style template
|
;; Set `context' and `c-restricted-<>-arglists'. Look for
|
||||||
;; arglists.
|
;; "<" for the sake of C++-style template arglists.
|
||||||
(if (memq (char-before match-pos) '(?\( ?, ?\[ ?<))
|
;; Ignore "(" when it's part of a control flow construct
|
||||||
|
;; (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
|
||||||
|
c-restricted-<>-arglists nil))
|
||||||
|
;; A control flow expression
|
||||||
|
((and (eq (char-before match-pos) ?\()
|
||||||
|
(save-excursion
|
||||||
|
(goto-char match-pos)
|
||||||
|
(backward-char)
|
||||||
|
(c-backward-token-2)
|
||||||
|
(looking-at c-block-stmt-2-key)))
|
||||||
|
(setq context nil
|
||||||
|
c-restricted-<>-arglists t))
|
||||||
|
;; Near BOB.
|
||||||
|
((<= match-pos (point-min))
|
||||||
|
(setq context 'arglist
|
||||||
|
c-restricted-<>-arglists t))
|
||||||
|
;; Got a cached hit in a declaration arglist.
|
||||||
|
((eq type 'c-decl-arg-start)
|
||||||
|
(setq context 'decl
|
||||||
|
c-restricted-<>-arglists nil))
|
||||||
|
;; Inside an angle bracket arglist.
|
||||||
|
((or (eq type 'c-<>-arg-sep)
|
||||||
|
(eq (char-before match-pos) ?<))
|
||||||
|
(setq context '<>
|
||||||
|
c-restricted-<>-arglists nil))
|
||||||
|
;; Got a cached hit in some other type of arglist.
|
||||||
|
(type
|
||||||
|
(setq context 'arglist
|
||||||
|
c-restricted-<>-arglists t))
|
||||||
|
((if inside-macro
|
||||||
|
(< match-pos max-type-decl-end-before-token)
|
||||||
|
(< match-pos max-type-decl-end))
|
||||||
|
;; The point is within the range of a previously
|
||||||
|
;; encountered type decl expression, so the arglist
|
||||||
|
;; is probably one that contains declarations.
|
||||||
|
;; However, if `c-recognize-paren-inits' is set it
|
||||||
|
;; might also be an initializer arglist.
|
||||||
|
(setq context 'decl
|
||||||
|
c-restricted-<>-arglists nil)
|
||||||
|
;; The result of this check is cached with a char
|
||||||
|
;; property on the match token, so that we can look
|
||||||
|
;; it up again when refontifying single lines in a
|
||||||
|
;; multiline declaration.
|
||||||
|
(c-put-char-property (1- match-pos)
|
||||||
|
'c-type 'c-decl-arg-start))
|
||||||
|
(t (setq context 'arglist
|
||||||
|
c-restricted-<>-arglists t))))
|
||||||
|
|
||||||
;; Find out the type of the arglist.
|
;; Check we haven't missed a preceding "typedef".
|
||||||
(if (<= match-pos (point-min))
|
(when (not (looking-at c-typedef-key))
|
||||||
(setq context 'arglist)
|
(c-backward-syntactic-ws)
|
||||||
(let ((type (c-get-char-property (1- match-pos) 'c-type)))
|
(c-backward-token-2)
|
||||||
(cond ((eq type 'c-decl-arg-start)
|
(or (looking-at c-typedef-key)
|
||||||
;; Got a cached hit in a declaration arglist.
|
(goto-char start-pos)))
|
||||||
(setq context 'decl))
|
|
||||||
((or (eq type 'c-<>-arg-sep)
|
|
||||||
(eq (char-before match-pos) ?<))
|
|
||||||
;; Inside an angle bracket arglist.
|
|
||||||
(setq context '<>))
|
|
||||||
(type
|
|
||||||
;; Got a cached hit in some other type of arglist.
|
|
||||||
(setq context 'arglist))
|
|
||||||
((if inside-macro
|
|
||||||
(< match-pos max-type-decl-end-before-token)
|
|
||||||
(< match-pos max-type-decl-end))
|
|
||||||
;; The point is within the range of a previously
|
|
||||||
;; encountered type decl expression, so the arglist
|
|
||||||
;; is probably one that contains declarations.
|
|
||||||
;; However, if `c-recognize-paren-inits' is set it
|
|
||||||
;; might also be an initializer arglist.
|
|
||||||
(setq context 'decl)
|
|
||||||
;; The result of this check is cached with a char
|
|
||||||
;; property on the match token, so that we can look
|
|
||||||
;; it up again when refontifying single lines in a
|
|
||||||
;; multiline declaration.
|
|
||||||
(c-put-char-property (1- match-pos)
|
|
||||||
'c-type 'c-decl-arg-start))
|
|
||||||
(t
|
|
||||||
(setq context 'arglist)))))
|
|
||||||
|
|
||||||
(setq context nil))
|
;; Now analyze the construct.
|
||||||
|
(setq decl-or-cast (c-forward-decl-or-cast-1
|
||||||
;; If we're in a normal arglist context we don't want to
|
|
||||||
;; recognize commas in nested angle bracket arglists since
|
|
||||||
;; those commas could be part of our own arglist.
|
|
||||||
(setq c-restricted-<>-arglists (and c-recognize-<>-arglists
|
|
||||||
(eq context 'arglist))
|
|
||||||
|
|
||||||
;; Now analyze the construct.
|
|
||||||
decl-or-cast (c-forward-decl-or-cast-1
|
|
||||||
match-pos context last-cast-end))
|
match-pos context last-cast-end))
|
||||||
|
|
||||||
(if (not decl-or-cast)
|
(if (not decl-or-cast)
|
||||||
;; False alarm. Return t to go on to the next check.
|
;; Are we at a declarator?
|
||||||
t
|
;; Try to go back to the declaration to check this.
|
||||||
|
(let (paren-state bod-res lim encl-pos is-typedef)
|
||||||
|
(goto-char start-pos)
|
||||||
|
(save-excursion
|
||||||
|
(setq lim (and (c-syntactic-skip-backward "^;" nil t)
|
||||||
|
(point))))
|
||||||
|
(save-excursion
|
||||||
|
(setq bod-res (car (c-beginning-of-decl-1 lim)))
|
||||||
|
(if (and (eq bod-res 'same)
|
||||||
|
(progn
|
||||||
|
(c-backward-syntactic-ws)
|
||||||
|
(eq (char-before) ?\})))
|
||||||
|
(c-beginning-of-decl-1 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))
|
||||||
|
(progn
|
||||||
|
(c-font-lock-declarators limit t is-typedef)
|
||||||
|
nil)
|
||||||
|
;; False alarm. Return t to go on to the next check.
|
||||||
|
(goto-char start-pos)
|
||||||
|
t))
|
||||||
|
t)))
|
||||||
|
|
||||||
(if (eq decl-or-cast 'cast)
|
(if (eq decl-or-cast 'cast)
|
||||||
;; Save the position after the previous cast so we can feed
|
;; Save the position after the previous cast so we can feed
|
||||||
|
|
@ -1296,7 +1381,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
|
||||||
"Complex font lock matchers for types and declarations. Used on level
|
"Complex font lock matchers for types and declarations. Used on level
|
||||||
3 and higher."
|
3 and higher."
|
||||||
|
|
||||||
;; Note: This code in this form dumps a number of funtions into the
|
;; Note: This code in this form dumps a number of functions into the
|
||||||
;; resulting constant, `c-matchers-3'. At run time, font lock will call
|
;; resulting constant, `c-matchers-3'. At run time, font lock will call
|
||||||
;; each of them as a "FUNCTION" (see Elisp page "Search-based
|
;; each of them as a "FUNCTION" (see Elisp page "Search-based
|
||||||
;; Fontification"). The font lock region is delimited by POINT and the
|
;; Fontification"). The font lock region is delimited by POINT and the
|
||||||
|
|
@ -1348,7 +1433,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
|
||||||
`(,(concat "\\<\\(" re "\\)\\>")
|
`(,(concat "\\<\\(" re "\\)\\>")
|
||||||
1 'font-lock-type-face)))
|
1 'font-lock-type-face)))
|
||||||
|
|
||||||
;; Fontify types preceded by `c-type-prefix-kwds'.
|
;; Fontify types preceded by `c-type-prefix-kwds' (e.g. "struct").
|
||||||
,@(when (c-lang-const c-type-prefix-kwds)
|
,@(when (c-lang-const c-type-prefix-kwds)
|
||||||
`((,(byte-compile
|
`((,(byte-compile
|
||||||
`(lambda (limit)
|
`(lambda (limit)
|
||||||
|
|
@ -1396,23 +1481,25 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
|
||||||
;; override it if it turns out to be an new declaration, but
|
;; override it if it turns out to be an new declaration, but
|
||||||
;; it will be wrong if it's an expression (see the test
|
;; it will be wrong if it's an expression (see the test
|
||||||
;; decls-8.cc).
|
;; decls-8.cc).
|
||||||
,@(when (c-lang-const c-opt-block-decls-with-vars-key)
|
;; ,@(when (c-lang-const c-opt-block-decls-with-vars-key)
|
||||||
`((,(c-make-font-lock-search-function
|
;; `((,(c-make-font-lock-search-function
|
||||||
(concat "}"
|
;; (concat "}"
|
||||||
(c-lang-const c-single-line-syntactic-ws)
|
;; (c-lang-const c-single-line-syntactic-ws)
|
||||||
"\\(" ; 1 + c-single-line-syntactic-ws-depth
|
;; "\\(" ; 1 + c-single-line-syntactic-ws-depth
|
||||||
(c-lang-const c-type-decl-prefix-key)
|
;; (c-lang-const c-type-decl-prefix-key)
|
||||||
"\\|"
|
;; "\\|"
|
||||||
(c-lang-const c-symbol-key)
|
;; (c-lang-const c-symbol-key)
|
||||||
"\\)")
|
;; "\\)")
|
||||||
`((c-font-lock-declarators limit t nil)
|
;; `((c-font-lock-declarators limit t nil) ; That `nil' says use `font-lock-variable-name-face';
|
||||||
(progn
|
;; ; `t' would mean `font-lock-function-name-face'.
|
||||||
(c-put-char-property (match-beginning 0) 'c-type
|
;; (progn
|
||||||
'c-decl-id-start)
|
;; (c-put-char-property (match-beginning 0) 'c-type
|
||||||
(goto-char (match-beginning
|
;; 'c-decl-id-start)
|
||||||
,(1+ (c-lang-const
|
;; ; 'c-decl-type-start)
|
||||||
c-single-line-syntactic-ws-depth)))))
|
;; (goto-char (match-beginning
|
||||||
(goto-char (match-end 0)))))))
|
;; ,(1+ (c-lang-const
|
||||||
|
;; c-single-line-syntactic-ws-depth)))))
|
||||||
|
;; (goto-char (match-end 0)))))))
|
||||||
|
|
||||||
;; Fontify the type in C++ "new" expressions.
|
;; Fontify the type in C++ "new" expressions.
|
||||||
,@(when (c-major-mode-is 'c++-mode)
|
,@(when (c-major-mode-is 'c++-mode)
|
||||||
|
|
@ -1660,6 +1747,10 @@ need for `c-font-lock-extra-types'.")
|
||||||
;;; C++.
|
;;; C++.
|
||||||
|
|
||||||
(defun c-font-lock-c++-new (limit)
|
(defun c-font-lock-c++-new (limit)
|
||||||
|
;; FIXME!!! Put in a comment about the context of this function's
|
||||||
|
;; invocation. I think it's called as an ANCHORED-MATCHER within an
|
||||||
|
;; ANCHORED-HIGHLIGHTER. (2007/2/10).
|
||||||
|
;;
|
||||||
;; Assuming point is after a "new" word, check that it isn't inside
|
;; Assuming point is after a "new" word, check that it isn't inside
|
||||||
;; a string or comment, and if so try to fontify the type in the
|
;; a string or comment, and if so try to fontify the type in the
|
||||||
;; allocation expression. Nil is always returned.
|
;; allocation expression. Nil is always returned.
|
||||||
|
|
|
||||||
|
|
@ -1565,6 +1565,17 @@ be a subset of `c-primitive-type-kwds'."
|
||||||
;; In CORBA PSDL:
|
;; In CORBA PSDL:
|
||||||
"strong"))
|
"strong"))
|
||||||
|
|
||||||
|
(c-lang-defconst c-typedef-kwds
|
||||||
|
"Prefix keyword\(s\) like \"typedef\" which make a type declaration out
|
||||||
|
of a variable declaration."
|
||||||
|
t '("typedef")
|
||||||
|
(awk idl java) nil)
|
||||||
|
|
||||||
|
(c-lang-defconst c-typedef-key
|
||||||
|
;; Adorned regexp matching `c-typedef-kwds'.
|
||||||
|
t (c-make-keywords-re t (c-lang-const c-typedef-kwds)))
|
||||||
|
(c-lang-defvar c-typedef-key (c-lang-const c-typedef-key))
|
||||||
|
|
||||||
(c-lang-defconst c-type-prefix-kwds
|
(c-lang-defconst c-type-prefix-kwds
|
||||||
"Keywords where the following name - if any - is a type name, and
|
"Keywords where the following name - if any - is a type name, and
|
||||||
where the keyword together with the symbol works as a type in
|
where the keyword together with the symbol works as a type in
|
||||||
|
|
@ -1731,6 +1742,10 @@ will be handled."
|
||||||
;; types in IDL since they only can occur in "raises" specs.
|
;; types in IDL since they only can occur in "raises" specs.
|
||||||
idl (delete "exception" (append (c-lang-const c-typedef-decl-kwds) nil)))
|
idl (delete "exception" (append (c-lang-const c-typedef-decl-kwds) nil)))
|
||||||
|
|
||||||
|
(c-lang-defconst c-typedef-decl-key
|
||||||
|
t (c-make-keywords-re t (c-lang-const c-typedef-decl-kwds)))
|
||||||
|
(c-lang-defvar c-typedef-decl-key (c-lang-const c-typedef-decl-key))
|
||||||
|
|
||||||
(c-lang-defconst c-typeless-decl-kwds
|
(c-lang-defconst c-typeless-decl-kwds
|
||||||
"Keywords introducing declarations where the \(first) identifier
|
"Keywords introducing declarations where the \(first) identifier
|
||||||
\(declarator) follows directly after the keyword, without any type.
|
\(declarator) follows directly after the keyword, without any type.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue