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