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