Skip to content

Commit 643e323

Browse files
author
Alan Mackenzie
committed
CC Mode: Fix various minor indentation bugs
As part of this, introduce a second anchor point to the syntactic symbols brace-list-intro and enum-intro, the position of the opening brace. * lisp/progmodes/cc-align.el (c-lineup-item-after-paren-at-boi): New function. * /lisp/progmodes/cc-engine.el (c-foreign-truncate-lit-pos-cache) (c-foreign-init-lit-pos-cache): Use c-truncate-lit-pos/state-cache in place of an older function. (c-no-bracelist-cache): Update its definition to exclude conses. (c-strip-conses): New function. (c-inside-bracelist-p): Use c-strip-conses. (c-add-stmt-syntax): In the "go out a block" loop, go out of a brace at BOI when there's non-whitespace text after it. Refactor an `if' form containing a cond form into a cond form. Add the new second second anchor point into syntactic contexts with brace-list-intro and enum-intro. Anchor brace-list-close and enum-close elements on the individual declarations in struct, etc., variable declarations. (c-guess-basic-syntax, CASE 20): Use the new constraint-cont syntactic symbol. (c-guess-basic-syntax, CASE 9B): Anchor brace-list-close and enum-close elements on the individual declarations in struct, etc., variable declarations. (c-guess-basic-syntax, CASEs 9C, 9D): Add the new second anchor point into brace-list-intro and enum-intro syntactic contexts. * lisp/progmodes/cc-mode.el (c-locate-first-punctuation-prop): New function. (c-depropertize-CPP): Use c-locate-first-punctuation-prop. * lisp/progmodes/cc-vars.el (c-offsets-alist): Amend the entries for constraint-cont, brace-list-intro, and enum-intro, using c-lineup-item-after-paren-at-boi. * doc/misc/cc-mode.texi (List Line-Up): Add a description of c-lineup-item-after-paren-at-boi.
1 parent 2f1052d commit 643e323

File tree

5 files changed

+189
-65
lines changed

5 files changed

+189
-65
lines changed

doc/misc/cc-mode.texi

+27
Original file line numberDiff line numberDiff line change
@@ -6192,6 +6192,33 @@ to perform indentation.
61926192

61936193
@comment ------------------------------------------------------------
61946194

6195+
@defun c-lineup-item-after-paren-at-boi
6196+
@findex lineup-item-after-paren-at-boi (c-)
6197+
Line up under the first entry on the same line as an open parenthesis
6198+
when that parenthesis is the lefmost non-space character in its line.
6199+
For example:
6200+
6201+
@example
6202+
@group
6203+
template <typename T>
6204+
requires
6205+
( requires (T t) @{ ++t; @}
6206+
&& Baz<T>) @hereFn{constraint-cont}
6207+
int foo();
6208+
@end group
6209+
@end example
6210+
6211+
6212+
This function is intended for use in a list. If the construct being
6213+
analyzed doesn't conform to the above description, the function
6214+
returns nil. Otherwise it returns a vector containing the indentation.
6215+
6216+
@workswith{} @code{brace-list-intro}, @code{enum-intro},
6217+
@code{constraint-cont}.
6218+
@end defun
6219+
6220+
@comment ------------------------------------------------------------
6221+
61956222
@defun c-lineup-class-decl-init-+
61966223
@findex lineup-class-decl-init-+ (c-)
61976224
Line up the second entry of a class (etc.) initializer

lisp/progmodes/cc-align.el

+24
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,30 @@ statement-block-intro, statement-case-intro, arglist-intro."
314314
(if (eolp) (skip-chars-backward " \t"))
315315
(vector (current-column))))
316316

317+
(defun c-lineup-item-after-paren-at-boi (_langelem)
318+
"Line up a *-cont line to just after the surrounding open paren at boi.
319+
\"paren\" here can also mean \"brace\", etc. We line up under the first
320+
non-whitespace text after the paren. If there is no such paren, or no
321+
such text, return nil, allowing another function to handle the
322+
construct.
323+
324+
Works with: brace-list-intro, enum-intro, constraint-cont."
325+
(save-excursion
326+
(beginning-of-line)
327+
(and
328+
(if (c-langelem-2nd-pos c-syntactic-element)
329+
;; brace-list-intro, enum-intro.
330+
(progn (goto-char (c-langelem-2nd-pos c-syntactic-element))
331+
t)
332+
;; constraint-cont.
333+
(c-go-up-list-backward nil (c-langelem-pos c-syntactic-element)))
334+
(eq (point) (c-point 'boi))
335+
(looking-at "\\s(")
336+
(progn (forward-char)
337+
(c-forward-syntactic-ws (c-point 'eol))
338+
(unless (eolp)
339+
(vector (current-column)))))))
340+
317341
(defun c-lineup-arglist-close-under-paren (langelem)
318342
"Line up a line under the enclosing open paren.
319343
Normally used to line up a closing paren in the same column as its

lisp/progmodes/cc-engine.el

+118-61
Original file line numberDiff line numberDiff line change
@@ -3233,7 +3233,7 @@ This function should be added to the `before-change-functions'
32333233
hook by major modes that use CC Mode's filling functionality
32343234
without initializing CC Mode. Currently (2020-06) these are
32353235
`js-mode' and `mhtml-mode'."
3236-
(c-truncate-lit-pos-cache beg))
3236+
(c-truncate-lit-pos/state-cache beg))
32373237

32383238
(defun c-foreign-init-lit-pos-cache ()
32393239
"Initialize CC Mode's literal cache.
@@ -3242,7 +3242,7 @@ This function should be called from the mode functions of major
32423242
modes which use CC Mode's filling functionality without
32433243
initializing CC Mode. Currently (2020-06) these are `js-mode' and
32443244
`mhtml-mode'."
3245-
(c-truncate-lit-pos-cache 1))
3245+
(c-truncate-lit-pos/state-cache 1))
32463246

32473247

32483248
;; A system for finding noteworthy parens before the point.
@@ -13365,12 +13365,21 @@ comment at the start of cc-engine.el for more info."
1336513365
(t t)))) ;; The caller can go up one level.
1336613366
))))
1336713367

13368-
;; A list of the form returned by `c-parse-state'. Each opening brace in it
13369-
;; is not the brace of a brace list. Any cons items in it are ignored, and
13370-
;; are also unreliable.
13368+
;; A list of the form returned by `c-parse-state', but without conses. Each
13369+
;; opening brace in it is not the brace of a brace list.
1337113370
(defvar c-no-bracelist-cache nil)
1337213371
(make-variable-buffer-local 'c-no-bracelist-cache)
1337313372

13373+
(defun c-strip-conses (liszt)
13374+
;; Make a copy of the list LISZT, removing conses from the copy. Return the
13375+
;; result.
13376+
(let ((ptr liszt) new)
13377+
(while ptr
13378+
(if (atom (car ptr))
13379+
(push (car ptr) new))
13380+
(setq ptr (cdr ptr)))
13381+
(nreverse new)))
13382+
1337413383
(defun c-inside-bracelist-p (containing-sexp paren-state accept-in-paren)
1337513384
;; Return the buffer position of the beginning of the brace list statement
1337613385
;; if CONTAINING-SEXP is inside a brace list, otherwise return nil.
@@ -13433,13 +13442,13 @@ comment at the start of cc-engine.el for more info."
1343313442
(not (memq next-containing c-no-bracelist-cache)))
1343413443
(setq next-containing (c-pull-open-brace paren-state)))
1343513444
(setq c-no-bracelist-cache
13436-
(nconc whole-paren-state
13445+
(nconc (c-strip-conses whole-paren-state)
1343713446
(and next-containing (list next-containing))
1343813447
paren-state))
1343913448
nil)
1344013449
((not (memq containing-sexp c-no-bracelist-cache))
1344113450
;; Update `c-no-bracelist-cache'
13442-
(setq c-no-bracelist-cache (copy-tree whole-paren-state))
13451+
(setq c-no-bracelist-cache (c-strip-conses whole-paren-state))
1344313452
nil)))))
1344413453

1344513454
(defun c-looking-at-special-brace-list ()
@@ -14067,6 +14076,7 @@ comment at the start of cc-engine.el for more info."
1406714076
(let ((syntax-last c-syntactic-context)
1406814077
(boi (c-point 'boi))
1406914078
(anchor-boi (c-point 'boi))
14079+
(anchor-point-2 containing-sexp)
1407014080
;; Set when we're on a label, so that we don't stop there.
1407114081
;; FIXME: To be complete we should check if we're on a label
1407214082
;; now at the start.
@@ -14078,17 +14088,24 @@ comment at the start of cc-engine.el for more info."
1407814088
(point) nil)
1407914089
syntax-extra-args)
1408014090

14081-
;; Loop while we have to back out of containing blocks.
14091+
;; Each time round the following loop, back out of the containing block.
14092+
;; Do this unless `fixed-anchor' is non-nil and `containing-sexp' is at
14093+
;; or before the BOI of the anchor position. Carry on until the inner
14094+
;; `while' loop fails to back up to `containing-sexp', or we reach the
14095+
;; top level, or `containing-sexp' is before the initial anchor point.
1408214096
(while
1408314097
(and
1408414098
(catch 'back-up-block
1408514099

14086-
;; Loop while we have to back up statements.
14100+
;; Each time round the following loop, back up a single
14101+
;; statement until we reach a BOS at BOI, or `containing-sexp',
14102+
;; or any previous statement when `stop-at-boi-only' is nil.
14103+
;; More or less. Read the source for full details. ;-(
1408714104
(while (or (/= (point) boi)
1408814105
on-label
1408914106
(looking-at c-comment-start-regexp))
1409014107

14091-
;; Skip past any comments that stands between the
14108+
;; Skip past any comments that stand between the
1409214109
;; statement start and boi.
1409314110
(let ((savepos (point)))
1409414111
(while (and (/= savepos boi)
@@ -14146,7 +14163,11 @@ comment at the start of cc-engine.el for more info."
1414614163

1414714164
containing-sexp
1414814165
(or (null fixed-anchor)
14149-
(> containing-sexp anchor-boi)))
14166+
(> containing-sexp anchor-boi)
14167+
(save-excursion
14168+
(goto-char (1+ containing-sexp))
14169+
(c-forward-syntactic-ws (c-point 'eol))
14170+
(< (point) (c-point 'eol)))))
1415014171

1415114172
;; Now we have to go out of this block.
1415214173
(goto-char containing-sexp)
@@ -14168,7 +14189,7 @@ comment at the start of cc-engine.el for more info."
1416814189
;; from and add the right syntactic element for it.
1416914190
(let ((paren-pos (point))
1417014191
(paren-char (char-after))
14171-
step-type)
14192+
step-type anchor-point)
1417214193

1417314194
(if (eq paren-char ?\()
1417414195
;; Stepped out of a parenthesis block, so we're in an
@@ -14199,45 +14220,62 @@ comment at the start of cc-engine.el for more info."
1419914220
on-label nil))
1420014221

1420114222
;; Stepped out of a brace block.
14223+
(save-excursion
14224+
(if (and (zerop (c-backward-token-2))
14225+
(looking-at "=\\([^=]\\|$\\)")
14226+
(zerop (c-backward-token-2))
14227+
(looking-at c-symbol-key)
14228+
(not (looking-at c-keywords-regexp)))
14229+
(setq anchor-point (point))))
14230+
(if anchor-point
14231+
(progn (goto-char anchor-point)
14232+
(setq step-type 'same
14233+
on-label nil))
14234+
1420214235
(setq step-type (c-beginning-of-statement-1 containing-sexp)
14203-
on-label (eq step-type 'label))
14236+
on-label (eq step-type 'label)))
1420414237

14205-
(if (and (eq step-type 'same)
14206-
(/= paren-pos (point)))
14207-
(let (inexpr bspec)
14208-
(cond
14209-
((save-excursion
14210-
(goto-char paren-pos)
14211-
(setq inexpr (c-looking-at-inexpr-block
14212-
(c-safe-position containing-sexp paren-state)
14213-
containing-sexp)))
14214-
(c-add-syntax (if (eq (car inexpr) 'inlambda)
14215-
'defun-block-intro
14216-
'statement-block-intro)
14217-
nil))
14218-
((looking-at c-other-decl-block-key)
14219-
(c-add-syntax
14220-
(cdr (assoc (match-string 1)
14221-
c-other-decl-block-key-in-symbols-alist))
14222-
(max (c-point 'boi paren-pos) (point))))
14223-
((c-at-enum-brace paren-pos)
14224-
(c-add-syntax 'enum-intro nil))
14225-
((c-inside-bracelist-p paren-pos paren-state nil)
14226-
(if (save-excursion
14227-
(goto-char paren-pos)
14228-
(c-looking-at-statement-block))
14229-
(c-add-syntax 'defun-block-intro nil)
14230-
(c-add-syntax 'brace-list-intro nil)))
14231-
((save-excursion
14238+
(let (inexpr bspec)
14239+
(cond
14240+
((or (not (eq step-type 'same))
14241+
(eq paren-pos (point)))
14242+
(if (and (eq paren-pos (point))
14243+
(c-inside-bracelist-p paren-pos paren-state nil))
14244+
(c-add-syntax 'brace-list-intro nil anchor-point-2)
14245+
(c-add-syntax 'statement-block-intro nil)))
14246+
((save-excursion
14247+
(goto-char paren-pos)
14248+
(setq inexpr (c-looking-at-inexpr-block
14249+
(c-safe-position containing-sexp paren-state)
14250+
containing-sexp)))
14251+
(c-add-syntax (if (eq (car inexpr) 'inlambda)
14252+
'defun-block-intro
14253+
'statement-block-intro)
14254+
nil))
14255+
((looking-at c-other-decl-block-key)
14256+
(c-add-syntax
14257+
(cdr (assoc (match-string 1)
14258+
c-other-decl-block-key-in-symbols-alist))
14259+
(max (c-point 'boi paren-pos) (point))))
14260+
((c-at-enum-brace paren-pos)
14261+
(c-add-syntax 'enum-intro nil anchor-point-2))
14262+
((c-inside-bracelist-p paren-pos paren-state nil)
14263+
(if (save-excursion
1423214264
(goto-char paren-pos)
14233-
(setq bspec (c-looking-at-or-maybe-in-bracelist
14234-
containing-sexp containing-sexp))
14235-
(and (consp bspec)
14236-
(eq (cdr bspec) 'in-paren)))
14237-
(c-add-syntax 'brace-list-intro (car bspec)))
14238-
(t (c-add-syntax 'defun-block-intro nil))))
14265+
(c-looking-at-statement-block))
14266+
(c-add-syntax 'defun-block-intro nil)
14267+
(c-add-syntax 'brace-list-intro nil anchor-point-2)))
14268+
((save-excursion
14269+
(goto-char paren-pos)
14270+
(setq bspec (c-looking-at-or-maybe-in-bracelist
14271+
containing-sexp containing-sexp))
14272+
(and (consp bspec)
14273+
(eq (cdr bspec) 'in-paren)))
14274+
(c-add-syntax 'brace-list-intro (car bspec)
14275+
anchor-point-2))
14276+
(t (c-add-syntax 'defun-block-intro nil))))
1423914277

14240-
(c-add-syntax 'statement-block-intro nil)))
14278+
(setq anchor-point-2 containing-sexp))
1424114279

1424214280
(if (= paren-pos boi)
1424314281
;; Always done if the open brace was at boi. The
@@ -15489,9 +15527,13 @@ comment at the start of cc-engine.el for more info."
1548915527
(not (eq (cdr tmp) 'expression))
1549015528
(setq placeholder (car tmp)))
1549115529
(c-add-syntax
15492-
(if (eq char-after-ip ?{)
15493-
'substatement-open
15494-
'substatement)
15530+
(cond
15531+
((and (eq (char-after containing-sexp) ?\()
15532+
(> containing-sexp placeholder))
15533+
'constraint-cont)
15534+
((eq char-after-ip ?{)
15535+
'substatement-open)
15536+
(t 'substatement))
1549515537
(c-point 'boi placeholder)))
1549615538

1549715539
;; ((Old) CASE 6 has been removed.)
@@ -15761,7 +15803,17 @@ comment at the start of cc-engine.el for more info."
1576115803
(c-determine-limit 1000))
1576215804
(point)))
1576315805
(c-most-enclosing-brace state-cache (point))))
15764-
(c-beginning-of-statement-1 lim nil nil t)
15806+
(save-excursion
15807+
(setq placeholder
15808+
(and (zerop (c-backward-token-2))
15809+
(looking-at "=\\([^=]\\|$\\)")
15810+
(zerop (c-backward-token-2))
15811+
(looking-at c-symbol-key)
15812+
(not (looking-at c-keywords-regexp))
15813+
(point))))
15814+
(if placeholder
15815+
(goto-char placeholder)
15816+
(c-beginning-of-statement-1 lim nil nil t))
1576515817
(c-add-stmt-syntax (if enum-pos 'enum-close 'brace-list-close)
1576615818
nil t lim paren-state)))
1576715819

@@ -15790,7 +15842,7 @@ comment at the start of cc-engine.el for more info."
1579015842
(goto-char containing-sexp))
1579115843
(if (eq (point) (c-point 'boi))
1579215844
(c-add-syntax (if enum-pos 'enum-intro 'brace-list-intro)
15793-
(point))
15845+
(point) containing-sexp)
1579415846
(setq lim (or (save-excursion
1579515847
(and
1579615848
(c-back-over-member-initializers
@@ -15799,20 +15851,25 @@ comment at the start of cc-engine.el for more info."
1579915851
(c-most-enclosing-brace state-cache (point))))
1580015852
(c-beginning-of-statement-1 lim nil nil t)
1580115853
(c-add-stmt-syntax (if enum-pos 'enum-intro 'brace-list-intro)
15802-
nil t lim paren-state)))
15854+
(list containing-sexp)
15855+
t lim paren-state)))
1580315856

1580415857
;; CASE 9D: this is just a later brace-list-entry/enum-entry or
1580515858
;; brace-entry-open
15806-
(t (if (or (eq char-after-ip ?{)
15807-
(and c-special-brace-lists
15808-
(save-excursion
15809-
(goto-char indent-point)
15810-
(c-forward-syntactic-ws (c-point 'eol))
15811-
(c-looking-at-special-brace-list))))
15812-
(c-add-syntax 'brace-entry-open (point))
15859+
(t (cond
15860+
((or (eq char-after-ip ?{)
15861+
(and c-special-brace-lists
15862+
(save-excursion
15863+
(goto-char indent-point)
15864+
(c-forward-syntactic-ws (c-point 'eol))
15865+
(c-looking-at-special-brace-list))))
15866+
(c-add-syntax 'brace-entry-open (point)))
15867+
((eq (c-point 'eol) (1- indent-point))
1581315868
(c-add-stmt-syntax (if enum-pos 'enum-entry 'brace-list-entry)
1581415869
nil t containing-sexp
15815-
paren-state (point))))))))
15870+
paren-state (point)))
15871+
(t (c-add-syntax (if enum-pos 'enum-entry 'brace-list-entry)
15872+
(point)))))))))
1581615873

1581715874
;; CASE 10: A continued statement or top level construct.
1581815875
((and (not (memq char-before-ip '(?\; ?:)))

lisp/progmodes/cc-mode.el

+15-1
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,15 @@ Note that the style variables are always made local to the buffer."
10081008
'(put-text-property remove-text-properties
10091009
remove-list-of-text-properties)))
10101010

1011+
(defun c-locate-first-punctuation-prop (beg)
1012+
;; Scan the region (BEG (point)) for `syntax-table' punctuation text properties,
1013+
;; returning the position of the first found, or nil. Point is unchanged.
1014+
(let ((end (point)))
1015+
(goto-char beg)
1016+
(prog1 (if (c-search-forward-char-property 'syntax-table '(1) end)
1017+
(match-beginning 0))
1018+
(goto-char end))))
1019+
10111020
(defun c-depropertize-CPP (beg end)
10121021
;; Remove the punctuation syntax-table text property from the CPP parts of
10131022
;; (c-new-BEG c-new-END), and remove all syntax-table properties from any
@@ -1032,7 +1041,10 @@ Note that the style variables are always made local to the buffer."
10321041
(search-forward-regexp c-anchored-cpp-prefix end 'bound)))
10331042
(goto-char (match-beginning 1))
10341043
(setq m-beg (point))
1035-
(c-end-of-macro))
1044+
(c-end-of-macro)
1045+
(c-truncate-lit-pos/state-cache
1046+
(or (c-locate-first-punctuation-prop m-beg) (point-max))))
1047+
10361048
(when (and ss-found (> (point) end))
10371049
(when c-ml-string-opener-re
10381050
(save-excursion (c-depropertize-ml-strings-in-region m-beg (point))))
@@ -1044,6 +1056,8 @@ Note that the style variables are always made local to the buffer."
10441056
(goto-char (match-beginning 1))
10451057
(setq m-beg (point))
10461058
(c-end-of-macro)
1059+
(c-truncate-lit-pos/state-cache
1060+
(or (c-locate-first-punctuation-prop m-beg) (point-max)))
10471061
(when c-ml-string-opener-re
10481062
(save-excursion (c-depropertize-ml-strings-in-region m-beg (point))))
10491063
(c-clear-syntax-table-with-value-trim-caches m-beg (point) '(1)))))

0 commit comments

Comments
 (0)