]> git.eshelyaron.com Git - emacs.git/commitdiff
Allow C++ nested brace-list-entries to be better indented.
authorAlan Mackenzie <acm@muc.de>
Wed, 1 Feb 2017 20:20:09 +0000 (20:20 +0000)
committerAlan Mackenzie <acm@muc.de>
Wed, 1 Feb 2017 20:20:09 +0000 (20:20 +0000)
This fixes bug #24431.  The key change of this bug fix is correctly analyzing
nested brace lists when the opening element stands on the same line as both
its introductory brace and an enclosing parameter list parenthesis.

* list/progmodes/cc-align.el (c-lineup-under-anchor): New line-up function.

* list/progmodes/cc-engine.el (c-looking-at-or-maybe-in-bracelist): Accept the
presence of exactly an identifier between an open parenthesis and an open
brace as evidence of the brace starting a brace list.
(c-looking-at-statement-block): New function, extracted from
c-looking-at-inexpr-block.  Enhance it to analyze inner blocks recursively
when needed.
(c-looking-at-inexpr-block): Extract new function (see above) and call it.
(c-add-stmt-syntax): Enhance, with new &optional parameter, to supply the
prime syntactic symbol with a fixed anchor point.  When this is used, restrict
all added syntactic symbols to those having an anchor point on the same line.
Add, in addition to the current additional symbols, c-brace-list-entry when
needed; use c-looking-at-statement-block to determine the latter.
(c-guess-basic-syntax, CASE 9D): Use c-add-stmt-syntax rather than just
c-add-syntax, to assemble the syntactic context of a 'brace-list-entry, thus
getting, possibly, several accompanying syntactic entries.

* lisp/progmodes/cc-styles.el (c-style-alist, "gnu" style): New entry for
'brace-list-intro, namely c-lineup-arglist-intro-after-paren.

* lisp/progmodes/cc-vars.el (c-offsets-alist): Change the factory default
offset for 'brace-list-entry from 0 to c-lineup-under-anchor.

* doc/misc/cc-mode.texi (Syntactic Symbols): Amend the definition of
brace-list-intro.
(Brace List Symbols): Amend the example to show the new analysis of brace
lists when the first element comes on the same line as the opening brace.
(Misc Line-Up): Document the new line-up function c-lineup-under-anchor.

doc/misc/cc-mode.texi
lisp/progmodes/cc-align.el
lisp/progmodes/cc-engine.el
lisp/progmodes/cc-styles.el
lisp/progmodes/cc-vars.el

index 68a16c0ed746d102ecdfce5b928d7cda143990e7..14981c9c58b9fac6b5be9030eb7f28b47959a184 100644 (file)
@@ -4141,7 +4141,8 @@ Open brace of an enum or static array list.  @ref{Brace List Symbols}.
 @item brace-list-close
 Close brace of an enum or static array list.  @ref{Brace List Symbols}.
 @item brace-list-intro
-First line in an enum or static array list.  @ref{Brace List Symbols}.
+First line after the opening @samp{@{} in an enum or static array
+list.  @ref{Brace List Symbols}.
 @item brace-list-entry
 Subsequent lines in an enum or static array list.  @ref{Brace List
 Symbols}.
@@ -4635,11 +4636,18 @@ example:
 
 Here, you've already seen the analysis of lines 1, 2, 3, and 11.  On
 line 4, things get interesting; this line is assigned
-@code{brace-entry-open} syntactic symbol because it's a bracelist entry
-line that starts with an open brace.  Lines 5 and 6 (and line 9) are
-pretty standard, and line 7 is a @code{brace-list-close} as you'd
-expect.  Once again, line 8 is assigned as @code{brace-entry-open} as is
-line 10.
+@code{brace-entry-open} syntactic symbol because it's a bracelist
+entry line that starts with an open brace.  Lines 5 and 6 are pretty
+standard, and line 7 is a @code{brace-list-close} as you'd expect.
+Once again, line 8 is assigned as @code{brace-entry-open} as is line
+10.  Line 9 is assigned two syntactic elements, @code{brace-list-intro}
+with anchor point at the @samp{@{} of line 8@footnote{This extra
+syntactic element was introduced in @ccmode{} 5.33.1 to allow extra
+flexibility in indenting the second line of such a construct.  You can
+preserve the behaviour resulting from the former syntactic analysis by
+giving @code{brace-list-entry} an offset of
+@code{c-lineup-under-anchor} (@pxref{Misc Line-Up}).}, and
+@code{brace-list-entry} anchored on the @samp{1} of line 8.
 
 @comment !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 @node    External Scope Symbols, Paren List Symbols, Brace List Symbols, Syntactic Symbols
@@ -6288,6 +6296,17 @@ already has; think of it as an identity function for lineups.
 
 @comment ------------------------------------------------------------
 
+@defun c-lineup-under-anchor
+
+Line up a line directly underneath its anchor point.  This is like
+@samp{0}, except any previously calculated offset contributions are
+disregarded.
+
+@workswith Any syntactic symbol which has an anchor point.
+@end defun
+
+@comment ------------------------------------------------------------
+
 @defun c-lineup-cpp-define
 @findex lineup-cpp-define (c-)
 Line up macro continuation lines according to the indentation of the
index 7cb36c4396b4bdf0ad9b5c8e1f1a6c1d39237b72..0f7e4b598dc21bb17fcdc31fc3f2697f24682324 100644 (file)
@@ -1221,6 +1221,18 @@ Works with: arglist-cont, arglist-cont-nonempty."
 
        (vector (progn (goto-char alignto) (current-column)))))))
 
+(defun c-lineup-under-anchor (langelem)
+  "Line up the current line directly under the anchor position in LANGELEM.
+
+This is like 0, except it supersedes any indentation already calculated for
+previous syntactic elements in the syntactic context.
+
+Works with: Any syntactic symbol which has an anchor position."
+  (save-excursion
+    (goto-char (c-langelem-pos langelem))
+    (vector (current-column))))
+    
+
 (defun c-lineup-dont-change (langelem)
   "Do not change the indentation of the current line.
 
index fd7aa50840fa3caaddf3b8183c37d7be127c9f17..dfd7aebd5693f90629fa41334d6513834e306249 100644 (file)
@@ -10260,13 +10260,22 @@ comment at the start of cc-engine.el for more info."
                      (t nil)))))
 
       (setq pos (point))
-      (if (and after-type-id-pos
-              (goto-char after-type-id-pos)
-              (setq res (c-back-over-member-initializers))
-              (goto-char res)
-              (eq (car (c-beginning-of-decl-1 lim)) 'same))
-         (cons (point) nil)            ; Return value.
-      
+      (cond
+       ((and after-type-id-pos
+            (goto-char after-type-id-pos)
+            (setq res (c-back-over-member-initializers))
+            (goto-char res)
+            (eq (car (c-beginning-of-decl-1 lim)) 'same))
+       (cons (point) nil))             ; Return value.
+
+       ((and after-type-id-pos
+            (progn
+              (c-backward-syntactic-ws)
+              (eq (char-before) ?\()))
+       ;; Single identifier between '(' and '{'.  We have a bracelist.
+       (cons after-type-id-pos nil))
+
+       (t
        (goto-char pos)
        ;; Checks to do on all sexps before the brace, up to the
        ;; beginning of the statement.
@@ -10368,7 +10377,7 @@ comment at the start of cc-engine.el for more info."
                                        ; languages where
                                        ; `c-opt-inexpr-brace-list-key' is
                                        ; non-nil and we have macros.
-        (t t)))                        ;; The caller can go up one level.
+        (t t))))                       ;; The caller can go up one level.
       )))
 
 (defun c-inside-bracelist-p (containing-sexp paren-state)
@@ -10493,6 +10502,30 @@ comment at the start of cc-engine.el for more info."
   (c-at-statement-start-p))
 (make-obsolete 'c-looking-at-bos 'c-at-statement-start-p "22.1")
 
+(defun c-looking-at-statement-block ()
+  ;; Point is at an opening brace.  If this is a statement block (i.e. the
+  ;; elements in it are terminated by semicolons) return t.  Otherwise, return
+  ;; nil.
+  (let ((here (point)))
+    (prog1
+       (if (c-go-list-forward)
+           (let ((there (point)))
+             (backward-char)
+             (c-syntactic-skip-backward
+              "^;," here t)
+             (cond
+              ((eq (char-before) ?\;) t)
+              ((eq (char-before) ?,) nil)
+              (t (goto-char here)
+                 (forward-char)
+                 (and (c-syntactic-re-search-forward "{" there t t)
+                      (progn (backward-char)
+                             (c-looking-at-statement-block))))))
+         (forward-char)
+         (and (c-syntactic-re-search-forward "[;,]" nil t t)
+              (eq (char-before) ?\;)))
+      (goto-char here))))
+
 (defun c-looking-at-inexpr-block (lim containing-sexp &optional check-at-end)
   ;; Return non-nil if we're looking at the beginning of a block
   ;; inside an expression.  The value returned is actually a cons of
@@ -10648,15 +10681,7 @@ comment at the start of cc-engine.el for more info."
                    (and (c-major-mode-is 'c++-mode)
                         (save-excursion
                           (goto-char block-follows)
-                          (if (c-go-list-forward)
-                              (progn
-                                (backward-char)
-                                (c-syntactic-skip-backward
-                                 "^;," block-follows t)
-                                (not (eq (char-before) ?\;)))
-                            (or (not (c-syntactic-re-search-forward
-                                      "[;,]" nil t t))
-                                (not (eq (char-before) ?\;)))))))
+                          (not (c-looking-at-statement-block)))))
                nil
              (cons 'inexpr-statement (point)))))
 
@@ -10792,17 +10817,20 @@ comment at the start of cc-engine.el for more info."
                          syntax-extra-args
                          stop-at-boi-only
                          containing-sexp
-                         paren-state)
+                         paren-state
+                         &optional fixed-anchor)
   ;; Add the indicated SYNTAX-SYMBOL to `c-syntactic-context', extending it as
   ;; needed with further syntax elements of the types `substatement',
-  ;; `inexpr-statement', `arglist-cont-nonempty', `statement-block-intro', and
-  ;; `defun-block-intro'.
+  ;; `inexpr-statement', `arglist-cont-nonempty', `statement-block-intro',
+  ;; `defun-block-intro', and `brace-list-intro'.
   ;;
-  ;; Do the generic processing to anchor the given syntax symbol on
-  ;; the preceding statement: Skip over any labels and containing
-  ;; statements on the same line, and then search backward until we
-  ;; find a statement or block start that begins at boi without a
-  ;; label or comment.
+  ;; Do the generic processing to anchor the given syntax symbol on the
+  ;; preceding statement: First skip over any labels and containing statements
+  ;; on the same line.  If FIXED-ANCHOR is non-nil, use this as the
+  ;; anchor-point for the given syntactic symbol, and don't make syntactic
+  ;; entries for constructs beginning on lines before that containing
+  ;; ANCHOR-POINT.  Otherwise search backward until we find a statement or
+  ;; block start that begins at boi without a label or comment.
   ;;
   ;; Point is assumed to be at the prospective anchor point for the
   ;; given SYNTAX-SYMBOL.  More syntax entries are added if we need to
@@ -10831,6 +10859,7 @@ comment at the start of cc-engine.el for more info."
 
     (let ((syntax-last c-syntactic-context)
          (boi (c-point 'boi))
+         (anchor-boi (c-point 'boi))
          ;; Set when we're on a label, so that we don't stop there.
          ;; FIXME: To be complete we should check if we're on a label
          ;; now at the start.
@@ -10908,7 +10937,9 @@ comment at the start of cc-engine.el for more info."
                          (c-add-syntax 'substatement nil))))
                 )))
 
-          containing-sexp)
+          containing-sexp
+          (or (null fixed-anchor)
+              (> containing-sexp anchor-boi)))
 
        ;; Now we have to go out of this block.
        (goto-char containing-sexp)
@@ -10982,6 +11013,14 @@ comment at the start of cc-engine.el for more info."
                     (cdr (assoc (match-string 1)
                                 c-other-decl-block-key-in-symbols-alist))
                     (max (c-point 'boi paren-pos) (point))))
+                  ((save-excursion
+                     (goto-char paren-pos)
+                     (c-looking-at-or-maybe-in-bracelist containing-sexp))
+                   (if (save-excursion
+                         (goto-char paren-pos)
+                         (c-looking-at-statement-block))
+                       (c-add-syntax 'defun-block-intro nil)
+                     (c-add-syntax 'brace-list-intro nil)))
                   (t (c-add-syntax 'defun-block-intro nil))))
 
              (c-add-syntax 'statement-block-intro nil)))
@@ -11001,7 +11040,10 @@ comment at the start of cc-engine.el for more info."
          (setq q (cdr (car p))) ; e.g. (nil 28) [from (arglist-cont-nonempty nil 28)]
          (while q
            (unless (car q)
-             (setcar q (point)))
+             (setcar q (if (or (cdr p)
+                               (null fixed-anchor))
+                           (point)
+                         fixed-anchor)))
            (setq q (cdr q)))
          (setq p (cdr p))))
       )))
@@ -12354,7 +12396,8 @@ comment at the start of cc-engine.el for more info."
                             (c-forward-syntactic-ws (c-point 'eol))
                             (c-looking-at-special-brace-list (point)))))
                  (c-add-syntax 'brace-entry-open (point))
-               (c-add-syntax 'brace-list-entry (point))
+               (c-add-stmt-syntax 'brace-list-entry nil t containing-sexp
+                                  paren-state (point))
                ))
           ))))
 
@@ -12848,7 +12891,7 @@ Cannot combine absolute offsets %S and %S in `add' method"
   ;;
   ;; Note that topmost-intro always has an anchor position at bol, for
   ;; historical reasons.  It's often used together with other symbols
-  ;; that has more sane positions.  Since we always use the first
+  ;; that have more sane positions.  Since we always use the first
   ;; found anchor position, we rely on that these other symbols always
   ;; precede topmost-intro in the LANGELEMS list.
   ;;
index d35054905054a6c2a820686f43e73571d457d2cf..b3848a74f97de6fa41f04d43db77ee79bebca6da 100644 (file)
@@ -67,6 +67,7 @@
                         (arglist-close . c-lineup-arglist)
                         (inline-open . 0)
                         (brace-list-open . +)
+                        (brace-list-intro . c-lineup-arglist-intro-after-paren)
                         (topmost-intro-cont
                          . (first c-lineup-topmost-intro-cont
                                   c-lineup-gnu-DEFUN-intro-cont))))
index a6a96d15188b6d33dfc9128e03c588f14af03934..1114b21381d19fefa720f623e33c9675833154dd 100644 (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      . 0)
+       (brace-list-entry      . c-lineup-under-anchor)
        ;; 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.