Correct the indentation of CC Mode brace lists

while preserving the indentation of nested C++ uniform initialization.

* lisp/progmodes/cc-align.el (c-lineup-2nd-brace-entry-in-arglist)
(c-lineup-class-decl-init-+, c-lineup-class-decl-init-after-brace): New
indentation functions.

* lisp/progmodes/cc-engine.el (c-forward-class-decl): New function.
(c-do-declarators): New function, partially extracted from
c-font-lock-declarators, which now calls the new function.
(c-inside-bracelist-p): Amend the introductory comment.
(c-add-stmt-syntax): Add code to prevent the spurious recognition of a
'defun-block-intro when a brace pair is used as an initializer.
(c-evaluate-offset): No longer ignore vectors of length >= 2.
(c-calc-offset): Refactor clumsily nested `if'/`or' into a cond form.

* lisp/progmodes/cc-fonts.el (c-font-lock-declarators): Replace the bulk of
this function by a call to the new c-forward-class-decl.

* lisp/progmodes/cc-langs.el (c-type-decl-prefix-key): Recognize "~" as a
type decl operator.

* lisp/progmodes/cc-mode.el (c-fl-decl-start): While searching backward for a
"}" at an EOD, deal with actually finding the end of a brace list.

* doc/misc/cc-mode.texi (List Line-Up): document
c-lineup-2nd-brace-entry-in-arglist, c-lineup-class-decl-init-+, and
c-lineup-class-decl-init-after-brace.

* lisp/progmodes/cc-styles.el (c-style-alist): In styles "gnu", "bsd",
"stroustrup", "python", and "java", change the offset for brace-list-intro
from the default value or c-lineup-arglist-intro-after-paren to a list
beginning with the symbol first, followed by two of the new alignment
functions, followed by +.

* lisp/progmodes/cc-vars.el (c-offset-alist): Change the default value of
brace-list-entry from c-lineup-under-anchor back to 0.
This commit is contained in:
Alan Mackenzie 2019-03-12 18:33:31 +00:00
parent d58c29b345
commit aa1a4cceca
8 changed files with 524 additions and 170 deletions

View file

@ -5638,9 +5638,9 @@ any problems writing custom line-up functions for AWK mode.
The calling convention for line-up functions is described fully in
@ref{Custom Line-Up}. Roughly speaking, the return value is either an
offset itself (such as @code{+} or @code{[0]}) or it's @code{nil},
meaning ``this function is inappropriate in this case; try a
different one''. @xref{c-offsets-alist}.
offset itself (such as @code{+} or @code{[0]}), another line-up
function, or it's @code{nil}, meaning ``this function is inappropriate
in this case - try a different one''. @xref{c-offsets-alist}.
The subsections below describe all the standard line-up functions,
categorized by the sort of token the lining-up centers around. For
@ -5995,6 +5995,125 @@ brace block.
@comment ------------------------------------------------------------
@defun c-lineup-2nd-brace-entry-in-arglist
@findex lineup-2nd-brace-entry-in-arglist (c-)
Line up the second entry of a brace block under the first, when the
first line is also contained in an arglist or an enclosing brace
@emph{on that line}.
I.e. handle something like the following:
@example
@group
set_line (line_t @{point_t@{0.4, 0.2@},
point_t@{0.2, 0.5@}, @hereFn{brace-list-intro}
.....@});
^ enclosing parenthesis.
@end group
@end example
The middle line of that example will have a syntactic context with
three syntactic symbols, @code{arglist-cont-nonempty},
@code{brace-list-intro}, and @code{brace-list-entry} (@pxref{Brace
List Symbols}).
This function is intended for use in a list. If the construct being
analyzed isn't like the preceding, the function returns nil.
Otherwise it returns the function
@code{c-lineup-arglist-intro-after-paren}, which the caller then uses
to perform indentation.
@workswith{} @code{brace-list-intro}.
@end defun
@comment ------------------------------------------------------------
@defun c-lineup-class-decl-init-+
@findex lineup-class-decl-init-+ (c-)
Line up the second entry of a class (etc.) initializer
@code{c-basic-offset} characters in from the identifier when:
@enumerate
@item
The type is a class, struct, union, etc. (but not an enum);
@item
There is a brace block in the type declaration, specifying it; and
@item
The first element of the initializer is on the same line as its
opening brace.
@end enumerate
I.e. we have a construct like this:
@example
@group
struct STR @{
int i; float f;
@} str_1 = @{1, 1.7@},
str_2 = @{2,
3.1 @hereFn{brace-list-intro}
@};
@sssTBasicOffset{}
@end group
@end example
Note that the syntactic context of the @code{brace-list-intro} line
also has a syntactic element with the symbol @code{brace-list-entry}
(@pxref{Brace List Symbols}).
This function is intended for use in a list. If the above structure
isn't present, the function returns nil, allowing a different offset
specification to indent the line.
@workswith{} @code{brace-list-intro}.
@end defun
@comment ------------------------------------------------------------
@defun c-lineup-class-decl-init-after-brace
@findex lineup-class-decl-init-after-brace (c-)
Line up the second entry of a class (etc.) initializer after its
opening brace when:
@enumerate
@item
The type is a class, struct, union, etc. (but not an enum);
@item
There is a brace block in the type declaration, specifying it; and
@item
The first element of the initializer is on the same line as its
opening brace.
@end enumerate
I.e. we have a construct like this:
@example
@group
struct STR @{
int i; float f;
@} str_1 = @{1, 1.7@},
str_2 = @{2,
3.1 @hereFn{brace-list-intro}
@};
@end group
@end example
Note that the syntactic context of the @code{brace-list-intro} line
also has a syntactic element with the symbol @code{brace-list-entry}
(@pxref{Brace List Symbols}). Also note that this function works by
returning the symbol @code{c-lineup-arglist-intro-after-paren}, which
the caller then uses to perform the indentation.
This function is intended for use in a list. If the above structure
isn't present, the function returns nil, allowing a different offset
specification to indent the line.
@workswith{} @code{brace-list-intro}.
@end defun
@comment ------------------------------------------------------------
@defun c-lineup-multi-inher
@findex lineup-multi-inher @r{(c-)}
Line up the classes in C++ multiple inheritance clauses and member

View file

@ -1083,6 +1083,130 @@ arglist-cont."
(vector (+ (current-column) c-basic-offset))))
(vector 0)))))
(defun c-lineup-2nd-brace-entry-in-arglist (langelem)
"Lineup the second entry of a brace block under the first, when the first
line is also contained in an arglist or an enclosing brace ON THAT LINE.
I.e. handle something like the following:
set_line (line_t {point_t{0.4, 0.2},
point_t{0.2, 0.5}, <---- brace-list-intro
.....});
^ enclosing parenthesis.
The middle line of that example will have a syntactic context
with three syntactic symbols, arglist-cont-nonempty, brace-list-intro, and
brace-list-entry.
This function is intended for use in a list. If the construct
being analyzed isn't like the preceding, the function returns nil.
Otherwise it returns the function `c-lineup-arglist-intro-after-paren', which
the caller then uses to perform indentation.
Works with brace-list-intro."
;; brace-list-intro and brace-list-entry are both present for the second
;; entry of the list when the first entry is on the same line as the opening
;; brace.
(and (assq 'brace-list-intro c-syntactic-context)
(assq 'brace-list-entry c-syntactic-context)
(or (assq 'arglist-cont-nonempty c-syntactic-context) ; "(" earlier on
; the line.
(save-excursion ; "{" earlier on the line
(goto-char (c-langelem-pos
(assq 'brace-list-intro c-syntactic-context)))
(and
(eq (c-backward-token-2
1 nil
(c-point 'bol (c-langelem-pos
(assq 'brace-list-entry
c-syntactic-context))))
0)
(eq (char-after) ?{))))
'c-lineup-arglist-intro-after-paren))
(defun c-lineup-class-decl-init-+ (langelem)
"Line up the second entry of a class (etc.) initializer c-basic-offset
characters in from the identifier when:
\(i) The type is a class, struct, union, etc. (but not an enum);
\(ii) There is a brace block in the type declaration, specifying it; and
\(iii) The first element of the initializer is on the same line as its opening
brace.
I.e. we have a construct like this:
struct STR {
int i; float f;
} str_1 = {1, 1.7},
str_2 = {2,
3.1 <---- brace-list-intro
};
<--> <---- c-basic-offset
Note that the syntactic context of the brace-list-intro line also has a
syntactic element with the symbol brace-list-entry.
This function is intended for use in a list. If the above structure isn't
present, this function returns nil, allowing a different offset specification
to indent the line.
Works with: brace-list-intro."
(and (assq 'brace-list-intro c-syntactic-context)
(assq 'brace-list-entry c-syntactic-context)
(let ((init-pos (c-point 'boi (c-langelem-pos
(assq 'brace-list-entry
c-syntactic-context))))
)
(save-excursion
(goto-char (c-langelem-pos (assq 'brace-list-intro
c-syntactic-context)))
(and
(c-forward-class-decl)
(not (c-do-declarators init-pos t nil nil nil))
(eq (point) init-pos)
(vector (+ (current-column) c-basic-offset)))))))
(defun c-lineup-class-decl-init-after-brace (langelem)
"Line up the second entry of a class (etc.) initializer after its opening
brace when:
\(i) The type is a class, struct, union, etc. (but not an enum);
\(ii) There is a brace block in the type declaration, specifying it; and
\(iii) The first element of the initializer is on the same line as its opening
brace.
I.e. we have a construct like this:
struct STR {
int i; float f;
} str_1 = {1, 1.7},
str_2 = {2,
3.1 <---- brace-list-intro
};
Note that the syntactic context of the brace-list-intro line also has a
syntactic element with the symbol brace-list-entry. Also note that this
function works by returning the symbol `c-lineup-arglist-intro-after-paren',
which the caller then uses to perform the indentation.
This function is intended for use in a list. If the above structure isn't
present, this function returns nil, allowing a different offset specification
to indent the line.
Works with: brace-list-intro."
(and (assq 'brace-list-intro c-syntactic-context)
(assq 'brace-list-entry c-syntactic-context)
(let ((init-pos (c-point 'boi (c-langelem-pos
(assq 'brace-list-entry
c-syntactic-context))))
)
(save-excursion
(goto-char (c-langelem-pos (assq 'brace-list-intro
c-syntactic-context)))
(and
(c-forward-class-decl)
(not (c-do-declarators init-pos t nil nil nil))
(eq (point) init-pos)
'c-lineup-arglist-intro-after-paren)))))
(defun c-lineup-cpp-define (_langelem)
"Line up macro continuation lines according to the indentation of
the construct preceding the macro. E.g.:

View file

@ -8040,49 +8040,28 @@ comment at the start of cc-engine.el for more info."
(or res (goto-char here))
res))
(defun c-forward-class-decl ()
"From the beginning of a struct/union, etc. move forward to
after the brace block which defines it, leaving point at the
start of the next token and returning point. On failure leave
point unchanged and return nil."
(let ((here (point)))
(if
(and
(looking-at c-class-key)
(eq (c-forward-token-2) 0)
(c-on-identifier)
(eq (c-forward-token-2) 0)
(eq (char-after) ?{)
(c-go-list-forward))
(progn
(c-forward-syntactic-ws)
(point))
(goto-char here)
nil)))
;; Handling of large scale constructs like statements and declarations.
;; Macro used inside `c-forward-decl-or-cast-1'. It ought to be a
;; defsubst or perhaps even a defun, but it contains lots of free
;; variables that refer to things inside `c-forward-decl-or-cast-1'.
(defmacro c-fdoc-shift-type-backward (&optional short)
;; `c-forward-decl-or-cast-1' can consume an arbitrary length list
;; of types when parsing a declaration, which means that it
;; sometimes consumes the identifier in the declaration as a type.
;; This is used to "backtrack" and make the last type be treated as
;; an identifier instead.
`(progn
,(unless short
;; These identifiers are bound only in the inner let.
'(setq identifier-type at-type
identifier-start type-start
got-parens nil
got-identifier t
got-suffix t
got-suffix-after-parens id-start
paren-depth 0))
(if (setq at-type (if (eq backup-at-type 'prefix)
t
backup-at-type))
(setq type-start backup-type-start
id-start backup-id-start)
(setq type-start start-pos
id-start start-pos))
;; When these flags already are set we've found specifiers that
;; unconditionally signal these attributes - backtracking doesn't
;; change that. So keep them set in that case.
(or at-type-decl
(setq at-type-decl backup-at-type-decl))
(or maybe-typeless
(setq maybe-typeless backup-maybe-typeless))
,(unless short
;; This identifier is bound only in the inner let.
'(setq start id-start))))
(defun c-forward-declarator (&optional limit accept-anon)
;; Assuming point is at the start of a declarator, move forward over it,
;; leaving point at the next token after it (e.g. a ) or a ; or a ,).
@ -8235,6 +8214,176 @@ comment at the start of cc-engine.el for more info."
(goto-char here)
nil)))
(defun c-do-declarators
(cdd-limit cdd-list cdd-not-top cdd-comma-prop cdd-function)
"Assuming point is at the start of a comma separated list of declarators,
apply CDD-FUNCTION to each declarator (when CDD-LIST is non-nil) or just the
first declarator (when CDD-LIST is nil). When CDD-FUNCTION is nil, no
function is applied.
CDD-FUNCTION is supplied with 6 arguments:
0. The start position of the declarator's identifier;
1. The end position of this identifier;
\[Note: if there is no identifier, as in int (*);, both of these are nil.]
2. The position of the next token after the declarator (CLARIFY!!!).
3. CDD-NOT-TOP;
4. Non-nil if the identifier is of a function.
5. When there is an initialization following the declarator (such as \"=
....\" or \"( ....\".), the character which introduces this initialization,
otherwise nil.
Additionally, if CDD-COMMA-PROP is non-nil, mark the separating commas with
this value of the c-type property, when CDD-LIST is non-nil.
Stop at or before CDD-LIMIT (which may NOT be nil).
If CDD-NOT-TOP is non-nil, we are not at the top-level (\"top-level\" includes
being directly inside a class or namespace, etc.).
Return non-nil if we've reached the token after the last declarator (often a
semicolon, or a comma when CDD-LIST is nil); otherwise (when we hit CDD-LIMIT,
or fail otherwise) return nil, leaving point at the beginning of the putative
declarator that could not be processed.
This function might do hidden buffer changes."
;; N.B.: We use the "cdd-" prefix in this routine to try to prevent
;; confusion with possible reference to common variable names from within
;; CDD-FUNCTION.
(let
((cdd-pos (point)) cdd-next-pos cdd-id-start cdd-id-end
cdd-decl-res cdd-got-func cdd-got-type cdd-got-init
c-last-identifier-range cdd-exhausted)
;; The following `while' applies `cdd-function' to a single declarator id
;; each time round. It loops only when CDD-LIST is non-nil.
(while
(and (not cdd-exhausted)
(setq cdd-decl-res (c-forward-declarator cdd-limit)))
(setq cdd-next-pos (point)
cdd-id-start (car cdd-decl-res)
cdd-id-end (cadr cdd-decl-res)
cdd-got-func (and (eq (char-after) ?\()
(or (not (c-major-mode-is 'c++-mode))
(not cdd-not-top)
(car (cddr (cddr cdd-decl-res))) ; Id is in
; parens, etc.
(save-excursion
(forward-char)
(c-forward-syntactic-ws)
(looking-at "[*&]")))
(not (car (cddr cdd-decl-res)))
(or (not (c-major-mode-is 'c++-mode))
(save-excursion
(let (c-last-identifier-range)
(forward-char)
(c-forward-syntactic-ws)
(catch 'is-function
(while
(progn
(if (eq (char-after) ?\))
(throw 'is-function t))
(setq cdd-got-type (c-forward-type))
(cond
((null cdd-got-type)
(throw 'is-function nil))
((not (eq cdd-got-type 'maybe))
(throw 'is-function t)))
(c-forward-declarator nil t)
(eq (char-after) ?,))
(forward-char)
(c-forward-syntactic-ws))
t)))))
cdd-got-init (and (cadr (cddr cdd-decl-res))
(char-after)))
;; Jump past any initializer or function prototype to see if
;; there's a ',' to continue at.
(cond (cdd-got-func
;; Skip a parenthesized initializer (C++) or a function
;; prototype.
(if (c-go-list-forward (point) cdd-limit) ; over the parameter list.
(c-forward-syntactic-ws cdd-limit)
(setq cdd-exhausted t))) ; unbalanced parens
(cdd-got-init ; "=" sign OR opening "(", "[", or "{"
;; Skip an initializer expression. If we're at a '='
;; then accept a brace list directly after it to cope
;; with array initializers. Otherwise stop at braces
;; to avoid going past full function and class blocks.
(if (and (if (and (eq cdd-got-init ?=)
(= (c-forward-token-2 1 nil cdd-limit) 0)
(looking-at "{"))
(c-go-list-forward (point) cdd-limit)
t)
;; FIXME: Should look for c-decl-end markers here;
;; we might go far into the following declarations
;; in e.g. ObjC mode (see e.g. methods-4.m).
(c-syntactic-re-search-forward "[;,{]" cdd-limit 'move t))
(backward-char)
(setq cdd-exhausted t)
))
(t (c-forward-syntactic-ws cdd-limit)))
(if cdd-function
(funcall cdd-function cdd-id-start cdd-id-end cdd-next-pos
cdd-not-top cdd-got-func cdd-got-init))
;; If a ',' is found we set cdd-pos to the next declarator and iterate.
(if (and cdd-list (< (point) cdd-limit) (looking-at ","))
(progn
(when cdd-comma-prop
(c-put-char-property (point) 'c-type cdd-comma-prop))
(forward-char)
(c-forward-syntactic-ws cdd-limit)
(setq cdd-pos (point)))
(setq cdd-exhausted t)))
(if (> (point) cdd-pos)
t
(goto-char cdd-pos)
nil)))
;; Macro used inside `c-forward-decl-or-cast-1'. It ought to be a
;; defsubst or perhaps even a defun, but it contains lots of free
;; variables that refer to things inside `c-forward-decl-or-cast-1'.
(defmacro c-fdoc-shift-type-backward (&optional short)
;; `c-forward-decl-or-cast-1' can consume an arbitrary length list
;; of types when parsing a declaration, which means that it
;; sometimes consumes the identifier in the declaration as a type.
;; This is used to "backtrack" and make the last type be treated as
;; an identifier instead.
`(progn
,(unless short
;; These identifiers are bound only in the inner let.
'(setq identifier-type at-type
identifier-start type-start
got-parens nil
got-identifier t
got-suffix t
got-suffix-after-parens id-start
paren-depth 0))
(if (setq at-type (if (eq backup-at-type 'prefix)
t
backup-at-type))
(setq type-start backup-type-start
id-start backup-id-start)
(setq type-start start-pos
id-start start-pos))
;; When these flags already are set we've found specifiers that
;; unconditionally signal these attributes - backtracking doesn't
;; change that. So keep them set in that case.
(or at-type-decl
(setq at-type-decl backup-at-type-decl))
(or maybe-typeless
(setq maybe-typeless backup-maybe-typeless))
,(unless short
;; This identifier is bound only in the inner let.
'(setq start id-start))))
(defun c-forward-decl-or-cast-1 (preceding-token-end context last-cast-end)
;; Move forward over a declaration or a cast if at the start of one.
;; The point is assumed to be at the start of some token. Nil is
@ -10727,12 +10876,17 @@ comment at the start of cc-engine.el for more info."
)))
(defun c-inside-bracelist-p (containing-sexp paren-state accept-in-paren)
;; return the buffer position of the beginning of the brace list
;; statement if we're inside a brace list, otherwise return nil.
;; CONTAINING-SEXP is the buffer pos of the innermost containing
;; paren. PAREN-STATE is the remainder of the state of enclosing
;; braces. ACCEPT-IN-PAREN is non-nil iff we will accept as a brace
;; list a brace directly enclosed in a parenthesis.
;; return the buffer position of the beginning of the brace list statement
;; if CONTAINING-SEXP is inside a brace list, otherwise return nil.
;;
;; CONTAINING-SEXP is the buffer pos of the innermost containing paren. NO
;; IT ISN'T!!! [This function is badly designed, and probably needs
;; reformulating without its first argument, and the critical position being
;; at point.]
;;
;; PAREN-STATE is the remainder of the state of enclosing braces.
;; ACCEPT-IN-PAREN is non-nil iff we will accept as a brace list a brace
;; directly enclosed in a parenthesis.
;;
;; The "brace list" here is recognized solely by its context, not by
;; its contents.
@ -10852,7 +11006,8 @@ comment at the start of cc-engine.el for more info."
(defun c-looking-at-statement-block ()
;; Point is at an opening brace. If this is a statement block (i.e. the
;; elements in the block are terminated by semicolons, or the block is
;; empty, or the block contains a keyword) return t. Otherwise, return nil.
;; empty, or the block contains a keyword) return non-nil. Otherwise,
;; return nil.
(let ((here (point)))
(prog1
(if (c-go-list-forward)
@ -11356,7 +11511,7 @@ comment at the start of cc-engine.el for more info."
(if (and (eq step-type 'same)
(/= paren-pos (point)))
(let (inexpr)
(let (inexpr bspec)
(cond
((save-excursion
(goto-char paren-pos)
@ -11378,6 +11533,13 @@ comment at the start of cc-engine.el for more info."
(c-looking-at-statement-block))
(c-add-syntax 'defun-block-intro nil)
(c-add-syntax 'brace-list-intro nil)))
((save-excursion
(goto-char paren-pos)
(setq bspec (c-looking-at-or-maybe-in-bracelist
containing-sexp containing-sexp))
(and (consp bspec)
(eq (cdr bspec) 'in-paren)))
(c-add-syntax 'brace-list-intro (car bspec)))
(t (c-add-syntax 'defun-block-intro nil))))
(c-add-syntax 'statement-block-intro nil)))
@ -13242,7 +13404,7 @@ Cannot combine absolute offsets %S and %S in `add' method"
nil))))
(if (or (null res) (integerp res)
(and (vectorp res) (= (length res) 1) (integerp (aref res 0))))
(and (vectorp res) (>= (length res) 1) (integerp (aref res 0))))
res
(c-benign-error "Error evaluating offset %S for %s: Got invalid value %S"
offset symbol res)
@ -13265,12 +13427,11 @@ Cannot combine absolute offsets %S and %S in `add' method"
(if c-strict-syntax-p
(c-benign-error "No offset found for syntactic symbol %s" symbol))
(setq offset 0))
(if (vectorp offset)
offset
(or (and (numberp offset) offset)
(and (symbolp offset) (symbol-value offset))
0))
))
(cond
((or (vectorp offset) (numberp offset))
offset)
((and (symbolp offset) (symbol-value offset)))
(t 0))))
(defun c-get-offset (langelem)
;; This is a compatibility wrapper for `c-calc-offset' in case

View file

@ -1032,114 +1032,41 @@ casts and declarations are fontified. Used on level 2 and higher."
;;(message "c-font-lock-declarators from %s to %s" (point) limit)
(c-fontify-types-and-refs
((pos (point)) next-pos id-start
decl-res
id-face got-type got-init
c-last-identifier-range
(separator-prop (if types 'c-decl-type-start 'c-decl-id-start)))
;; The following `while' fontifies a single declarator id each time round.
;; It loops only when LIST is non-nil.
(while
(and pos (setq decl-res (c-forward-declarator)))
(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)))
(or (not (c-major-mode-is 'c++-mode))
(save-excursion
(let (c-last-identifier-range)
(forward-char)
(c-forward-syntactic-ws)
(catch 'is-function
(while
(progn
(if (eq (char-after) ?\))
(throw 'is-function t))
(setq got-type (c-forward-type))
(cond
((null got-type)
(throw 'is-function nil))
((not (eq got-type 'maybe))
(throw 'is-function t)))
(c-forward-declarator nil t)
(eq (char-after) ?,))
(forward-char)
(c-forward-syntactic-ws))
t)))))
'font-lock-function-name-face
'font-lock-variable-name-face)
got-init (and (cadr (cddr decl-res)) ; got-init
(char-after)))
(if types
;; Register and fontify the identifier as a type.
(let ((c-promote-possible-types t))
(goto-char id-start)
(c-forward-type))
;; Fontify the last symbol in the identifier if it isn't fontified
;; already. The check is necessary only in certain cases where this
;; function is used "sloppily", e.g. in `c-simple-decl-matchers'.
(when (and c-last-identifier-range
(not (get-text-property (car c-last-identifier-range)
'face)))
(c-put-font-lock-face (car c-last-identifier-range)
(cdr c-last-identifier-range)
id-face)))
(goto-char next-pos)
(setq pos nil) ; So as to terminate the enclosing `while' form.
(if (and template-class
(eq got-init ?=) ; C++ "<class X = Y>"?
(c-forward-token-2 1 nil limit) ; Over "="
(let ((c-promote-possible-types t))
(c-forward-type t))) ; Over "Y"
(setq list nil)) ; Shouldn't be needed. We can't have a list, here.
(when list
;; Jump past any initializer or function prototype to see if
;; there's a ',' to continue at.
(cond ((eq id-face 'font-lock-function-name-face)
;; Skip a parenthesized initializer (C++) or a function
;; prototype.
(if (c-safe (c-forward-sexp 1) t) ; over the parameter list.
(c-forward-syntactic-ws limit)
(goto-char limit))) ; unbalanced parens
(got-init ; "=" sign OR opening "(", "[", or "{"
;; Skip an initializer expression. If we're at a '='
;; then accept a brace list directly after it to cope
;; with array initializers. Otherwise stop at braces
;; to avoid going past full function and class blocks.
(and (if (and (eq got-init ?=)
(= (c-forward-token-2 1 nil limit) 0)
(looking-at "{"))
(c-safe (c-forward-sexp) t) ; over { .... }
t)
(< (point) limit)
;; FIXME: Should look for c-decl-end markers here;
;; we might go far into the following declarations
;; in e.g. ObjC mode (see e.g. methods-4.m).
(c-syntactic-re-search-forward "[;,{]" limit 'move t)
(backward-char)))
(t (c-forward-syntactic-ws limit)))
;; If a ',' is found we set pos to the next declarator and iterate.
(when (and (< (point) limit) (looking-at ","))
(c-put-char-property (point) 'c-type separator-prop)
(forward-char)
(c-forward-syntactic-ws limit)
(setq pos (point)))))) ; acts to make the `while' form continue.
nil)
()
(c-do-declarators
limit list not-top
(if types 'c-decl-type-start 'c-decl-id-start)
(lambda (id-start id-end end-pos not-top is-function init-char)
(if types
;; Register and fontify the identifier as a type.
(let ((c-promote-possible-types t))
(goto-char id-start)
(c-forward-type))
;; The following doesn't work properly (yet, 2018-09-22).
;; (c-put-font-lock-face id-start id-end
;; (if is-function
;; 'font-lock-function-name-face
;; 'font-lock-variable-name-face))
(when (and c-last-identifier-range
(not (get-text-property (car c-last-identifier-range)
'face)))
;; We use `c-last-identifier-range' rather than `id-start' and
;; `id-end', since the latter two can be erroneous. E.g. in
;; "~Foo", `id-start' is at the tilde. This is a bug in
;; `c-forward-declarator'.
(c-put-font-lock-face (car c-last-identifier-range)
(cdr c-last-identifier-range)
(if is-function
'font-lock-function-name-face
'font-lock-variable-name-face))))
(and template-class
(eq init-char ?=) ; C++ "<class X = Y>"?
(progn
(goto-char end-pos)
(c-forward-token-2 1 nil limit) ; Over "="
(let ((c-promote-possible-types t))
(c-forward-type t))))))
nil))
(defun c-get-fontification-context (match-pos not-front-decl &optional toplev)
;; Return a cons (CONTEXT . RESTRICTED-<>-ARGLISTS) for MATCH-POS.

View file

@ -3258,7 +3258,7 @@ Identifier syntax is in effect when this is matched \(see
"\\|"
"\\.\\.\\."
"\\|"
"[*(&]"
"[*(&~]"
"\\|"
(c-lang-const c-type-decl-prefix-key)
"\\|"

View file

@ -1803,7 +1803,16 @@ Note that this is a strict tail, so won't match, e.g. \"0x....\".")
;; Go to a less nested declaration each time round this loop.
(and
(setq old-pos (point))
(c-syntactic-skip-backward "^;{}" bod-lim t)
(let (pseudo)
(while
(progn
(c-syntactic-skip-backward "^;{}" bod-lim t)
(and (eq (char-before) ?})
(save-excursion
(backward-char)
(setq pseudo (c-cheap-inside-bracelist-p (c-parse-state))))))
(goto-char pseudo))
t)
(> (point) bod-lim)
(progn (c-forward-syntactic-ws)
;; Have we got stuck in a comment at EOB?

View file

@ -68,7 +68,9 @@
(arglist-close . c-lineup-arglist)
(inline-open . 0)
(brace-list-open . +)
(brace-list-intro . c-lineup-arglist-intro-after-paren)
(brace-list-intro . (first
c-lineup-2nd-brace-entry-in-arglist
c-lineup-class-decl-init-+ +))
(topmost-intro-cont
. (first c-lineup-topmost-intro-cont
c-lineup-gnu-DEFUN-intro-cont))))
@ -95,6 +97,9 @@
(label . 0)
(statement-cont . +)
(inline-open . 0)
(brace-list-intro . (first
c-lineup-2nd-brace-entry-in-arglist
c-lineup-class-decl-init-+ +))
(inexpr-class . 0))))
("stroustrup"
@ -104,6 +109,9 @@
(substatement-open . 0)
(substatement-label . 0)
(label . 0)
(brace-list-intro . (first
c-lineup-2nd-brace-entry-in-arglist
c-lineup-class-decl-init-+ +))
(statement-cont . +))))
("whitesmith"
@ -194,6 +202,9 @@
(c-offsets-alist . ((substatement-open . 0)
(inextern-lang . 0)
(arglist-intro . +)
(brace-list-intro . (first
c-lineup-2nd-brace-entry-in-arglist
c-lineup-class-decl-init-+ +))
(knr-argdecl-intro . +)))
(c-hanging-braces-alist . ((brace-list-open)
(brace-list-intro)
@ -219,6 +230,9 @@
(statement-cont . +)
(arglist-intro . c-lineup-arglist-intro-after-paren)
(arglist-close . c-lineup-arglist)
(brace-list-intro . (first
c-lineup-2nd-brace-entry-in-arglist
c-lineup-class-decl-init-+ +))
(access-label . 0)
(inher-cont . c-lineup-java-inher)
(func-decl-cont . c-lineup-java-throws))))

View file

@ -1115,7 +1115,7 @@ can always override the use of `c-default-style' by making calls to
;; Anchor pos: At the brace list decl start(*).
(brace-list-intro . +)
;; Anchor pos: At the brace list decl start(*).
(brace-list-entry . c-lineup-under-anchor)
(brace-list-entry . 0)
;; Anchor pos: At the first non-ws char after the open paren if
;; the first token is on the same line, otherwise boi at that
;; token.