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