summaryrefslogtreecommitdiff
path: root/lisp/progmodes
diff options
context:
space:
mode:
authorAlan Mackenzie <acm@muc.de>2017-02-01 20:20:09 +0000
committerAlan Mackenzie <acm@muc.de>2017-02-01 20:20:09 +0000
commit94ad13b93c6fc099a353c8eb27c00a68ee79a952 (patch)
tree4e68066d5b6431089ab1c44092c46995d26c42ba /lisp/progmodes
parent5d61ef0de9a3f5b1be9e93465cb88aae995975ba (diff)
downloademacs-94ad13b93c6fc099a353c8eb27c00a68ee79a952.tar.gz
emacs-94ad13b93c6fc099a353c8eb27c00a68ee79a952.tar.bz2
emacs-94ad13b93c6fc099a353c8eb27c00a68ee79a952.zip
Allow C++ nested brace-list-entries to be better indented.
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.
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/cc-align.el12
-rw-r--r--lisp/progmodes/cc-engine.el101
-rw-r--r--lisp/progmodes/cc-styles.el1
-rw-r--r--lisp/progmodes/cc-vars.el2
4 files changed, 86 insertions, 30 deletions
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
index 7cb36c4396b..0f7e4b598dc 100644
--- a/lisp/progmodes/cc-align.el
+++ b/lisp/progmodes/cc-align.el
@@ -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.
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index fd7aa50840f..dfd7aebd569 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -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.
;;
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
index d3505490505..b3848a74f97 100644
--- a/lisp/progmodes/cc-styles.el
+++ b/lisp/progmodes/cc-styles.el
@@ -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))))
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index a6a96d15188..1114b21381d 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -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.