Copyright up-date.
[bpt/emacs.git] / lisp / progmodes / cc-align.el
CommitLineData
785eecbb
RS
1;;; cc-align.el --- custom indentation functions for CC Mode
2
c4052e82 3;; Copyright (C) 1985,1987,1992-2000 Free Software Foundation, Inc.
785eecbb 4
c4052e82
GM
5;; Authors: 2000- Martin Stjernholm
6;; 1998-1999 Barry A. Warsaw and Martin Stjernholm
0ec8351b 7;; 1992-1997 Barry A. Warsaw
785eecbb
RS
8;; 1987 Dave Detlefs and Stewart Clamen
9;; 1985 Richard M. Stallman
0ec8351b 10;; Maintainer: bug-cc-mode@gnu.org
785eecbb 11;; Created: 22-Apr-1997 (split from cc-mode.el)
81eb2ff9 12;; Version: See cc-mode.el
785eecbb
RS
13;; Keywords: c languages oop
14
15;; This file is part of GNU Emacs.
16
17;; GNU Emacs is free software; you can redistribute it and/or modify
18;; it under the terms of the GNU General Public License as published by
19;; the Free Software Foundation; either version 2, or (at your option)
20;; any later version.
21
22;; GNU Emacs is distributed in the hope that it will be useful,
23;; but WITHOUT ANY WARRANTY; without even the implied warranty of
24;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25;; GNU General Public License for more details.
26
27;; You should have received a copy of the GNU General Public License
28;; along with GNU Emacs; see the file COPYING. If not, write to the
29;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
30;; Boston, MA 02111-1307, USA.
31
32(eval-when-compile
51f606de
GM
33 (let ((load-path
34 (if (and (boundp 'byte-compile-current-file)
35 (stringp byte-compile-current-file))
36 (cons (file-name-directory byte-compile-current-file)
37 load-path)
38 load-path)))
39 (load "cc-defs" nil t)))
40(require 'cc-engine)
785eecbb
RS
41
42\f
43;; Standard indentation line-ups
51f606de 44
785eecbb 45(defun c-lineup-arglist (langelem)
51f606de
GM
46 "Line up the current argument line under the first argument.
47
48Works with: arglist-cont-nonempty."
785eecbb
RS
49 (save-excursion
50 (let* ((containing-sexp
51 (save-excursion
52 ;; arglist-cont-nonempty gives relpos ==
53 ;; to boi of containing-sexp paren. This
54 ;; is good when offset is +, but bad
55 ;; when it is c-lineup-arglist, so we
56 ;; have to special case a kludge here.
57 (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
58 (progn
59 (beginning-of-line)
60 (backward-up-list 1)
61 (skip-chars-forward " \t" (c-point 'eol)))
62 (goto-char (cdr langelem)))
63 (point)))
64 (langelem-col (c-langelem-col langelem t)))
65 (if (save-excursion
66 (beginning-of-line)
67 (looking-at "[ \t]*)"))
68 (progn (goto-char (match-end 0))
0ec8351b 69 (c-forward-sexp -1)
785eecbb
RS
70 (forward-char 1)
71 (c-forward-syntactic-ws)
72 (- (current-column) langelem-col))
73 (goto-char containing-sexp)
74 (or (eolp)
51f606de 75 (not (memq (char-after) '(?{ ?\( ?\[)))
785eecbb
RS
76 (let ((eol (c-point 'eol))
77 (here (progn
78 (forward-char 1)
79 (skip-chars-forward " \t")
80 (point))))
81 (c-forward-syntactic-ws)
82 (if (< (point) eol)
83 (goto-char here))))
84 (- (current-column) langelem-col)
85 ))))
86
87(defun c-lineup-arglist-intro-after-paren (langelem)
51f606de
GM
88 "Line up a line just after the open paren of the surrounding paren or
89brace block.
90
91Works with: defun-block-intro, brace-list-intro,
92statement-block-intro, statement-case-intro, arglist-intro."
785eecbb
RS
93 (save-excursion
94 (let ((langelem-col (c-langelem-col langelem t))
95 (ce-curcol (save-excursion
96 (beginning-of-line)
97 (backward-up-list 1)
98 (skip-chars-forward " \t" (c-point 'eol))
99 (current-column))))
100 (- ce-curcol langelem-col -1))))
101
102(defun c-lineup-arglist-close-under-paren (langelem)
51f606de
GM
103 "Line up a closing paren line under the corresponding open paren.
104
105Works with: defun-close, class-close, inline-close, block-close,
106brace-list-close, arglist-close, extern-lang-close, namespace-close
107\(for most of these, a zero offset will normally produce the same
108result, though)."
785eecbb
RS
109 (save-excursion
110 (let ((langelem-col (c-langelem-col langelem t))
111 (ce-curcol (save-excursion
112 (beginning-of-line)
113 (backward-up-list 1)
114 (current-column))))
115 (- ce-curcol langelem-col))))
116
eae86618 117(defun c-lineup-close-paren (langelem)
51f606de
GM
118 "Line up the closing paren under its corresponding open paren if the
119open paren is followed by code. If the open paren ends its line, no
120indentation is added. E.g:
121
122main (int, main (
123 char ** int, char **
124 ) <-> ) <- c-lineup-close-paren
125
126Works with: defun-close, class-close, inline-close, block-close,
127brace-list-close, arglist-close, extern-lang-close, namespace-close."
eae86618
RS
128 (save-excursion
129 (condition-case nil
130 (let (opencol spec)
131 (beginning-of-line)
132 (backward-up-list 1)
0ec8351b
BW
133 (setq spec (c-looking-at-special-brace-list))
134 (if spec (goto-char (car (car spec))))
eae86618
RS
135 (setq opencol (current-column))
136 (forward-char 1)
137 (if spec (progn
138 (c-forward-syntactic-ws)
139 (forward-char 1)))
140 (c-forward-syntactic-ws (c-point 'eol))
141 (if (eolp)
142 0
143 (- opencol (c-langelem-col langelem t))))
51f606de 144 (error nil))))
eae86618 145
785eecbb 146(defun c-lineup-streamop (langelem)
51f606de
GM
147 "Line up C++ stream operators under each other.
148
149Works with: stream-op."
785eecbb
RS
150 (save-excursion
151 (let ((langelem-col (c-langelem-col langelem)))
152 (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
153 (goto-char (match-beginning 0))
154 (- (current-column) langelem-col))))
155
156(defun c-lineup-multi-inher (langelem)
c4052e82
GM
157 "Line up the classes in C++ multiple inheritance clauses and member
158initializers under each other. E.g:
51f606de 159
c4052e82
GM
160class Foo: Foo::Foo (int a, int b):
161 public Cyphr, Cyphr (a),
162 public Bar <-> Bar (b) <- c-lineup-multi-inher
163
164class Foo Foo::Foo (int a, int b)
165 : public Cyphr, : Cyphr (a),
166 public Bar <-> Bar (b) <- c-lineup-multi-inher
167
168class Foo Foo::Foo (int a, int b)
169 : public Cyphr : Cyphr (a)
170 , public Bar <-> , Bar (b) <- c-lineup-multi-inher
171
172Works with: inher-cont, member-init-cont."
785eecbb 173 (save-excursion
c4052e82
GM
174 (let* ((eol (c-point 'eol))
175 (here (point))
176 (char-after-ip (progn
177 (skip-chars-forward " \t")
178 (char-after)))
179 (langelem-col (c-langelem-col langelem)))
180
181 ;; This kludge is necessary to support both inher-cont and
182 ;; member-init-cont, since they have different anchor positions.
183 (c-backward-syntactic-ws)
184 (when (eq (char-before) ?:)
185 (backward-char)
186 (c-backward-syntactic-ws))
187
785eecbb 188 (skip-chars-forward "^:" eol)
c4052e82
GM
189 (if (eq char-after-ip ?,)
190 (skip-chars-forward " \t" eol)
191 (skip-chars-forward " \t:" eol))
785eecbb
RS
192 (if (or (eolp)
193 (looking-at c-comment-start-regexp))
194 (c-forward-syntactic-ws here))
195 (- (current-column) langelem-col)
196 )))
197
198(defun c-lineup-java-inher (langelem)
51f606de
GM
199 "Line up Java implements and extends declarations.
200If class names follows on the same line as the implements/extends
201keyword, they are lined up under each other. Otherwise, they are
202indented by adding `c-basic-offset' to the column of the keyword.
203E.g:
204
205class Foo class Foo
206 extends extends Cyphr,
207 Bar <-> Bar <- c-lineup-java-inher
208 <--> c-basic-offset
209
210Works with: inher-cont."
785eecbb
RS
211 (save-excursion
212 (let ((langelem-col (c-langelem-col langelem)))
213 (forward-word 1)
214 (if (looking-at "[ \t]*$")
51f606de 215 c-basic-offset
785eecbb
RS
216 (c-forward-syntactic-ws)
217 (- (current-column) langelem-col)))))
218
219(defun c-lineup-java-throws (langelem)
51f606de
GM
220 "Line up Java throws declarations.
221If exception names follows on the same line as the throws keyword,
222they are lined up under each other. Otherwise, they are indented by
223adding `c-basic-offset' to the column of the throws keyword. The
224throws keyword itself is also indented by `c-basic-offset' from the
225function declaration start if it doesn't hang. E.g:
226
227int foo() int foo() throws Cyphr,
228 throws <-> Bar, <- c-lineup-java-throws
229 Bar <-> Vlod <- c-lineup-java-throws
230<--><--> c-basic-offset
231
232Works with: func-decl-cont."
785eecbb 233 (save-excursion
51f606de
GM
234 (let* ((lim (1- (c-point 'bol)))
235 (throws (catch 'done
236 (goto-char (cdr langelem))
237 (while (zerop (c-forward-token-1 1 t lim))
238 (if (looking-at "throws\\>[^_]")
239 (throw 'done t))))))
240 (if throws
241 (if (zerop (c-forward-token-1 1 nil (c-point 'eol)))
242 (- (current-column) (c-langelem-col langelem))
243 (back-to-indentation)
244 (+ (- (current-column) (c-langelem-col langelem))
245 c-basic-offset))
246 c-basic-offset))))
785eecbb 247
eae86618 248(defun c-indent-one-line-block (langelem)
51f606de
GM
249 "Indent a one line block `c-basic-offset' extra.
250E.g:
251
252if (n > 0) if (n > 0)
253 {m+=n; n=0;} <-> { <- c-indent-one-line-block
254<--> c-basic-offset m+=n; n=0;
255 }
256
257The block may be surrounded by any kind of parenthesis characters.
258nil is returned if the line doesn't start with a one line block, which
259makes the function usable in list expressions.
260
261Work with: Almost all syntactic symbols, but most useful on *-open."
eae86618 262 (save-excursion
51f606de
GM
263 (let ((eol (c-point 'eol)))
264 (back-to-indentation)
265 (if (and (eq (char-syntax (char-after)) ?\()
0ec8351b 266 (c-safe (progn (c-forward-sexp) t))
51f606de 267 (<= (point) eol))
eae86618 268 c-basic-offset
51f606de 269 nil))))
eae86618 270
51f606de
GM
271(defun c-indent-multi-line-block (langelem)
272 "Indent a multi line block `c-basic-offset' extra.
273E.g:
274
275int *foo[] = { int *foo[] = {
276 NULL, NULL,
277 {17}, <-> { <- c-indent-multi-line-block
278 17
279 }
280 <--> c-basic-offset
281
282The block may be surrounded by any kind of parenthesis characters.
283nil is returned if the line doesn't start with a multi line block,
284which makes the function usable in list expressions.
285
286Work with: Almost all syntactic symbols, but most useful on *-open."
785eecbb 287 (save-excursion
51f606de 288 (let ((eol (c-point 'eol)))
785eecbb 289 (back-to-indentation)
51f606de
GM
290 (if (and (eq (char-syntax (char-after)) ?\()
291 (or (not (c-safe (progn (c-forward-sexp) t)))
292 (> (point) eol)))
293 c-basic-offset
294 nil))))
295
296(defun c-lineup-C-comments (langelem)
297 "Line up C block comment continuation lines.
298Various heuristics are used to handle most of the common comment
299styles. Some examples:
300
301/* /** /* /* text /* /**
302 * text * text text text ** text ** text
303 */ */ */ */ */ */
304
305/*********************************************************************
306 * text
307 ********************************************************************/
308
309/*********************************************************************
310 Free form text comments:
311 In comments with a long delimiter line at the start, the indentation
312 is kept unchanged for lines that start with an empty comment line
313 prefix. The delimiter line is whatever matches the
314 `comment-start-skip' regexp.
315*********************************************************************/
316
317The variable `c-comment-prefix-regexp' is used to recognize the
318comment line prefix, e.g. the `*' that usually starts every line
319inside a comment.
320
321Works with: The `c' syntactic symbol."
322 (save-excursion
323 (let* ((here (point))
324 (prefixlen (progn (back-to-indentation)
325 (if (looking-at c-comment-prefix-regexp)
326 (- (match-end 0) (point))
327 0)))
328 (starterlen (save-excursion
329 (goto-char (cdr langelem))
330 (looking-at comment-start-skip)
331 (- (save-excursion
332 (goto-char (match-end 0))
333 (skip-chars-backward " \t")
334 (point))
335 (or (match-end 1) (point))
336 1))) ; Don't count the first '/'.
337 (langelem-col (save-excursion (c-langelem-col langelem))))
338 (if (and (> starterlen 10) (zerop prefixlen))
339 ;; The comment has a long starter and the line doesn't have
340 ;; a nonempty comment prefix. Treat it as free form text
341 ;; and don't change the indentation.
342 (- (current-column) langelem-col)
343 (forward-line -1)
344 (back-to-indentation)
345 (if (>= (cdr langelem) (point))
346 ;; On the second line in the comment.
347 (if (zerop prefixlen)
348 ;; No nonempty comment prefix. Align after comment
349 ;; starter.
785eecbb 350 (progn
51f606de
GM
351 (goto-char (match-end 0))
352 (if (looking-at "\\([ \t]+\\).+$")
353 ;; Align with the text that hangs after the
354 ;; comment starter.
355 (goto-char (match-end 1)))
356 (- (current-column) langelem-col))
357 ;; How long is the comment starter? if greater than the
358 ;; length of the comment prefix, align left. if less
359 ;; than or equal, align right. this should also pick up
360 ;; Javadoc style comments.
361 (if (> starterlen prefixlen)
362 (progn
785eecbb 363 (goto-char (cdr langelem))
51f606de
GM
364 (- (current-column) -1 langelem-col))
365 (goto-char (match-end 0))
366 (skip-chars-backward " \t")
367 (- (current-column) prefixlen langelem-col)))
368 ;; Not on the second line in the comment. If the previous
369 ;; line has a nonempty comment prefix, align with it.
370 ;; Otherwise, align with the previous nonempty line, but
371 ;; align the comment ender with the starter.
372 (when (or (not (looking-at c-comment-prefix-regexp))
373 (eq (match-beginning 0) (match-end 0)))
374 (goto-char here)
375 (back-to-indentation)
376 (if (looking-at (concat "\\(" c-comment-prefix-regexp "\\)\\*/"))
377 (goto-char (cdr langelem))
378 (while (and (zerop (forward-line -1))
379 (looking-at "^[ \t]*$")))
380 (back-to-indentation)
381 (if (< (point) (cdr langelem))
382 ;; Align with the comment starter rather than
383 ;; with the code before it.
384 (goto-char (cdr langelem)))))
385 (- (current-column) langelem-col))))))
785eecbb
RS
386
387(defun c-lineup-comment (langelem)
51f606de
GM
388 "Line up a comment start according to `c-comment-only-line-offset'.
389If the comment is lined up with a comment starter on the previous
390line, that alignment is preserved.
391
392Works with: comment-intro."
785eecbb
RS
393 (save-excursion
394 (back-to-indentation)
395 ;; this highly kludgiforous flag prevents the mapcar over
396 ;; c-syntactic-context from entering an infinite loop
51f606de
GM
397 (let ((recurse-prevention-flag (boundp 'recurse-prevention-flag))
398 (col (current-column)))
785eecbb 399 (cond
785eecbb 400 (recurse-prevention-flag 0)
51f606de
GM
401 ;; CASE 1: preserve aligned comments
402 ((save-excursion
403 (and (c-forward-comment -1)
404 (= col (current-column))))
785eecbb 405 ;; we have to subtract out all other indentation
51f606de
GM
406 (- col (apply '+ (mapcar 'c-get-offset
407 c-syntactic-context))))
785eecbb
RS
408 ;; indent as specified by c-comment-only-line-offset
409 ((not (bolp))
410 (or (car-safe c-comment-only-line-offset)
411 c-comment-only-line-offset))
412 (t
413 (or (cdr-safe c-comment-only-line-offset)
414 (car-safe c-comment-only-line-offset)
415 -1000)) ;jam it against the left side
416 ))))
417
418(defun c-lineup-runin-statements (langelem)
51f606de
GM
419 "Line up statements when the first statement is on the same line as
420the block opening brace. E.g:
421
422int main()
423{ puts (\"Hello world!\");
424 return 0; <- c-lineup-runin-statements
425}
426
427If there is no statement after the opening brace to align with, nil is
428returned. This makes the function usable in list expressions.
429
430Works with: The `statement' syntactic symbol."
785eecbb
RS
431 (if (eq (char-after (cdr langelem)) ?{)
432 (save-excursion
433 (let ((langelem-col (c-langelem-col langelem)))
434 (forward-char 1)
435 (skip-chars-forward " \t")
51f606de
GM
436 (unless (eolp)
437 (- (current-column) langelem-col))))))
785eecbb
RS
438
439(defun c-lineup-math (langelem)
51f606de
GM
440 "Line up the current line after the equal sign on the first line in
441the statement. If there isn't any, indent with `c-basic-offset'. If
442the current line contains an equal sign too, try to align it with the
443first one.
444
445Works with: statement-cont."
785eecbb
RS
446 (save-excursion
447 (let ((equalp (save-excursion
448 (goto-char (c-point 'boi))
449 (skip-chars-forward "^=" (c-point 'eol))
450 (and (eq (char-after) ?=)
451 (- (point) (c-point 'boi)))))
452 (langelem-col (c-langelem-col langelem))
453 donep)
454 (while (and (not donep)
455 (< (point) (c-point 'eol)))
456 (skip-chars-forward "^=" (c-point 'eol))
457 (if (c-in-literal (cdr langelem))
458 (forward-char 1)
459 (setq donep t)))
0ec8351b
BW
460 (if (or (not (eq (char-after) ?=))
461 (save-excursion
462 (forward-char 1)
463 (c-forward-syntactic-ws (c-point 'eol))
464 (eolp)))
785eecbb
RS
465 ;; there's no equal sign on the line
466 c-basic-offset
467 ;; calculate indentation column after equals and ws, unless
468 ;; our line contains an equals sign
469 (if (not equalp)
470 (progn
471 (forward-char 1)
472 (skip-chars-forward " \t")
473 (setq equalp 0)))
474 (- (current-column) equalp langelem-col))
475 )))
476
51f606de
GM
477(defun c-lineup-template-args (langelem)
478 "Line up template argument lines under the first argument.
479To allow this function to be used in a list expression, nil is
480returned if there's no template argument on the first line.
481
482Works with: template-args-cont."
483 (save-excursion
484 (c-with-syntax-table c++-template-syntax-table
485 (beginning-of-line)
486 (backward-up-list 1)
487 (if (and (eq (char-after) ?<)
488 (zerop (c-forward-token-1 1 nil (c-point 'eol))))
489 (- (current-column) (c-langelem-col langelem))))))
490
785eecbb 491(defun c-lineup-ObjC-method-call (langelem)
51f606de
GM
492 "Line up selector args as elisp-mode does with function args:
493Go to the position right after the message receiver, and if you are at
494the end of the line, indent the current line c-basic-offset columns
495from the opening bracket; otherwise you are looking at the first
496character of the first method call argument, so lineup the current
497line with it.
498
499Works with: objc-method-call-cont."
785eecbb
RS
500 (save-excursion
501 (let* ((extra (save-excursion
502 (back-to-indentation)
503 (c-backward-syntactic-ws (cdr langelem))
504 (if (eq (char-before) ?:)
505 (- c-basic-offset)
506 0)))
507 (open-bracket-pos (cdr langelem))
508 (open-bracket-col (progn
509 (goto-char open-bracket-pos)
510 (current-column)))
511 (target-col (progn
512 (forward-char)
0ec8351b 513 (c-forward-sexp)
785eecbb
RS
514 (skip-chars-forward " \t")
515 (if (eolp)
516 (+ open-bracket-col c-basic-offset)
517 (current-column))))
518 )
519 (- target-col open-bracket-col extra))))
520
521(defun c-lineup-ObjC-method-args (langelem)
51f606de
GM
522 "Line up the colons that separate args.
523The colon on the current line is aligned with the one on the first
524line.
525
526Works with: objc-method-args-cont."
785eecbb
RS
527 (save-excursion
528 (let* ((here (c-point 'boi))
529 (curcol (progn (goto-char here) (current-column)))
530 (eol (c-point 'eol))
531 (relpos (cdr langelem))
532 (first-col-column (progn
533 (goto-char relpos)
534 (skip-chars-forward "^:" eol)
535 (and (eq (char-after) ?:)
536 (current-column)))))
537 (if (not first-col-column)
538 c-basic-offset
539 (goto-char here)
540 (skip-chars-forward "^:" eol)
541 (if (eq (char-after) ?:)
542 (+ curcol (- first-col-column (current-column)))
543 c-basic-offset)))))
544
545(defun c-lineup-ObjC-method-args-2 (langelem)
51f606de
GM
546 "Line up the colons that separate args.
547The colon on the current line is aligned with the one on the previous
548line.
549
550Works with: objc-method-args-cont."
785eecbb
RS
551 (save-excursion
552 (let* ((here (c-point 'boi))
553 (curcol (progn (goto-char here) (current-column)))
554 (eol (c-point 'eol))
555 (relpos (cdr langelem))
556 (prev-col-column (progn
557 (skip-chars-backward "^:" relpos)
558 (and (eq (char-before) ?:)
559 (- (current-column) 1)))))
560 (if (not prev-col-column)
561 c-basic-offset
562 (goto-char here)
563 (skip-chars-forward "^:" eol)
564 (if (eq (char-after) ?:)
565 (+ curcol (- prev-col-column (current-column)))
566 c-basic-offset)))))
567
0ec8351b 568(defun c-lineup-inexpr-block (langelem)
51f606de
GM
569 "Line up the block for constructs that use a block inside an expression,
570e.g. anonymous classes in Java and lambda functions in Pike. The body
571is aligned with the start of the header, e.g. with the \"new\" or
572\"lambda\" keyword. Returns nil if the block isn't part of such a
573construct.
574
575Works with: inlambda, inexpr-statement, inexpr-class."
0ec8351b
BW
576 (save-excursion
577 (back-to-indentation)
578 (let ((res (or (c-looking-at-inexpr-block)
579 (if (c-safe (backward-up-list 1)
580 (eq (char-after) ?{))
581 (c-looking-at-inexpr-block)))))
51f606de 582 (when res
0ec8351b
BW
583 (goto-char (cdr res))
584 (- (current-column)
585 (progn
586 (back-to-indentation)
587 (current-column)))))))
588
51f606de
GM
589(defun c-lineup-whitesmith-in-block (langelem)
590 "Line up lines inside a block in whitesmith style.
591It's done in a way that works both when the opening brace hangs and
592when it doesn't. E.g:
593
594something
595 { something {
596 foo; <-> foo; <- c-lineup-whitesmith-in-block
597 } }
598 <--> c-basic-offset
599
600In the first case the indentation is kept unchanged, in the
601second `c-basic-offset' is added.
602
603Works with: defun-close, defun-block-intro, block-close,
604brace-list-close, brace-list-intro, statement-block-intro, inclass,
605inextern-lang, innamespace."
eae86618 606 (save-excursion
51f606de 607 (goto-char (cdr langelem))
eae86618 608 (back-to-indentation)
51f606de
GM
609 (if (eq (char-syntax (char-after)) ?\()
610 0
611 c-basic-offset)))
eae86618 612
51f606de
GM
613(defun c-lineup-dont-change (langelem)
614 "Do not change the indentation of the current line.
615
616Works with: Any syntactic symbol."
617 (save-excursion
618 (back-to-indentation)
619 (- (current-column) (c-langelem-col langelem))))
eae86618
RS
620
621\f
785eecbb
RS
622(defun c-snug-do-while (syntax pos)
623 "Dynamically calculate brace hanginess for do-while statements.
624Using this function, `while' clauses that end a `do-while' block will
625remain on the same line as the brace that closes that block.
626
627See `c-hanging-braces-alist' for how to utilize this function as an
628ACTION associated with `block-close' syntax."
629 (save-excursion
630 (let (langelem)
631 (if (and (eq syntax 'block-close)
632 (setq langelem (assq 'block-close c-syntactic-context))
633 (progn (goto-char (cdr langelem))
634 (if (eq (char-after) ?{)
0ec8351b 635 (c-safe (c-forward-sexp -1)))
785eecbb
RS
636 (looking-at "\\<do\\>[^_]")))
637 '(before)
638 '(before after)))))
639
640(defun c-gnu-impose-minimum ()
641 "Imposes a minimum indentation for lines inside a top-level construct.
642The variable `c-label-minimum-indentation' specifies the minimum
643indentation amount."
644 (let ((non-top-levels '(defun-block-intro statement statement-cont
645 statement-block-intro statement-case-intro
646 statement-case-open substatement substatement-open
647 case-label label do-while-closure else-clause
648 ))
649 (syntax c-syntactic-context)
650 langelem)
651 (while syntax
652 (setq langelem (car (car syntax))
653 syntax (cdr syntax))
c4052e82
GM
654 ;; don't adjust macro or comment-only lines
655 (cond ((memq langelem '(cpp-macro comment-intro))
785eecbb
RS
656 (setq syntax nil))
657 ((memq langelem non-top-levels)
658 (save-excursion
659 (setq syntax nil)
660 (back-to-indentation)
661 (if (zerop (current-column))
662 (insert (make-string c-label-minimum-indentation 32)))
663 ))
664 ))))
665
666\f
667;; Useful for c-hanging-semi&comma-criteria
51f606de 668
785eecbb 669(defun c-semi&comma-inside-parenlist ()
eae86618 670 "Controls newline insertion after semicolons in parenthesis lists.
785eecbb
RS
671If a comma was inserted, no determination is made. If a semicolon was
672inserted inside a parenthesis list, no newline is added otherwise a
673newline is added. In either case, checking is stopped. This supports
674exactly the old newline insertion behavior."
675 ;; newline only after semicolon, but only if that semicolon is not
676 ;; inside a parenthesis list (e.g. a for loop statement)
677 (if (not (eq last-command-char ?\;))
678 nil ; continue checking
679 (if (condition-case nil
680 (save-excursion
681 (up-list -1)
682 (not (eq (char-after) ?\()))
683 (error t))
684 t
685 'stop)))
686
eae86618
RS
687;; Suppresses newlines before non-blank lines
688(defun c-semi&comma-no-newlines-before-nonblanks ()
689 "Controls newline insertion after semicolons.
690If a comma was inserted, no determination is made. If a semicolon was
691inserted, and the following line is not blank, no newline is inserted.
692Otherwise, no determination is made."
693 (save-excursion
694 (if (and (= last-command-char ?\;)
695 ;;(/= (point-max)
696 ;; (save-excursion (skip-syntax-forward " ") (point))
697 (zerop (forward-line 1))
698 (not (looking-at "^[ \t]*$")))
699 'stop
700 nil)))
701
702;; Suppresses new lines after semicolons in one-liners methods
703(defun c-semi&comma-no-newlines-for-oneline-inliners ()
704 "Controls newline insertion after semicolons for some one-line methods.
705If a comma was inserted, no determination is made. Newlines are
706suppressed in one-liners, if the line is an in-class inline function.
707For other semicolon contexts, no determination is made."
708 (let ((syntax (c-guess-basic-syntax))
709 (bol (save-excursion
710 (if (c-safe (up-list -1) t)
711 (c-point 'bol)
712 -1))))
713 (if (and (eq last-command-char ?\;)
714 (eq (car (car syntax)) 'inclass)
715 (eq (car (car (cdr syntax))) 'topmost-intro)
716 (= (c-point 'bol) bol))
717 'stop
718 nil)))
719
785eecbb
RS
720\f
721(provide 'cc-align)
722;;; cc-align.el ends here