Add arch taglines
[bpt/emacs.git] / lisp / progmodes / cc-align.el
CommitLineData
785eecbb
RS
1;;; cc-align.el --- custom indentation functions for CC Mode
2
d9e94c22 3;; Copyright (C) 1985,1987,1992-2003 Free Software Foundation, Inc.
785eecbb 4
d9e94c22
MS
5;; Authors: 1998- Martin Stjernholm
6;; 1992-1999 Barry A. Warsaw
785eecbb
RS
7;; 1987 Dave Detlefs and Stewart Clamen
8;; 1985 Richard M. Stallman
0ec8351b 9;; Maintainer: bug-cc-mode@gnu.org
785eecbb 10;; Created: 22-Apr-1997 (split from cc-mode.el)
81eb2ff9 11;; Version: See cc-mode.el
785eecbb
RS
12;; Keywords: c languages oop
13
14;; This file is part of GNU Emacs.
15
16;; GNU Emacs is free software; you can redistribute it and/or modify
17;; it under the terms of the GNU General Public License as published by
18;; the Free Software Foundation; either version 2, or (at your option)
19;; any later version.
20
21;; GNU Emacs is distributed in the hope that it will be useful,
22;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24;; GNU General Public License for more details.
25
26;; You should have received a copy of the GNU General Public License
a66cd3ee 27;; along with GNU Emacs; see the file COPYING. If not, write to
130c507e 28;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
785eecbb
RS
29;; Boston, MA 02111-1307, USA.
30
3afbc435
PJ
31;;; Commentary:
32
33;;; Code:
34
785eecbb 35(eval-when-compile
51f606de 36 (let ((load-path
130c507e
GM
37 (if (and (boundp 'byte-compile-dest-file)
38 (stringp byte-compile-dest-file))
39 (cons (file-name-directory byte-compile-dest-file) load-path)
51f606de 40 load-path)))
d9e94c22 41 (load "cc-bytecomp" nil t)))
130c507e
GM
42
43(cc-require 'cc-defs)
44(cc-require 'cc-vars)
130c507e 45(cc-require 'cc-engine)
785eecbb
RS
46
47\f
48;; Standard indentation line-ups
51f606de 49
d9e94c22
MS
50;; Calling convention:
51;;
52;; The single argument is a cons cell containing the syntactic symbol
53;; in the car, and the relpos (a.k.a. anchor position) in the cdr.
54;; The cdr may be nil for syntactic symbols which doesn't have an
55;; associated relpos.
56;;
57;; Some syntactic symbols provide more information, usually more
58;; interesting positions. The complete list for the syntactic element
59;; (beginning with the symbol itself) is available in
60;; `c-syntactic-element'.
61
a66cd3ee
MS
62(defun c-lineup-topmost-intro-cont (langelem)
63 "Line up declaration continuation lines zero or one indentation step.
64For lines in the \"header\" of a definition, zero is used. For other
65lines, `c-basic-offset' is added to the indentation. E.g:
66
67int
68neg (int i) <- c-lineup-topmost-intro-cont
69{
70 return -i;
71}
72
73struct
74larch <- c-lineup-topmost-intro-cont
75{
76 double height;
77}
78 the_larch, <- c-lineup-topmost-intro-cont
79 another_larch; <- c-lineup-topmost-intro-cont
80<--> c-basic-offset
81
82struct larch
83the_larch, <- c-lineup-topmost-intro-cont
84 another_larch; <- c-lineup-topmost-intro-cont
85
86\(This function is mainly provided to mimic the behavior of CC Mode
875.28 and earlier where this case wasn't handled consistently so that
88these lines could be analyzed as either topmost-intro-cont or
89statement-cont.)
90
91Works with: topmost-intro-cont."
92 (save-excursion
93 (beginning-of-line)
94 (c-backward-syntactic-ws (cdr langelem))
95 (if (memq (char-before) '(?} ?,))
96 c-basic-offset)))
97
785eecbb 98(defun c-lineup-arglist (langelem)
51f606de
GM
99 "Line up the current argument line under the first argument.
100
d9e94c22
MS
101As a special case, if an argument on the same line as the open
102parenthesis starts with a brace block opener, the indentation is
103`c-basic-offset' only. This is intended as a \"DWIM\" measure in
104cases like macros that contains statement blocks, e.g:
105
106A_VERY_LONG_MACRO_NAME ({
107 some (code, with + long, lines * in[it]);
108 });
109<--> c-basic-offset
110
111This is motivated partly because it's more in line with how code
112blocks are handled, and partly since it approximates the behavior of
113earlier CC Mode versions, which due to inaccurate analysis tended to
114indent such cases this way.
115
a66cd3ee 116Works with: arglist-cont-nonempty, arglist-close."
785eecbb 117 (save-excursion
d9e94c22
MS
118 (goto-char (1+ (elt c-syntactic-element 2)))
119
120 ;; Don't stop in the middle of a special brace list opener
121 ;; like "({".
122 (when c-special-brace-lists
123 (let ((special-list (c-looking-at-special-brace-list)))
124 (when special-list
125 (goto-char (+ (car (car special-list)) 2)))))
126
127 (let ((savepos (point))
128 (eol (c-point 'eol)))
129
130 ;; Find out if an argument on the same line starts with an
131 ;; unclosed open brace paren. Note similar code in
132 ;; `c-lineup-close-paren' and
133 ;; `c-lineup-arglist-close-under-paren'.
134 (if (and (c-syntactic-re-search-forward "{" eol t t)
135 (looking-at c-syntactic-eol)
136 (progn (backward-char)
137 (not (c-looking-at-special-brace-list)))
138 (progn (c-backward-syntactic-ws)
139 (or (= (point) savepos)
140 (eq (char-before) ?,))))
141 c-basic-offset
142
143 ;; Normal case. Indent to the token after the arglist open paren.
144 (goto-char savepos)
a66cd3ee
MS
145 (c-forward-syntactic-ws)
146 (when (< (point) eol)
d9e94c22
MS
147 (goto-char savepos)
148 (skip-chars-forward " \t"))
149 (vector (current-column))))))
a66cd3ee
MS
150
151;; Contributed by Kevin Ryde <user42@zip.com.au>.
152(defun c-lineup-argcont (elem)
153 "Line up a continued argument.
154
155foo (xyz, aaa + bbb + ccc
156 + ddd + eee + fff); <- c-lineup-argcont
157
8df87102 158Only continuation lines like this are touched, nil is returned on lines
a66cd3ee
MS
159which are the start of an argument.
160
161Within a gcc asm block, \":\" is recognised as an argument separator,
162but of course only between operand specifications, not in the expressions
163for the operands.
164
165Works with: arglist-cont, arglist-cont-nonempty."
166
167 (save-excursion
168 (beginning-of-line)
a66cd3ee 169
d9e94c22
MS
170 (when (eq (car elem) 'arglist-cont-nonempty)
171 ;; Our argument list might not be the innermost one. If it
172 ;; isn't, go back to the last position in it. We do this by
173 ;; stepping back over open parens until we get to the open paren
174 ;; of our argument list.
175 (let ((open-paren (elt c-syntactic-element 2))
176 (paren-state (c-parse-state)))
177 (while (not (eq (car paren-state) open-paren))
178 (goto-char (car paren-state))
179 (setq paren-state (cdr paren-state)))))
180
181 (let ((start (point)) c)
182
183 (when (bolp)
184 ;; Previous line ending in a comma means we're the start of an
185 ;; argument. This should quickly catch most cases not for us.
186 ;; This case is only applicable if we're the innermost arglist.
187 (c-backward-syntactic-ws)
188 (setq c (char-before)))
189
190 (unless (eq c ?,)
191 ;; In a gcc asm, ":" on the previous line means the start of an
192 ;; argument. And lines starting with ":" are not for us, don't
193 ;; want them to indent to the preceding operand.
194 (let ((gcc-asm (save-excursion
195 (goto-char start)
196 (c-in-gcc-asm-p))))
197 (unless (and gcc-asm
198 (or (eq c ?:)
199 (save-excursion
200 (goto-char start)
201 (looking-at "[ \t]*:"))))
202
203 (c-lineup-argcont-scan (if gcc-asm ?:))
204 (vector (current-column))))))))
a66cd3ee
MS
205
206(defun c-lineup-argcont-scan (&optional other-match)
207 ;; Find the start of an argument, for `c-lineup-argcont'.
d9e94c22 208 (when (zerop (c-backward-token-2 1 t))
a66cd3ee
MS
209 (let ((c (char-after)))
210 (if (or (eq c ?,) (eq c other-match))
211 (progn
212 (forward-char)
213 (c-forward-syntactic-ws))
214 (c-lineup-argcont-scan other-match)))))
785eecbb
RS
215
216(defun c-lineup-arglist-intro-after-paren (langelem)
d9e94c22
MS
217 "Line up a line to just after the open paren of the surrounding paren
218or brace block.
51f606de
GM
219
220Works with: defun-block-intro, brace-list-intro,
221statement-block-intro, statement-case-intro, arglist-intro."
785eecbb 222 (save-excursion
a66cd3ee
MS
223 (beginning-of-line)
224 (backward-up-list 1)
225 (skip-chars-forward " \t" (c-point 'eol))
226 (vector (1+ (current-column)))))
785eecbb
RS
227
228(defun c-lineup-arglist-close-under-paren (langelem)
d9e94c22
MS
229 "Line up a line under the enclosing open paren.
230Normally used to line up a closing paren in the same column as its
231corresponding open paren, but can also be used with arglist-cont and
232arglist-cont-nonempty to line up all lines inside a parenthesis under
233the open paren.
234
235As a special case, if a brace block is opened at the same line as the
236open parenthesis of the argument list, the indentation is
237`c-basic-offset' only. See `c-lineup-arglist' for further discussion
238of this \"DWIM\" measure.
239
240Works with: Almost all symbols, but are typically most useful on
241arglist-close, brace-list-close, arglist-cont and arglist-cont-nonempty."
242 (save-excursion
243 (let (special-list paren-start savepos)
244 (if (memq (car langelem) '(arglist-cont-nonempty arglist-close))
245 (goto-char (elt c-syntactic-element 2))
246 (beginning-of-line)
247 (c-go-up-list-backward))
248
249 (if (and c-special-brace-lists
250 (setq special-list (c-looking-at-special-brace-list)))
251 ;; Don't stop in the middle of a special brace list opener
252 ;; like "({".
253 (progn
254 (setq paren-start (car (car special-list)))
255 (goto-char (+ paren-start 2)))
256 (setq paren-start (point))
257 (forward-char 1))
258
259 (setq savepos (point))
260 ;; Find out if an argument on the same line starts with an
261 ;; unclosed open brace paren. Note similar code in
262 ;; `c-lineup-arglist' and `c-lineup-close-paren'.
263 (if (and (c-syntactic-re-search-forward "{" (c-point 'eol) t t)
264 (looking-at c-syntactic-eol)
265 (progn (backward-char)
266 (not (c-looking-at-special-brace-list)))
267 (progn (c-backward-syntactic-ws)
268 (or (= (point) savepos)
269 (eq (char-before) ?,))))
270 c-basic-offset
51f606de 271
d9e94c22
MS
272 ;; Normal case. Indent to the arglist open paren.
273 (goto-char paren-start)
274 (vector (current-column))))))
275
276(defun c-lineup-arglist-operators (langelem)
277 "Line up lines starting with an infix operator under the open paren.
278Return nil on lines that don't start with an operator, to leave those
279cases to other lineup functions. Example:
280
281if ( x < 10
282 || at_limit (x, <- c-lineup-arglist-operators
283 list) <- c-lineup-arglist-operators returns nil
284 )
285
286Since this function doesn't do anything for lines without an infix
287operator you typically want to use it together with some other lineup
288settings, e.g. as follows \(the arglist-close setting is just a
289suggestion to get a consistent style):
290
291\(c-set-offset 'arglist-cont '(c-lineup-arglist-operators 0))
292\(c-set-offset 'arglist-cont-nonempty '(c-lineup-arglist-operators
293 c-lineup-arglist))
294\(c-set-offset 'arglist-close '(c-lineup-arglist-close-under-paren))
295
296Works with: arglist-cont, arglist-cont-nonempty."
785eecbb 297 (save-excursion
d9e94c22
MS
298 (back-to-indentation)
299 (when (looking-at "[-+|&*%<>=]\\|\\(/[^/*]\\)")
300 ;; '-' can be both an infix and a prefix operator, but I'm lazy now..
301 (c-lineup-arglist-close-under-paren langelem))))
785eecbb 302
eae86618 303(defun c-lineup-close-paren (langelem)
51f606de
GM
304 "Line up the closing paren under its corresponding open paren if the
305open paren is followed by code. If the open paren ends its line, no
306indentation is added. E.g:
307
308main (int, main (
309 char ** int, char **
310 ) <-> ) <- c-lineup-close-paren
311
d9e94c22
MS
312As a special case, if a brace block is opened at the same line as the
313open parenthesis of the argument list, the indentation is
314`c-basic-offset' instead of the open paren column. See
315`c-lineup-arglist' for further discussion of this \"DWIM\" measure.
316
317Works with: All *-close symbols."
eae86618 318 (save-excursion
d9e94c22
MS
319 (beginning-of-line)
320 (c-go-up-list-backward)
321
322 (let ((spec (c-looking-at-special-brace-list)) savepos argstart)
323 (if spec (goto-char (car (car spec))))
324 (setq savepos (point))
325 (forward-char 1)
326 (when spec
327 (c-forward-syntactic-ws)
328 (forward-char 1))
329
330 (if (looking-at c-syntactic-eol)
331 ;; The arglist is "empty".
332 0
333
334 ;; Find out if an argument on the same line starts with an
335 ;; unclosed open brace paren. Note similar code in
336 ;; `c-lineup-arglist' and
337 ;; `c-lineup-arglist-close-under-paren'.
338 (setq argstart (point))
339 (if (and (c-syntactic-re-search-forward "{" (c-point 'eol) t t)
340 (looking-at c-syntactic-eol)
341 (progn (backward-char)
342 (not (c-looking-at-special-brace-list)))
343 (progn (c-backward-syntactic-ws)
344 (or (= (point) argstart)
345 (eq (char-before) ?,))))
346 c-basic-offset
347
348 ;; Normal case. Indent to the arglist open paren.
349 (goto-char savepos)
350 (vector (current-column)))))))
eae86618 351
785eecbb 352(defun c-lineup-streamop (langelem)
51f606de
GM
353 "Line up C++ stream operators under each other.
354
355Works with: stream-op."
785eecbb 356 (save-excursion
a66cd3ee
MS
357 (goto-char (cdr langelem))
358 (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
359 (goto-char (match-beginning 0))
360 (vector (current-column))))
785eecbb
RS
361
362(defun c-lineup-multi-inher (langelem)
c4052e82
GM
363 "Line up the classes in C++ multiple inheritance clauses and member
364initializers under each other. E.g:
51f606de 365
c4052e82
GM
366class Foo: Foo::Foo (int a, int b):
367 public Cyphr, Cyphr (a),
368 public Bar <-> Bar (b) <- c-lineup-multi-inher
369
370class Foo Foo::Foo (int a, int b)
371 : public Cyphr, : Cyphr (a),
372 public Bar <-> Bar (b) <- c-lineup-multi-inher
373
374class Foo Foo::Foo (int a, int b)
375 : public Cyphr : Cyphr (a)
376 , public Bar <-> , Bar (b) <- c-lineup-multi-inher
377
378Works with: inher-cont, member-init-cont."
785eecbb 379 (save-excursion
d9e94c22 380 (back-to-indentation)
c4052e82
GM
381 (let* ((eol (c-point 'eol))
382 (here (point))
383 (char-after-ip (progn
384 (skip-chars-forward " \t")
a66cd3ee
MS
385 (char-after))))
386 (if (cdr langelem) (goto-char (cdr langelem)))
c4052e82
GM
387
388 ;; This kludge is necessary to support both inher-cont and
389 ;; member-init-cont, since they have different anchor positions.
390 (c-backward-syntactic-ws)
391 (when (eq (char-before) ?:)
392 (backward-char)
393 (c-backward-syntactic-ws))
394
785eecbb 395 (skip-chars-forward "^:" eol)
c4052e82
GM
396 (if (eq char-after-ip ?,)
397 (skip-chars-forward " \t" eol)
398 (skip-chars-forward " \t:" eol))
785eecbb
RS
399 (if (or (eolp)
400 (looking-at c-comment-start-regexp))
401 (c-forward-syntactic-ws here))
d9e94c22
MS
402 (if (< (point) here)
403 (vector (current-column)))
785eecbb
RS
404 )))
405
406(defun c-lineup-java-inher (langelem)
51f606de 407 "Line up Java implements and extends declarations.
d9e94c22 408If class names follow on the same line as the implements/extends
51f606de
GM
409keyword, they are lined up under each other. Otherwise, they are
410indented by adding `c-basic-offset' to the column of the keyword.
411E.g:
412
413class Foo class Foo
414 extends extends Cyphr,
415 Bar <-> Bar <- c-lineup-java-inher
416 <--> c-basic-offset
417
418Works with: inher-cont."
785eecbb 419 (save-excursion
a66cd3ee
MS
420 (goto-char (cdr langelem))
421 (forward-word 1)
422 (if (looking-at "[ \t]*$")
423 c-basic-offset
424 (c-forward-syntactic-ws)
425 (vector (current-column)))))
785eecbb
RS
426
427(defun c-lineup-java-throws (langelem)
51f606de 428 "Line up Java throws declarations.
d9e94c22 429If exception names follow on the same line as the throws keyword,
51f606de
GM
430they are lined up under each other. Otherwise, they are indented by
431adding `c-basic-offset' to the column of the throws keyword. The
432throws keyword itself is also indented by `c-basic-offset' from the
433function declaration start if it doesn't hang. E.g:
434
435int foo() int foo() throws Cyphr,
436 throws <-> Bar, <- c-lineup-java-throws
437 Bar <-> Vlod <- c-lineup-java-throws
438<--><--> c-basic-offset
439
440Works with: func-decl-cont."
785eecbb 441 (save-excursion
51f606de
GM
442 (let* ((lim (1- (c-point 'bol)))
443 (throws (catch 'done
444 (goto-char (cdr langelem))
d9e94c22 445 (while (zerop (c-forward-token-2 1 t lim))
51f606de
GM
446 (if (looking-at "throws\\>[^_]")
447 (throw 'done t))))))
448 (if throws
d9e94c22 449 (if (zerop (c-forward-token-2 1 nil (c-point 'eol)))
a66cd3ee 450 (vector (current-column))
51f606de 451 (back-to-indentation)
a66cd3ee 452 (vector (+ (current-column) c-basic-offset)))
51f606de 453 c-basic-offset))))
785eecbb 454
eae86618 455(defun c-indent-one-line-block (langelem)
51f606de
GM
456 "Indent a one line block `c-basic-offset' extra.
457E.g:
458
459if (n > 0) if (n > 0)
460 {m+=n; n=0;} <-> { <- c-indent-one-line-block
461<--> c-basic-offset m+=n; n=0;
462 }
463
130c507e
GM
464The block may use any kind of parenthesis character. nil is returned
465if the line doesn't start with a one line block, which makes the
466function usable in list expressions.
51f606de
GM
467
468Work with: Almost all syntactic symbols, but most useful on *-open."
eae86618 469 (save-excursion
51f606de
GM
470 (let ((eol (c-point 'eol)))
471 (back-to-indentation)
472 (if (and (eq (char-syntax (char-after)) ?\()
0ec8351b 473 (c-safe (progn (c-forward-sexp) t))
51f606de 474 (<= (point) eol))
eae86618 475 c-basic-offset
51f606de 476 nil))))
eae86618 477
51f606de
GM
478(defun c-indent-multi-line-block (langelem)
479 "Indent a multi line block `c-basic-offset' extra.
480E.g:
481
482int *foo[] = { int *foo[] = {
483 NULL, NULL,
484 {17}, <-> { <- c-indent-multi-line-block
485 17
486 }
487 <--> c-basic-offset
488
130c507e
GM
489The block may use any kind of parenthesis character. nil is returned
490if the line doesn't start with a multi line block, which makes the
491function usable in list expressions.
51f606de
GM
492
493Work with: Almost all syntactic symbols, but most useful on *-open."
785eecbb 494 (save-excursion
51f606de 495 (let ((eol (c-point 'eol)))
785eecbb 496 (back-to-indentation)
51f606de
GM
497 (if (and (eq (char-syntax (char-after)) ?\()
498 (or (not (c-safe (progn (c-forward-sexp) t)))
499 (> (point) eol)))
500 c-basic-offset
501 nil))))
502
503(defun c-lineup-C-comments (langelem)
504 "Line up C block comment continuation lines.
130c507e 505Various heuristics are used to handle many of the common comment
51f606de
GM
506styles. Some examples:
507
508/* /** /* /* text /* /**
509 * text * text text text ** text ** text
510 */ */ */ */ */ */
511
512/*********************************************************************
513 * text
514 ********************************************************************/
515
516/*********************************************************************
517 Free form text comments:
518 In comments with a long delimiter line at the start, the indentation
519 is kept unchanged for lines that start with an empty comment line
520 prefix. The delimiter line is whatever matches the
521 `comment-start-skip' regexp.
522*********************************************************************/
523
524The variable `c-comment-prefix-regexp' is used to recognize the
525comment line prefix, e.g. the `*' that usually starts every line
526inside a comment.
527
528Works with: The `c' syntactic symbol."
529 (save-excursion
530 (let* ((here (point))
531 (prefixlen (progn (back-to-indentation)
130c507e 532 (if (looking-at c-current-comment-prefix)
51f606de
GM
533 (- (match-end 0) (point))
534 0)))
a66cd3ee
MS
535 (starterlen
536 ;; Get the length of the comment starter, not including
537 ;; the first '/'. We check if the comment prefix matched
538 ;; on the current line matches the starter or if it
539 ;; matches comment-start-skip, and choose whichever is
540 ;; longest.
541 (max (save-excursion
542 (goto-char (1+ (cdr langelem)))
543 (if (and (match-string 0)
544 (looking-at (regexp-quote (match-string 0))))
545 (- (match-end 0) (match-beginning 0))
546 0))
547 (save-excursion
548 (goto-char (cdr langelem))
549 (looking-at comment-start-skip)
550 (- (or (match-end 1)
551 (save-excursion
552 (goto-char (match-end 0))
553 (skip-chars-backward " \t")
554 (point)))
555 (point)
556 1)))))
51f606de
GM
557 (if (and (> starterlen 10) (zerop prefixlen))
558 ;; The comment has a long starter and the line doesn't have
559 ;; a nonempty comment prefix. Treat it as free form text
560 ;; and don't change the indentation.
a66cd3ee 561 (vector (current-column))
51f606de
GM
562 (forward-line -1)
563 (back-to-indentation)
564 (if (>= (cdr langelem) (point))
565 ;; On the second line in the comment.
566 (if (zerop prefixlen)
567 ;; No nonempty comment prefix. Align after comment
568 ;; starter.
785eecbb 569 (progn
51f606de 570 (goto-char (match-end 0))
a66cd3ee
MS
571 ;; The following should not be necessary, since
572 ;; comment-start-skip should match everything (i.e.
573 ;; typically whitespace) that leads up to the text.
574 ;;(if (looking-at "\\([ \t]+\\).+$")
575 ;; ;; Align with the text that hangs after the
576 ;; ;; comment starter.
577 ;; (goto-char (match-end 1)))
578 (vector (current-column)))
51f606de
GM
579 ;; How long is the comment starter? if greater than the
580 ;; length of the comment prefix, align left. if less
581 ;; than or equal, align right. this should also pick up
582 ;; Javadoc style comments.
583 (if (> starterlen prefixlen)
584 (progn
785eecbb 585 (goto-char (cdr langelem))
a66cd3ee
MS
586 (vector (1+ (current-column))))
587 (goto-char (+ (cdr langelem) starterlen 1))
588 (vector (- (current-column) prefixlen))))
51f606de
GM
589 ;; Not on the second line in the comment. If the previous
590 ;; line has a nonempty comment prefix, align with it.
591 ;; Otherwise, align with the previous nonempty line, but
592 ;; align the comment ender with the starter.
130c507e 593 (when (or (not (looking-at c-current-comment-prefix))
51f606de
GM
594 (eq (match-beginning 0) (match-end 0)))
595 (goto-char here)
596 (back-to-indentation)
130c507e 597 (if (looking-at (concat "\\(" c-current-comment-prefix "\\)\\*/"))
51f606de
GM
598 (goto-char (cdr langelem))
599 (while (and (zerop (forward-line -1))
600 (looking-at "^[ \t]*$")))
601 (back-to-indentation)
602 (if (< (point) (cdr langelem))
603 ;; Align with the comment starter rather than
604 ;; with the code before it.
605 (goto-char (cdr langelem)))))
a66cd3ee 606 (vector (current-column)))))))
785eecbb
RS
607
608(defun c-lineup-comment (langelem)
51f606de
GM
609 "Line up a comment start according to `c-comment-only-line-offset'.
610If the comment is lined up with a comment starter on the previous
611line, that alignment is preserved.
612
613Works with: comment-intro."
785eecbb
RS
614 (save-excursion
615 (back-to-indentation)
130c507e 616 (let ((col (current-column)))
785eecbb 617 (cond
51f606de
GM
618 ;; CASE 1: preserve aligned comments
619 ((save-excursion
d9e94c22 620 (and (c-backward-single-comment)
51f606de 621 (= col (current-column))))
130c507e 622 (vector col)) ; Return an absolute column.
785eecbb
RS
623 ;; indent as specified by c-comment-only-line-offset
624 ((not (bolp))
625 (or (car-safe c-comment-only-line-offset)
626 c-comment-only-line-offset))
627 (t
628 (or (cdr-safe c-comment-only-line-offset)
629 (car-safe c-comment-only-line-offset)
630 -1000)) ;jam it against the left side
631 ))))
632
a66cd3ee
MS
633(defun c-lineup-knr-region-comment (langelem)
634 "Line up a comment in the \"K&R region\" with the declaration.
635That is the region between the function or class header and the
636beginning of the block. E.g:
637
638int main()
639/* This is the main function. */ <- c-lineup-knr-region-comment
640{
641 return 0;
642}
643
644Return nil if called in any other situation, to be useful in list
645expressions.
646
647Works with: comment-intro."
648 (when (or (assq 'topmost-intro-cont c-syntactic-context)
649 (assq 'func-decl-cont c-syntactic-context)
650 (assq 'knr-argdecl-intro c-syntactic-context)
651 (assq 'lambda-intro-cont c-syntactic-context))
652 (save-excursion
653 (beginning-of-line)
654 (c-beginning-of-statement-1)
655 (vector (current-column)))))
656
785eecbb 657(defun c-lineup-runin-statements (langelem)
51f606de
GM
658 "Line up statements when the first statement is on the same line as
659the block opening brace. E.g:
660
661int main()
662{ puts (\"Hello world!\");
663 return 0; <- c-lineup-runin-statements
664}
665
666If there is no statement after the opening brace to align with, nil is
667returned. This makes the function usable in list expressions.
668
669Works with: The `statement' syntactic symbol."
785eecbb
RS
670 (if (eq (char-after (cdr langelem)) ?{)
671 (save-excursion
a66cd3ee
MS
672 (if (cdr langelem) (goto-char (cdr langelem)))
673 (forward-char 1)
674 (skip-chars-forward " \t")
675 (unless (eolp)
676 (vector (current-column))))))
785eecbb
RS
677
678(defun c-lineup-math (langelem)
51f606de
GM
679 "Line up the current line after the equal sign on the first line in
680the statement. If there isn't any, indent with `c-basic-offset'. If
681the current line contains an equal sign too, try to align it with the
682first one.
683
d9e94c22
MS
684Works with: topmost-intro-cont, statement-cont, arglist-cont,
685arglist-cont-nonempty."
686 (let (startpos endpos equalp)
687
688 (if (eq (car langelem) 'arglist-cont-nonempty)
689 ;; If it's an arglist-cont-nonempty then we're only interested
690 ;; in equal signs outside it. We don't search for a "=" on
691 ;; the current line since that'd have a different nesting
692 ;; compared to the one we should align with.
693 (save-excursion
694 (save-restriction
695 (setq endpos (nth 2 c-syntactic-element))
696 (narrow-to-region (cdr langelem) endpos)
697 (if (setq startpos (c-up-list-backward endpos))
698 (setq startpos (1+ startpos))
699 (setq startpos (cdr langelem)))))
700
701 (setq startpos (cdr langelem)
702 endpos (point))
703
704 ;; Find a syntactically relevant and unnested "=" token on the
705 ;; current line. equalp is in that case set to the number of
706 ;; columns to left shift the current line to align it with the
707 ;; goal column.
708 (save-excursion
709 (beginning-of-line)
710 (when (c-syntactic-re-search-forward
846f5040
MS
711 c-assignment-op-regexp
712 (c-point 'eol) t t t)
713 (setq equalp (- (or (match-beginning 1)
714 (match-end 0))
715 (c-point 'boi))))))
d9e94c22
MS
716
717 (save-excursion
718 (goto-char startpos)
719 (if (or (if (c-syntactic-re-search-forward
846f5040
MS
720 c-assignment-op-regexp
721 (min endpos (c-point 'eol)) t t t)
d9e94c22 722 (progn
846f5040
MS
723 (goto-char (or (match-beginning 1)
724 (match-end 0)))
d9e94c22
MS
725 nil)
726 t)
0ec8351b 727 (save-excursion
0ec8351b
BW
728 (c-forward-syntactic-ws (c-point 'eol))
729 (eolp)))
d9e94c22
MS
730 ;; There's no equal sign on the line, or there is one but
731 ;; nothing follows it.
785eecbb 732 c-basic-offset
d9e94c22 733
785eecbb
RS
734 ;; calculate indentation column after equals and ws, unless
735 ;; our line contains an equals sign
736 (if (not equalp)
737 (progn
785eecbb
RS
738 (skip-chars-forward " \t")
739 (setq equalp 0)))
d9e94c22 740
a66cd3ee 741 (vector (- (current-column) equalp)))
785eecbb
RS
742 )))
743
a66cd3ee
MS
744(defun c-lineup-cascaded-calls (langelem)
745 "Line up \"cascaded calls\" under each other.
d9e94c22
MS
746If the line begins with \"->\" or \".\" and the preceding line ends
747with one or more function calls preceded by the same token, then the
748arrow is lined up with the first of those tokens. E.g:
a66cd3ee
MS
749
750result = proc->add(17)->add(18)
751 ->add(19) + <- c-lineup-cascaded-calls
752 offset; <- c-lineup-cascaded-calls (inactive)
753
754In any other situation nil is returned to allow use in list
755expressions.
756
d9e94c22
MS
757Works with: topmost-intro-cont, statement-cont, arglist-cont,
758arglist-cont-nonempty."
759
760 (if (and (eq (car langelem) 'arglist-cont-nonempty)
761 (not (eq (nth 2 c-syntactic-element)
762 (c-most-enclosing-brace (c-parse-state)))))
763 ;; The innermost open paren is not our one, so don't do
764 ;; anything. This can occur for arglist-cont-nonempty with
765 ;; nested arglist starts on the same line.
766 nil
767
768 (save-excursion
a66cd3ee 769 (back-to-indentation)
d9e94c22
MS
770 (let ((operator (and (looking-at "->\\|\\.")
771 (regexp-quote (match-string 0))))
772 (stmt-start (cdr langelem)) col)
773
774 (when (and operator
775 (looking-at operator)
776 (zerop (c-backward-token-2 1 t stmt-start))
777 (eq (char-after) ?\()
778 (zerop (c-backward-token-2 2 t stmt-start))
779 (looking-at operator))
780 (setq col (current-column))
781
782 (while (and (zerop (c-backward-token-2 1 t stmt-start))
783 (eq (char-after) ?\()
784 (zerop (c-backward-token-2 2 t stmt-start))
785 (looking-at operator))
786 (setq col (current-column)))
787
788 (vector col))))))
789
790(defun c-lineup-string-cont (langelem)
791 "Line up a continued string under the one it continues.
792A continued string in this sense is where a string literal follows
793directly after another one. E.g:
794
795result = prefix + \"A message \"
796 \"string.\"; <- c-lineup-string-cont
797
798Nil is returned in other situations, to allow stacking with other
799lineup functions.
800
801Works with: topmost-intro-cont, statement-cont, arglist-cont,
802arglist-cont-nonempty."
803 (save-excursion
804 (back-to-indentation)
805 (and (looking-at "\\s\"")
806 (let ((quote (char-after)) pos)
807 (while (and (progn (c-backward-syntactic-ws)
808 (eq (char-before) quote))
809 (c-safe (c-backward-sexp) t)
810 (/= (setq pos (point)) (c-point 'boi))))
811 (when pos
812 (goto-char pos)
813 (vector (current-column)))))))
a66cd3ee 814
51f606de
GM
815(defun c-lineup-template-args (langelem)
816 "Line up template argument lines under the first argument.
817To allow this function to be used in a list expression, nil is
818returned if there's no template argument on the first line.
819
820Works with: template-args-cont."
821 (save-excursion
822 (c-with-syntax-table c++-template-syntax-table
823 (beginning-of-line)
824 (backward-up-list 1)
825 (if (and (eq (char-after) ?<)
d9e94c22 826 (zerop (c-forward-token-2 1 nil (c-point 'eol))))
a66cd3ee 827 (vector (current-column))))))
51f606de 828
785eecbb 829(defun c-lineup-ObjC-method-call (langelem)
d9e94c22 830 "Line up selector args as Emacs Lisp mode does with function args:
51f606de
GM
831Go to the position right after the message receiver, and if you are at
832the end of the line, indent the current line c-basic-offset columns
833from the opening bracket; otherwise you are looking at the first
834character of the first method call argument, so lineup the current
835line with it.
836
837Works with: objc-method-call-cont."
785eecbb
RS
838 (save-excursion
839 (let* ((extra (save-excursion
840 (back-to-indentation)
841 (c-backward-syntactic-ws (cdr langelem))
842 (if (eq (char-before) ?:)
843 (- c-basic-offset)
844 0)))
845 (open-bracket-pos (cdr langelem))
846 (open-bracket-col (progn
847 (goto-char open-bracket-pos)
848 (current-column)))
849 (target-col (progn
850 (forward-char)
0ec8351b 851 (c-forward-sexp)
785eecbb
RS
852 (skip-chars-forward " \t")
853 (if (eolp)
854 (+ open-bracket-col c-basic-offset)
855 (current-column))))
856 )
857 (- target-col open-bracket-col extra))))
858
859(defun c-lineup-ObjC-method-args (langelem)
51f606de
GM
860 "Line up the colons that separate args.
861The colon on the current line is aligned with the one on the first
862line.
863
864Works with: objc-method-args-cont."
785eecbb
RS
865 (save-excursion
866 (let* ((here (c-point 'boi))
867 (curcol (progn (goto-char here) (current-column)))
868 (eol (c-point 'eol))
869 (relpos (cdr langelem))
870 (first-col-column (progn
871 (goto-char relpos)
872 (skip-chars-forward "^:" eol)
873 (and (eq (char-after) ?:)
874 (current-column)))))
875 (if (not first-col-column)
876 c-basic-offset
877 (goto-char here)
878 (skip-chars-forward "^:" eol)
879 (if (eq (char-after) ?:)
880 (+ curcol (- first-col-column (current-column)))
881 c-basic-offset)))))
882
883(defun c-lineup-ObjC-method-args-2 (langelem)
51f606de
GM
884 "Line up the colons that separate args.
885The colon on the current line is aligned with the one on the previous
886line.
887
888Works with: objc-method-args-cont."
785eecbb
RS
889 (save-excursion
890 (let* ((here (c-point 'boi))
891 (curcol (progn (goto-char here) (current-column)))
892 (eol (c-point 'eol))
893 (relpos (cdr langelem))
894 (prev-col-column (progn
895 (skip-chars-backward "^:" relpos)
896 (and (eq (char-before) ?:)
897 (- (current-column) 1)))))
898 (if (not prev-col-column)
899 c-basic-offset
900 (goto-char here)
901 (skip-chars-forward "^:" eol)
902 (if (eq (char-after) ?:)
903 (+ curcol (- prev-col-column (current-column)))
904 c-basic-offset)))))
905
0ec8351b 906(defun c-lineup-inexpr-block (langelem)
51f606de
GM
907 "Line up the block for constructs that use a block inside an expression,
908e.g. anonymous classes in Java and lambda functions in Pike. The body
909is aligned with the start of the header, e.g. with the \"new\" or
910\"lambda\" keyword. Returns nil if the block isn't part of such a
911construct.
912
913Works with: inlambda, inexpr-statement, inexpr-class."
0ec8351b
BW
914 (save-excursion
915 (back-to-indentation)
a66cd3ee
MS
916 (let* ((paren-state (c-parse-state))
917 (containing-sexp (c-most-enclosing-brace paren-state))
918 (res (or (c-looking-at-inexpr-block
919 (c-safe-position containing-sexp paren-state)
920 containing-sexp)
921 (and containing-sexp
922 (progn (goto-char containing-sexp)
923 (eq (char-after) ?{))
924 (progn (setq containing-sexp
925 (c-most-enclosing-brace paren-state
926 (point)))
927 (c-looking-at-inexpr-block
928 (c-safe-position containing-sexp paren-state)
929 containing-sexp))))))
51f606de 930 (when res
0ec8351b
BW
931 (goto-char (cdr res))
932 (- (current-column)
933 (progn
934 (back-to-indentation)
935 (current-column)))))))
936
51f606de
GM
937(defun c-lineup-whitesmith-in-block (langelem)
938 "Line up lines inside a block in whitesmith style.
939It's done in a way that works both when the opening brace hangs and
940when it doesn't. E.g:
941
942something
943 { something {
944 foo; <-> foo; <- c-lineup-whitesmith-in-block
945 } }
946 <--> c-basic-offset
947
948In the first case the indentation is kept unchanged, in the
949second `c-basic-offset' is added.
950
951Works with: defun-close, defun-block-intro, block-close,
d9e94c22
MS
952brace-list-close, brace-list-intro, statement-block-intro and all in*
953symbols, e.g. inclass and inextern-lang."
eae86618 954 (save-excursion
51f606de 955 (goto-char (cdr langelem))
eae86618 956 (back-to-indentation)
51f606de
GM
957 (if (eq (char-syntax (char-after)) ?\()
958 0
959 c-basic-offset)))
eae86618 960
a66cd3ee
MS
961(defun c-lineup-cpp-define (langelem)
962 "Line up macro continuation lines according to the indentation of
963the construct preceding the macro. E.g:
964
965v beg of preceding constr v beg of preceding constr
966 int dribble() {
967const char msg[] = if (!running)
968 \"Some text.\"; error(\"Not running!\");
969
970#define X(A, B) \ #define X(A, B) \
971do { \ <-> do { \ <- c-lineup-cpp-define
972 printf (A, B); \ printf (A, B); \
973} while (0) } while (0)
974
975If `c-syntactic-indentation-in-macros' is non-nil, the function
976returns the relative indentation to the macro start line to allow
977accumulation with other offsets. E.g. in the following cases,
978cpp-define-intro is combined with the statement-block-intro that comes
979from the \"do {\" that hangs on the \"#define\" line:
980
981 int dribble() {
982const char msg[] = if (!running)
983 \"Some text.\"; error(\"Not running!\");
984
985#define X(A, B) do { \ #define X(A, B) do { \
986 printf (A, B); \ <-> printf (A, B); \ <- c-lineup-cpp-define
987 this->refs++; \ this->refs++; \
988} while (0) <-> } while (0) <- c-lineup-cpp-define
989
990The relative indentation returned by `c-lineup-cpp-define' is zero and
d9e94c22 991two, respectively, in these two examples. They are then added to the
a66cd3ee
MS
992two column indentation that statement-block-intro gives in both cases
993here.
994
995If the relative indentation is zero, then nil is returned instead.
d9e94c22
MS
996That is useful in a list expression to specify the default indentation
997on the top level.
a66cd3ee
MS
998
999If `c-syntactic-indentation-in-macros' is nil then this function keeps
1000the current indentation, except for empty lines \(ignoring the ending
1001backslash) where it takes the indentation from the closest preceding
1002nonempty line in the macro. If there's no such line in the macro then
1003the indentation is taken from the construct preceding it, as described
1004above.
1005
1006Works with: cpp-define-intro."
1007 (let (offset)
1008 (if c-syntactic-indentation-in-macros
1009 ;; Go to the macro start and do a syntactic analysis of it.
1010 ;; Then remove the cpp-macro element it should contain and
1011 ;; calculate the indentation it then would get.
1012 (save-excursion
1013 (c-beginning-of-macro)
1014 (setq offset (- (c-get-syntactic-indentation
1015 (delete '(cpp-macro) (c-guess-basic-syntax)))
1016 (save-excursion
1017 (back-to-indentation)
1018 (current-column))))
1019 (if (zerop offset)
1020 nil
1021 offset))
1022 ;; Do not indent syntactically inside the macro.
1023 (save-excursion
1024 (let ((macro-start-line (save-excursion
1025 (goto-char (c-query-macro-start))
1026 (beginning-of-line)
1027 (point))))
1028 (beginning-of-line)
1029 ;; Check every line while inside the macro.
1030 (while (and (> (point) macro-start-line)
1031 (looking-at "[ \t]*\\\\?$")
1032 (= (forward-line -1) 0)))
1033 (if (<= (point) macro-start-line)
1034 ;; If we've stepped out of the macro we take the
1035 ;; syntactic offset.
1036 (setq offset (c-get-syntactic-indentation
1037 (delete '(cpp-macro) (c-guess-basic-syntax))))
1038 (setq offset (current-indentation)))
1039 (if (zerop offset)
1040 nil
1041 (vector offset)))))))
1042
1043;; Contributed by Kevin Ryde <user42@zip.com.au>.
1044(defun c-lineup-gcc-asm-reg (elem)
1045 "Line up a gcc asm register under one on a previous line.
1046
1047 asm (\"foo %1, %0\\n\"
1048 \"bar %0, %1\"
1049 : \"=r\" (w),
1050 \"=r\" (x)
1051 : \"0\" (y),
1052 \"1\" (z));
1053
1054The \"x\" line is aligned to the text after the \":\" on the \"w\" line, and
1055similarly \"z\" under \"y\".
1056
1057This is done only in an \"asm\" or \"__asm__\" block, and only to those
8df87102 1058lines mentioned. Anywhere else nil is returned. The usual arrangement is
a66cd3ee
MS
1059to have this routine as an extra feature at the start of arglist lineups, e.g.
1060
1061 (c-lineup-gcc-asm-reg c-lineup-arglist)
1062
1063Works with: arglist-cont, arglist-cont-nonempty."
1064
1065 (let ((orig-pos (point))
1066 alignto)
1067 (save-excursion
1068 (and
1069 c-opt-asm-stmt-key
1070
d9e94c22
MS
1071 ;; Don't do anything if the innermost open paren isn't our one.
1072 ;; This can occur for arglist-cont-nonempty with nested arglist
1073 ;; starts on the same line.
1074 (or (not (eq (car elem) 'arglist-cont-nonempty))
1075 (eq (elt c-syntactic-element 2)
1076 (c-most-enclosing-brace (c-parse-state))))
1077
a66cd3ee
MS
1078 ;; Find the ":" to align to. Look for this first so as to quickly
1079 ;; eliminate pretty much all cases which are not for us.
1080 (re-search-backward "^[ \t]*:[ \t]*\\(.\\)?" (cdr elem) t)
1081
1082 ;; Must have something after the ":".
1083 (setq alignto (match-beginning 1))
1084
1085 ;; Don't touch ":" lines themselves.
1086 (progn (goto-char orig-pos)
1087 (beginning-of-line)
1088 (not (looking-at "^[ \t]*:")))
1089
1090 ;; Only operate in an asm statement.
1091 (progn (goto-char orig-pos)
1092 (c-in-gcc-asm-p))
1093
1094 (vector (progn (goto-char alignto) (current-column)))))))
1095
51f606de
GM
1096(defun c-lineup-dont-change (langelem)
1097 "Do not change the indentation of the current line.
1098
1099Works with: Any syntactic symbol."
1100 (save-excursion
1101 (back-to-indentation)
130c507e 1102 (vector (current-column))))
eae86618
RS
1103
1104\f
785eecbb
RS
1105(defun c-snug-do-while (syntax pos)
1106 "Dynamically calculate brace hanginess for do-while statements.
1107Using this function, `while' clauses that end a `do-while' block will
1108remain on the same line as the brace that closes that block.
1109
1110See `c-hanging-braces-alist' for how to utilize this function as an
1111ACTION associated with `block-close' syntax."
1112 (save-excursion
1113 (let (langelem)
1114 (if (and (eq syntax 'block-close)
1115 (setq langelem (assq 'block-close c-syntactic-context))
d9e94c22 1116 (progn (goto-char (elt langelem 1))
785eecbb 1117 (if (eq (char-after) ?{)
0ec8351b 1118 (c-safe (c-forward-sexp -1)))
785eecbb
RS
1119 (looking-at "\\<do\\>[^_]")))
1120 '(before)
1121 '(before after)))))
1122
1123(defun c-gnu-impose-minimum ()
1124 "Imposes a minimum indentation for lines inside a top-level construct.
1125The variable `c-label-minimum-indentation' specifies the minimum
1126indentation amount."
d9e94c22
MS
1127
1128 ;; Don't adjust macro or comment-only lines.
1129 (unless (or (assq 'cpp-macro c-syntactic-context)
1130 (assq 'comment-intro c-syntactic-context))
1131
1132 (let ((paren-state (save-excursion
1133 ;; Get the parenthesis state, but skip past
1134 ;; an initial closing paren on the line since
1135 ;; the close brace of a block shouldn't be
1136 ;; considered to be inside the block.
1137 (back-to-indentation)
1138 (when (looking-at "\\s\)")
1139 (forward-char))
1140 (c-parse-state))))
1141
1142 ;; Search for an enclosing brace on paren-state.
1143 (while (and paren-state
1144 (not (and (integer-or-marker-p (car paren-state))
1145 (eq (char-after (car paren-state)) ?{))))
1146 (setq paren-state (cdr paren-state)))
1147
1148 (when paren-state
1149 (save-excursion
1150 (back-to-indentation)
1151 (if (zerop (current-column))
1152 (insert-char ?\ c-label-minimum-indentation t)))))))
785eecbb
RS
1153
1154\f
1155;; Useful for c-hanging-semi&comma-criteria
51f606de 1156
785eecbb 1157(defun c-semi&comma-inside-parenlist ()
eae86618 1158 "Controls newline insertion after semicolons in parenthesis lists.
785eecbb
RS
1159If a comma was inserted, no determination is made. If a semicolon was
1160inserted inside a parenthesis list, no newline is added otherwise a
1161newline is added. In either case, checking is stopped. This supports
1162exactly the old newline insertion behavior."
1163 ;; newline only after semicolon, but only if that semicolon is not
1164 ;; inside a parenthesis list (e.g. a for loop statement)
1165 (if (not (eq last-command-char ?\;))
1166 nil ; continue checking
1167 (if (condition-case nil
1168 (save-excursion
1169 (up-list -1)
1170 (not (eq (char-after) ?\()))
1171 (error t))
1172 t
1173 'stop)))
1174
eae86618
RS
1175;; Suppresses newlines before non-blank lines
1176(defun c-semi&comma-no-newlines-before-nonblanks ()
1177 "Controls newline insertion after semicolons.
1178If a comma was inserted, no determination is made. If a semicolon was
1179inserted, and the following line is not blank, no newline is inserted.
1180Otherwise, no determination is made."
1181 (save-excursion
1182 (if (and (= last-command-char ?\;)
1183 ;;(/= (point-max)
1184 ;; (save-excursion (skip-syntax-forward " ") (point))
1185 (zerop (forward-line 1))
1186 (not (looking-at "^[ \t]*$")))
1187 'stop
1188 nil)))
1189
1190;; Suppresses new lines after semicolons in one-liners methods
1191(defun c-semi&comma-no-newlines-for-oneline-inliners ()
1192 "Controls newline insertion after semicolons for some one-line methods.
1193If a comma was inserted, no determination is made. Newlines are
1194suppressed in one-liners, if the line is an in-class inline function.
1195For other semicolon contexts, no determination is made."
1196 (let ((syntax (c-guess-basic-syntax))
1197 (bol (save-excursion
1198 (if (c-safe (up-list -1) t)
1199 (c-point 'bol)
1200 -1))))
1201 (if (and (eq last-command-char ?\;)
1202 (eq (car (car syntax)) 'inclass)
1203 (eq (car (car (cdr syntax))) 'topmost-intro)
1204 (= (c-point 'bol) bol))
1205 'stop
1206 nil)))
1207
785eecbb 1208\f
130c507e 1209(cc-provide 'cc-align)
3afbc435 1210
ab5796a9 1211;;; arch-tag: 4d71ed28-bf51-4509-a148-f39669669a2e
785eecbb 1212;;; cc-align.el ends here