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