summaryrefslogtreecommitdiff
path: root/lisp/progmodes/cc-align.el
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2019-03-12 18:33:31 +0000
committerAlan Mackenzie <acm@muc.de>2019-03-12 18:33:31 +0000
commitaa1a4cceca2d93d83c721ce83950230739073727 (patch)
tree5ee9e4a1722b1ffd6b5b545c62e96dafd0ebafe8 /lisp/progmodes/cc-align.el
parentd58c29b345b40b836eeb0d9452a5940beda01fff (diff)
downloademacs-aa1a4cceca2d93d83c721ce83950230739073727.tar.gz
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.
Diffstat (limited to 'lisp/progmodes/cc-align.el')
-rw-r--r--lisp/progmodes/cc-align.el124
1 files changed, 124 insertions, 0 deletions
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index 1f94bfd4fea..009f58ea586 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -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.: