aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Mackenzie2017-11-09 18:34:13 +0000
committerAlan Mackenzie2017-11-09 18:34:13 +0000
commitfc56bea1420266ea6495a2e74df28349458b6fb0 (patch)
treecfd5d9785a0c9b39e32d3ade48c1f0a443efc942
parent9dde8be9cd8dc9defdae282ed24eaf2dd6bf4c31 (diff)
downloademacs-fc56bea1420266ea6495a2e74df28349458b6fb0.tar.gz
emacs-fc56bea1420266ea6495a2e74df28349458b6fb0.zip
Correctly indent C++14 brace lists which are a second argument to a function.
In particular, don't indent contained brace lists in "staircase" fashion. This fixes bug #28623. * lisp/progmodes/cc-engine.el (c-looking-at-or-maybe-in-bracelist): When testing for being enclosed in parens, recognise also a brace directly following a comma, as well as a brace being the first thing inside the paren. Enhance the return value, by indicating when we're directly inside an open paren. (c-inside-bracelist-p): Add an extra argument ACCEPT-IN-PARAM which indicates whether we will accept a bracelist directly inside an open parenthesis. Simplify the manipulation of PAREN-STATE by dispensing with variable LIM and using c-pull-open-brace. Enhance the return value, respecting the new argument. (c-guess-basic-syntax): Save a copy of the initial parse-state in the new variable STATE-CACHE. Use this variable in place of C-STATE-CACHE throughout the function. At CASE 7B, call c-inside-bracelist-p with extra argument nil. At CASE 9, call that function with extra argument t.
-rw-r--r--lisp/progmodes/cc-engine.el105
1 files changed, 58 insertions, 47 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 6f39cc64338..982be3bb3b9 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -10407,16 +10407,20 @@ comment at the start of cc-engine.el for more info."
10407(defun c-looking-at-or-maybe-in-bracelist (&optional containing-sexp lim) 10407(defun c-looking-at-or-maybe-in-bracelist (&optional containing-sexp lim)
10408 ;; Point is at an open brace. If this starts a brace list, return a list 10408 ;; Point is at an open brace. If this starts a brace list, return a list
10409 ;; whose car is the buffer position of the start of the construct which 10409 ;; whose car is the buffer position of the start of the construct which
10410 ;; introduces the list, and whose cdr is t if we have parsed a keyword 10410 ;; introduces the list, and whose cdr is the symbol `in-paren' if the brace
10411 ;; matching `c-opt-inexpr-brace-list-key' (e.g. Java's "new"), nil 10411 ;; is directly enclosed in a parenthesis form (i.e. an arglist), t if we
10412 ;; otherwise. Otherwise, if point might be inside an enclosing brace list, 10412 ;; have parsed a keyword matching `c-opt-inexpr-brace-list-key' (e.g. Java's
10413 ;; return t. If point is definitely neither at nor in a brace list, return 10413 ;; "new"), nil otherwise. Otherwise, if point might be inside an enclosing
10414 ;; nil. 10414 ;; brace list, return t. If point is definitely neither at nor in a brace
10415 ;; list, return nil.
10415 ;; 10416 ;;
10416 ;; CONTAINING-SEXP is the position of the brace/paren/bracket enclosing 10417 ;; CONTAINING-SEXP is the position of the brace/paren/bracket enclosing
10417 ;; POINT, or nil if there is no such position, or we do not know it. LIM is 10418 ;; POINT, or nil if there is no such position, or we do not know it. LIM is
10418 ;; a backward search limit. 10419 ;; a backward search limit.
10419 ;; 10420 ;;
10421 ;; The determination of whether the brace starts a brace list is solely by
10422 ;; the context of the brace, not by its contents.
10423 ;;
10420 ;; Here, "brace list" does not include the body of an enum. 10424 ;; Here, "brace list" does not include the body of an enum.
10421 (save-excursion 10425 (save-excursion
10422 (let ((start (point)) 10426 (let ((start (point))
@@ -10426,17 +10430,20 @@ comment at the start of cc-engine.el for more info."
10426 (and (c-major-mode-is 'pike-mode) 10430 (and (c-major-mode-is 'pike-mode)
10427 c-decl-block-key)) 10431 c-decl-block-key))
10428 (braceassignp 'dontknow) 10432 (braceassignp 'dontknow)
10429 inexpr-brace-list bufpos macro-start res pos after-type-id-pos) 10433 inexpr-brace-list bufpos macro-start res pos after-type-id-pos
10434 in-paren)
10430 10435
10431 (setq res (c-backward-token-2 1 t lim)) 10436 (setq res (c-backward-token-2 1 t lim))
10432 ;; Checks to do only on the first sexp before the brace. 10437 ;; Checks to do only on the first sexp before the brace.
10433 ;; Have we a C++ initialization, without an "="? 10438 ;; Have we a C++ initialization, without an "="?
10434 (if (and (c-major-mode-is 'c++-mode) 10439 (if (and (c-major-mode-is 'c++-mode)
10435 (cond 10440 (cond
10436 ((and (not (eq res 0)) 10441 ((and (or (not (eq res 0))
10442 (eq (char-after) ?,))
10437 (c-go-up-list-backward nil lim) ; FIXME!!! Check ; `lim' 2016-07-12. 10443 (c-go-up-list-backward nil lim) ; FIXME!!! Check ; `lim' 2016-07-12.
10438 (eq (char-after) ?\()) 10444 (eq (char-after) ?\())
10439 (setq braceassignp 'c++-noassign)) 10445 (setq braceassignp 'c++-noassign
10446 in-paren 'in-paren))
10440 ((looking-at c-pre-id-bracelist-key)) 10447 ((looking-at c-pre-id-bracelist-key))
10441 ((looking-at c-return-key)) 10448 ((looking-at c-return-key))
10442 ((and (looking-at c-symbol-start) 10449 ((and (looking-at c-symbol-start)
@@ -10445,9 +10452,11 @@ comment at the start of cc-engine.el for more info."
10445 (t nil)) 10452 (t nil))
10446 (save-excursion 10453 (save-excursion
10447 (cond 10454 (cond
10448 ((not (eq res 0)) 10455 ((or (not (eq res 0))
10456 (eq (char-after) ?,))
10449 (and (c-go-up-list-backward nil lim) ; FIXME!!! Check `lim' 2016-07-12. 10457 (and (c-go-up-list-backward nil lim) ; FIXME!!! Check `lim' 2016-07-12.
10450 (eq (char-after) ?\())) 10458 (eq (char-after) ?\()
10459 (setq in-paren 'in-paren)))
10451 ((looking-at c-pre-id-bracelist-key)) 10460 ((looking-at c-pre-id-bracelist-key))
10452 ((looking-at c-return-key)) 10461 ((looking-at c-return-key))
10453 (t (setq after-type-id-pos (point)) 10462 (t (setq after-type-id-pos (point))
@@ -10486,7 +10495,7 @@ comment at the start of cc-engine.el for more info."
10486 (c-backward-syntactic-ws) 10495 (c-backward-syntactic-ws)
10487 (eq (char-before) ?\())) 10496 (eq (char-before) ?\()))
10488 ;; Single identifier between '(' and '{'. We have a bracelist. 10497 ;; Single identifier between '(' and '{'. We have a bracelist.
10489 (cons after-type-id-pos nil)) 10498 (cons after-type-id-pos 'in-paren))
10490 10499
10491 (t 10500 (t
10492 (goto-char pos) 10501 (goto-char pos)
@@ -10544,7 +10553,7 @@ comment at the start of cc-engine.el for more info."
10544 (braceassignp 10553 (braceassignp
10545 ;; We've hit the beginning of the aggregate list. 10554 ;; We've hit the beginning of the aggregate list.
10546 (c-beginning-of-statement-1 containing-sexp) 10555 (c-beginning-of-statement-1 containing-sexp)
10547 (cons (point) inexpr-brace-list)) 10556 (cons (point) (or in-paren inexpr-brace-list)))
10548 ((and after-type-id-pos 10557 ((and after-type-id-pos
10549 (save-excursion 10558 (save-excursion
10550 (when (eq (char-after) ?\;) 10559 (when (eq (char-after) ?\;)
@@ -10569,7 +10578,7 @@ comment at the start of cc-engine.el for more info."
10569 nil nil)) 10578 nil nil))
10570 (and (consp res) 10579 (and (consp res)
10571 (eq (car res) after-type-id-pos)))))) 10580 (eq (car res) after-type-id-pos))))))
10572 (cons bufpos inexpr-brace-list)) 10581 (cons bufpos (or in-paren inexpr-brace-list)))
10573 ((eq (char-after) ?\;) 10582 ((eq (char-after) ?\;)
10574 ;; Brace lists can't contain a semicolon, so we're done. 10583 ;; Brace lists can't contain a semicolon, so we're done.
10575 ;; (setq containing-sexp nil) 10584 ;; (setq containing-sexp nil)
@@ -10593,12 +10602,16 @@ comment at the start of cc-engine.el for more info."
10593 (t t)))) ;; The caller can go up one level. 10602 (t t)))) ;; The caller can go up one level.
10594 ))) 10603 )))
10595 10604
10596(defun c-inside-bracelist-p (containing-sexp paren-state) 10605(defun c-inside-bracelist-p (containing-sexp paren-state accept-in-paren)
10597 ;; return the buffer position of the beginning of the brace list 10606 ;; return the buffer position of the beginning of the brace list
10598 ;; statement if we're inside a brace list, otherwise return nil. 10607 ;; statement if we're inside a brace list, otherwise return nil.
10599 ;; CONTAINING-SEXP is the buffer pos of the innermost containing 10608 ;; CONTAINING-SEXP is the buffer pos of the innermost containing
10600 ;; paren. PAREN-STATE is the remainder of the state of enclosing 10609 ;; paren. PAREN-STATE is the remainder of the state of enclosing
10601 ;; braces 10610 ;; braces. ACCEPT-IN-PAREN is non-nil iff we will accept as a brace
10611 ;; list a brace directly enclosed in a parenthesis.
10612 ;;
10613 ;; The "brace list" here is recognized solely by its context, not by
10614 ;; its contents.
10602 ;; 10615 ;;
10603 ;; N.B.: This algorithm can potentially get confused by cpp macros 10616 ;; N.B.: This algorithm can potentially get confused by cpp macros
10604 ;; placed in inconvenient locations. It's a trade-off we make for 10617 ;; placed in inconvenient locations. It's a trade-off we make for
@@ -10613,17 +10626,11 @@ comment at the start of cc-engine.el for more info."
10613 ;; this will pick up array/aggregate init lists, even if they are nested. 10626 ;; this will pick up array/aggregate init lists, even if they are nested.
10614 (save-excursion 10627 (save-excursion
10615 (let ((bufpos t) 10628 (let ((bufpos t)
10616 lim next-containing) 10629 next-containing)
10617 (while (and (eq bufpos t) 10630 (while (and (eq bufpos t)
10618 containing-sexp) 10631 containing-sexp)
10619 (when paren-state 10632 (when paren-state
10620 (if (consp (car paren-state)) 10633 (setq next-containing (c-pull-open-brace paren-state)))
10621 (setq lim (cdr (car paren-state))
10622 paren-state (cdr paren-state))
10623 (setq lim (car paren-state)))
10624 (when paren-state
10625 (setq next-containing (car paren-state)
10626 paren-state (cdr paren-state))))
10627 10634
10628 (goto-char containing-sexp) 10635 (goto-char containing-sexp)
10629 (if (c-looking-at-inexpr-block next-containing next-containing) 10636 (if (c-looking-at-inexpr-block next-containing next-containing)
@@ -10632,14 +10639,16 @@ comment at the start of cc-engine.el for more info."
10632 ;; containing sexp, so that c-looking-at-inexpr-block 10639 ;; containing sexp, so that c-looking-at-inexpr-block
10633 ;; doesn't check for an identifier before it. 10640 ;; doesn't check for an identifier before it.
10634 (setq bufpos nil) 10641 (setq bufpos nil)
10635 (when (or (not (eq (char-after) ?{)) 10642 (if (not (eq (char-after) ?{))
10636 (eq (setq bufpos (c-looking-at-or-maybe-in-bracelist 10643 (setq bufpos nil)
10637 next-containing lim)) 10644 (when (eq (setq bufpos (c-looking-at-or-maybe-in-bracelist
10638 t)) 10645 next-containing next-containing))
10639 (setq containing-sexp next-containing 10646 t)
10640 lim nil 10647 (setq containing-sexp next-containing
10641 next-containing nil)))) 10648 next-containing nil)))))
10642 (and (consp bufpos) (car bufpos)))))) 10649 (and (consp bufpos)
10650 (or accept-in-paren (not (eq (cdr bufpos) 'in-paren)))
10651 (car bufpos))))))
10643 10652
10644(defun c-looking-at-special-brace-list (&optional _lim) 10653(defun c-looking-at-special-brace-list (&optional _lim)
10645 ;; If we're looking at the start of a pike-style list, i.e., `({ })', 10654 ;; If we're looking at the start of a pike-style list, i.e., `({ })',
@@ -11506,6 +11515,7 @@ comment at the start of cc-engine.el for more info."
11506 ;; The paren state outside `containing-sexp', or at 11515 ;; The paren state outside `containing-sexp', or at
11507 ;; `indent-point' if `containing-sexp' is nil. 11516 ;; `indent-point' if `containing-sexp' is nil.
11508 (paren-state (c-parse-state)) 11517 (paren-state (c-parse-state))
11518 (state-cache (copy-tree paren-state))
11509 ;; There's always at most one syntactic element which got 11519 ;; There's always at most one syntactic element which got
11510 ;; an anchor pos. It's stored in syntactic-relpos. 11520 ;; an anchor pos. It's stored in syntactic-relpos.
11511 syntactic-relpos 11521 syntactic-relpos
@@ -11668,7 +11678,7 @@ comment at the start of cc-engine.el for more info."
11668 (not (c-at-vsemi-p before-ws-ip)) 11678 (not (c-at-vsemi-p before-ws-ip))
11669 (not (memq char-after-ip '(?\) ?\] ?,))) 11679 (not (memq char-after-ip '(?\) ?\] ?,)))
11670 (or (not (eq char-before-ip ?})) 11680 (or (not (eq char-before-ip ?}))
11671 (c-looking-at-inexpr-block-backward c-state-cache)) 11681 (c-looking-at-inexpr-block-backward state-cache))
11672 (> (point) 11682 (> (point)
11673 (progn 11683 (progn
11674 ;; Ought to cache the result from the 11684 ;; Ought to cache the result from the
@@ -11746,7 +11756,7 @@ comment at the start of cc-engine.el for more info."
11746 (if containing-sexp 11756 (if containing-sexp
11747 (progn 11757 (progn
11748 (goto-char containing-sexp) 11758 (goto-char containing-sexp)
11749 (setq lim (c-most-enclosing-brace c-state-cache 11759 (setq lim (c-most-enclosing-brace state-cache
11750 containing-sexp)) 11760 containing-sexp))
11751 (c-backward-to-block-anchor lim) 11761 (c-backward-to-block-anchor lim)
11752 (c-add-stmt-syntax 'case-label nil t lim paren-state)) 11762 (c-add-stmt-syntax 'case-label nil t lim paren-state))
@@ -11772,7 +11782,7 @@ comment at the start of cc-engine.el for more info."
11772 11782
11773 (containing-sexp 11783 (containing-sexp
11774 (goto-char containing-sexp) 11784 (goto-char containing-sexp)
11775 (setq lim (c-most-enclosing-brace c-state-cache 11785 (setq lim (c-most-enclosing-brace state-cache
11776 containing-sexp)) 11786 containing-sexp))
11777 (save-excursion 11787 (save-excursion
11778 (setq tmpsymbol 11788 (setq tmpsymbol
@@ -11816,7 +11826,7 @@ comment at the start of cc-engine.el for more info."
11816 (goto-char (cdr placeholder)) 11826 (goto-char (cdr placeholder))
11817 (back-to-indentation) 11827 (back-to-indentation)
11818 (c-add-stmt-syntax tmpsymbol nil t 11828 (c-add-stmt-syntax tmpsymbol nil t
11819 (c-most-enclosing-brace c-state-cache (point)) 11829 (c-most-enclosing-brace state-cache (point))
11820 paren-state) 11830 paren-state)
11821 (unless (eq (point) (cdr placeholder)) 11831 (unless (eq (point) (cdr placeholder))
11822 (c-add-syntax (car placeholder)))) 11832 (c-add-syntax (car placeholder))))
@@ -12239,11 +12249,11 @@ comment at the start of cc-engine.el for more info."
12239 (and (eq (char-before) ?}) 12249 (and (eq (char-before) ?})
12240 (save-excursion 12250 (save-excursion
12241 (let ((start (point))) 12251 (let ((start (point)))
12242 (if (and c-state-cache 12252 (if (and state-cache
12243 (consp (car c-state-cache)) 12253 (consp (car state-cache))
12244 (eq (cdar c-state-cache) (point))) 12254 (eq (cdar state-cache) (point)))
12245 ;; Speed up the backward search a bit. 12255 ;; Speed up the backward search a bit.
12246 (goto-char (caar c-state-cache))) 12256 (goto-char (caar state-cache)))
12247 (c-beginning-of-decl-1 containing-sexp) ; Can't use `lim' here. 12257 (c-beginning-of-decl-1 containing-sexp) ; Can't use `lim' here.
12248 (setq placeholder (point)) 12258 (setq placeholder (point))
12249 (if (= start (point)) 12259 (if (= start (point))
@@ -12400,7 +12410,8 @@ comment at the start of cc-engine.el for more info."
12400 ((and (eq char-after-ip ?{) 12410 ((and (eq char-after-ip ?{)
12401 (progn 12411 (progn
12402 (setq placeholder (c-inside-bracelist-p (point) 12412 (setq placeholder (c-inside-bracelist-p (point)
12403 paren-state)) 12413 paren-state
12414 nil))
12404 (if placeholder 12415 (if placeholder
12405 (setq tmpsymbol '(brace-list-open . inexpr-class)) 12416 (setq tmpsymbol '(brace-list-open . inexpr-class))
12406 (setq tmpsymbol '(block-open . inexpr-statement) 12417 (setq tmpsymbol '(block-open . inexpr-statement)
@@ -12482,7 +12493,7 @@ comment at the start of cc-engine.el for more info."
12482 (skip-chars-forward " \t")) 12493 (skip-chars-forward " \t"))
12483 (goto-char placeholder)) 12494 (goto-char placeholder))
12484 (c-add-stmt-syntax 'arglist-cont-nonempty (list containing-sexp) t 12495 (c-add-stmt-syntax 'arglist-cont-nonempty (list containing-sexp) t
12485 (c-most-enclosing-brace c-state-cache (point)) 12496 (c-most-enclosing-brace state-cache (point))
12486 paren-state)) 12497 paren-state))
12487 12498
12488 ;; CASE 7G: we are looking at just a normal arglist 12499 ;; CASE 7G: we are looking at just a normal arglist
@@ -12523,7 +12534,7 @@ comment at the start of cc-engine.el for more info."
12523 (save-excursion 12534 (save-excursion
12524 (goto-char containing-sexp) 12535 (goto-char containing-sexp)
12525 (c-looking-at-special-brace-list))) 12536 (c-looking-at-special-brace-list)))
12526 (c-inside-bracelist-p containing-sexp paren-state)))) 12537 (c-inside-bracelist-p containing-sexp paren-state t))))
12527 (cond 12538 (cond
12528 12539
12529 ;; CASE 9A: In the middle of a special brace list opener. 12540 ;; CASE 9A: In the middle of a special brace list opener.
@@ -12571,7 +12582,7 @@ comment at the start of cc-engine.el for more info."
12571 (= (point) containing-sexp))) 12582 (= (point) containing-sexp)))
12572 (if (eq (point) (c-point 'boi)) 12583 (if (eq (point) (c-point 'boi))
12573 (c-add-syntax 'brace-list-close (point)) 12584 (c-add-syntax 'brace-list-close (point))
12574 (setq lim (c-most-enclosing-brace c-state-cache (point))) 12585 (setq lim (c-most-enclosing-brace state-cache (point)))
12575 (c-beginning-of-statement-1 lim nil nil t) 12586 (c-beginning-of-statement-1 lim nil nil t)
12576 (c-add-stmt-syntax 'brace-list-close nil t lim paren-state))) 12587 (c-add-stmt-syntax 'brace-list-close nil t lim paren-state)))
12577 12588
@@ -12597,7 +12608,7 @@ comment at the start of cc-engine.el for more info."
12597 (goto-char containing-sexp)) 12608 (goto-char containing-sexp))
12598 (if (eq (point) (c-point 'boi)) 12609 (if (eq (point) (c-point 'boi))
12599 (c-add-syntax 'brace-list-intro (point)) 12610 (c-add-syntax 'brace-list-intro (point))
12600 (setq lim (c-most-enclosing-brace c-state-cache (point))) 12611 (setq lim (c-most-enclosing-brace state-cache (point)))
12601 (c-beginning-of-statement-1 lim) 12612 (c-beginning-of-statement-1 lim)
12602 (c-add-stmt-syntax 'brace-list-intro nil t lim paren-state))) 12613 (c-add-stmt-syntax 'brace-list-intro nil t lim paren-state)))
12603 12614
@@ -12619,7 +12630,7 @@ comment at the start of cc-engine.el for more info."
12619 ((and (not (memq char-before-ip '(?\; ?:))) 12630 ((and (not (memq char-before-ip '(?\; ?:)))
12620 (not (c-at-vsemi-p before-ws-ip)) 12631 (not (c-at-vsemi-p before-ws-ip))
12621 (or (not (eq char-before-ip ?})) 12632 (or (not (eq char-before-ip ?}))
12622 (c-looking-at-inexpr-block-backward c-state-cache)) 12633 (c-looking-at-inexpr-block-backward state-cache))
12623 (> (point) 12634 (> (point)
12624 (save-excursion 12635 (save-excursion
12625 (c-beginning-of-statement-1 containing-sexp) 12636 (c-beginning-of-statement-1 containing-sexp)
@@ -12753,7 +12764,7 @@ comment at the start of cc-engine.el for more info."
12753 (skip-chars-forward " \t")) 12764 (skip-chars-forward " \t"))
12754 (goto-char placeholder)) 12765 (goto-char placeholder))
12755 (c-add-stmt-syntax 'template-args-cont (list containing-<) t 12766 (c-add-stmt-syntax 'template-args-cont (list containing-<) t
12756 (c-most-enclosing-brace c-state-cache (point)) 12767 (c-most-enclosing-brace state-cache (point))
12757 paren-state)) 12768 paren-state))
12758 12769
12759 ;; CASE 17: Statement or defun catchall. 12770 ;; CASE 17: Statement or defun catchall.
@@ -12827,7 +12838,7 @@ comment at the start of cc-engine.el for more info."
12827 (goto-char (cdr placeholder)) 12838 (goto-char (cdr placeholder))
12828 (back-to-indentation) 12839 (back-to-indentation)
12829 (c-add-stmt-syntax tmpsymbol nil t 12840 (c-add-stmt-syntax tmpsymbol nil t
12830 (c-most-enclosing-brace c-state-cache (point)) 12841 (c-most-enclosing-brace state-cache (point))
12831 paren-state) 12842 paren-state)
12832 (if (/= (point) (cdr placeholder)) 12843 (if (/= (point) (cdr placeholder))
12833 (c-add-syntax (car placeholder)))) 12844 (c-add-syntax (car placeholder))))