]> code.delx.au - gnu-emacs/blob - lisp/progmodes/cc-cmds.el
(compile-internal): Style typo.
[gnu-emacs] / lisp / progmodes / cc-cmds.el
1 ;;; cc-cmds.el --- user level commands for CC Mode
2
3 ;; Copyright (C) 1985,1987,1992-1999 Free Software Foundation, Inc.
4
5 ;; Authors: 1998-1999 Barry A. Warsaw and Martin Stjernholm
6 ;; 1992-1997 Barry A. Warsaw
7 ;; 1987 Dave Detlefs and Stewart Clamen
8 ;; 1985 Richard M. Stallman
9 ;; Maintainer: bug-cc-mode@gnu.org
10 ;; Created: 22-Apr-1997 (split from cc-mode.el)
11 ;; Version: See cc-mode.el
12 ;; Keywords: c languages oop
13
14 ;; This file is part of GNU Emacs.
15
16 ;; GNU Emacs is free software; you can redistribute it and/or modify
17 ;; it under the terms of the GNU General Public License as published by
18 ;; the Free Software Foundation; either version 2, or (at your option)
19 ;; any later version.
20
21 ;; GNU Emacs is distributed in the hope that it will be useful,
22 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 ;; GNU General Public License for more details.
25
26 ;; You should have received a copy of the GNU General Public License
27 ;; along with GNU Emacs; see the file COPYING. If not, write to the
28 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
29 ;; Boston, MA 02111-1307, USA.
30
31 (eval-when-compile
32 (let ((load-path
33 (if (and (boundp 'byte-compile-current-file)
34 (stringp byte-compile-current-file))
35 (cons (file-name-directory byte-compile-current-file)
36 load-path)
37 load-path)))
38 (load "cc-defs" nil t)))
39 (require 'cc-engine)
40
41 \f
42 (defun c-calculate-state (arg prevstate)
43 ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
44 ;; arg is nil or zero, toggle the state. If arg is negative, turn
45 ;; the state off, and if arg is positive, turn the state on
46 (if (or (not arg)
47 (zerop (setq arg (prefix-numeric-value arg))))
48 (not prevstate)
49 (> arg 0)))
50
51 ;; Auto-newline and hungry-delete
52 (defun c-toggle-auto-state (arg)
53 "Toggle auto-newline feature.
54 Optional numeric ARG, if supplied turns on auto-newline when positive,
55 turns it off when negative, and just toggles it when zero.
56
57 When the auto-newline feature is enabled (as evidenced by the `/a' or
58 `/ah' on the modeline after the mode name) newlines are automatically
59 inserted after special characters such as brace, comma, semi-colon,
60 and colon."
61 (interactive "P")
62 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
63 (c-update-modeline)
64 (c-keep-region-active))
65
66 (defun c-toggle-hungry-state (arg)
67 "Toggle hungry-delete-key feature.
68 Optional numeric ARG, if supplied turns on hungry-delete when positive,
69 turns it off when negative, and just toggles it when zero.
70
71 When the hungry-delete-key feature is enabled (as evidenced by the
72 `/h' or `/ah' on the modeline after the mode name) the delete key
73 gobbles all preceding whitespace in one fell swoop."
74 (interactive "P")
75 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
76 (c-update-modeline)
77 (c-keep-region-active))
78
79 (defun c-toggle-auto-hungry-state (arg)
80 "Toggle auto-newline and hungry-delete-key features.
81 Optional numeric ARG, if supplied turns on auto-newline and
82 hungry-delete when positive, turns them off when negative, and just
83 toggles them when zero.
84
85 See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
86 (interactive "P")
87 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
88 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
89 (c-update-modeline)
90 (c-keep-region-active))
91
92 \f
93 ;; Electric keys
94
95 ;; Note: In XEmacs 20.3 the Delete and BackSpace keysyms have been
96 ;; separated and "\177" is no longer an alias for both keys. Also,
97 ;; the variable delete-key-deletes-forward controls in which direction
98 ;; the Delete keysym deletes characters. The functions
99 ;; c-electric-delete and c-electric-backspace attempt to deal with
100 ;; this new functionality. For Emacs 19 and XEmacs 19 backwards
101 ;; compatibility, the old behavior has moved to c-electric-backspace
102 ;; and c-backspace-function.
103
104 (defun c-electric-backspace (arg)
105 "Deletes preceding character or whitespace.
106 If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
107 \"/ah\" string on the mode line, then all preceding whitespace is
108 consumed. If however an ARG is supplied, or `c-hungry-delete-key' is
109 nil, or point is inside a literal then the function in the variable
110 `c-backspace-function' is called.
111
112 See also \\[c-electric-delete]."
113 (interactive "*P")
114 (if (or (not c-hungry-delete-key)
115 arg
116 (c-in-literal))
117 (funcall c-backspace-function (prefix-numeric-value arg))
118 (let ((here (point)))
119 (skip-chars-backward " \t\n")
120 (if (/= (point) here)
121 (delete-region (point) here)
122 (funcall c-backspace-function 1)
123 ))))
124
125 (defun c-electric-delete (arg)
126 "Deletes preceding or following character or whitespace.
127
128 The behavior of this function depends on the variable
129 `delete-key-deletes-forward'. If this variable is nil (or does not
130 exist, as in older Emacsen), then this function behaves identical to
131 \\[c-electric-backspace].
132
133 If `delete-key-deletes-forward' is non-nil and is supported in your
134 Emacs, then deletion occurs in the forward direction. So if
135 `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
136 \"/ah\" string on the mode line, then all following whitespace is
137 consumed. If however an ARG is supplied, or `c-hungry-delete-key' is
138 nil, or point is inside a literal then the function in the variable
139 `c-delete-function' is called."
140 (interactive "*P")
141 (if (or (and (fboundp 'delete-forward-p) ;XEmacs 21
142 (delete-forward-p))
143 (and (boundp 'delete-key-deletes-forward) ;XEmacs 20
144 delete-key-deletes-forward))
145 (if (or (not c-hungry-delete-key)
146 arg
147 (c-in-literal))
148 (funcall c-delete-function (prefix-numeric-value arg))
149 (let ((here (point)))
150 (skip-chars-forward " \t\n")
151 (if (/= (point) here)
152 (delete-region (point) here)
153 (funcall c-delete-function 1))))
154 ;; act just like c-electric-backspace
155 (c-electric-backspace arg)))
156
157 (defun c-electric-pound (arg)
158 "Electric pound (`#') insertion.
159 Inserts a `#' character specially depending on the variable
160 `c-electric-pound-behavior'. If a numeric ARG is supplied, or if
161 point is inside a literal, nothing special happens."
162 (interactive "*P")
163 (if (or arg
164 (not (memq 'alignleft c-electric-pound-behavior))
165 (save-excursion (skip-chars-backward " \t") (not (bolp)))
166 (c-in-literal))
167 ;; do nothing special
168 (self-insert-command (prefix-numeric-value arg))
169 ;; place the pound character at the left edge
170 (let ((pos (- (point-max) (point)))
171 (bolp (bolp)))
172 (beginning-of-line)
173 (delete-horizontal-space)
174 (insert-char last-command-char 1)
175 (and (not bolp)
176 (goto-char (- (point-max) pos)))
177 )))
178
179 (defun c-electric-brace (arg)
180 "Insert a brace.
181
182 If the auto-newline feature is turned on, as evidenced by the \"/a\"
183 or \"/ah\" string on the mode line, newlines are inserted before and
184 after braces based on the value of `c-hanging-braces-alist'.
185
186 Also, the line is re-indented unless a numeric ARG is supplied, there
187 are non-whitespace characters present on the line after the brace, or
188 the brace is inserted inside a literal.
189
190 This function does various newline cleanups based on the value of
191 `c-cleanup-list'."
192 (interactive "*P")
193 (let* ((c-state-cache (c-parse-state))
194 (safepos (c-safe-position (point) c-state-cache))
195 (literal (c-in-literal safepos)))
196 ;; if we're in a literal, or we're not at the end of the line, or
197 ;; a numeric arg is provided, or auto-newlining is turned off,
198 ;; then just insert the character.
199 (if (or literal
200 arg
201 (not (looking-at "[ \t]*$")))
202 (self-insert-command (prefix-numeric-value arg))
203 (let* ((syms
204 ;; This is the list of brace syntactic symbols that can
205 ;; hang. If any new ones are added to c-offsets-alist,
206 ;; they should be added here as well.
207 '(class-open class-close defun-open defun-close
208 inline-open inline-close
209 brace-list-open brace-list-close
210 brace-list-intro brace-entry-open
211 block-open block-close
212 substatement-open statement-case-open
213 extern-lang-open extern-lang-close
214 namespace-open namespace-close
215 inexpr-class-open inexpr-class-close
216 ))
217 ;; we want to inhibit blinking the paren since this will
218 ;; be most disruptive. we'll blink it ourselves later on
219 (old-blink-paren blink-paren-function)
220 blink-paren-function
221 (insertion-point (point))
222 delete-temp-newline
223 (preserve-p (and (not (bobp))
224 (eq ?\ (char-syntax (char-before)))))
225 ;; shut this up too
226 (c-echo-syntactic-information-p nil)
227 (syntax (progn
228 ;; only insert a newline if there is
229 ;; non-whitespace behind us
230 (if (save-excursion
231 (skip-chars-backward " \t")
232 (not (bolp)))
233 (progn (newline)
234 (setq delete-temp-newline t)))
235 (self-insert-command (prefix-numeric-value arg))
236 ;; state cache doesn't change
237 (c-guess-basic-syntax)))
238 (newlines (and
239 c-auto-newline
240 (or (c-lookup-lists
241 syms
242 ;; Substitute inexpr-class and class-open
243 ;; or class-close with inexpr-class-open
244 ;; or inexpr-class-close.
245 (if (assq 'inexpr-class syntax)
246 (cond ((assq 'class-open syntax)
247 '((inexpr-class-open)))
248 ((assq 'class-close syntax)
249 '((inexpr-class-close)))
250 (t syntax))
251 syntax)
252 c-hanging-braces-alist)
253 '(ignore before after)))))
254 ;; Do not try to insert newlines around a special (Pike-style)
255 ;; brace list.
256 (if (and c-special-brace-lists
257 (c-intersect-lists '(brace-list-open brace-list-close
258 brace-list-intro brace-entry-open)
259 syntax)
260 (save-excursion
261 (c-safe (if (= (char-before) ?{)
262 (forward-char -1)
263 (c-forward-sexp -1))
264 (c-looking-at-special-brace-list))))
265 (setq newlines nil))
266 ;; If syntax is a function symbol, then call it using the
267 ;; defined semantics.
268 (if (and (not (consp (cdr newlines)))
269 (functionp (cdr newlines)))
270 (let ((c-syntactic-context syntax))
271 (setq newlines
272 (funcall (cdr newlines) (car newlines) insertion-point))))
273 ;; does a newline go before the open brace?
274 (if (memq 'before newlines)
275 ;; we leave the newline we've put in there before,
276 ;; but we need to re-indent the line above
277 (let ((pos (- (point-max) (point)))
278 (here (point)))
279 (forward-line -1)
280 (let ((c-state-cache (c-whack-state (point) c-state-cache)))
281 ;; we may need to update the cache. this should
282 ;; still be faster than recalculating the state
283 ;; in many cases
284 (save-excursion
285 (save-restriction
286 (narrow-to-region here (point))
287 (if (and (c-safe (progn (backward-up-list -1) t))
288 (memq (char-before) '(?\) ?}))
289 (progn (widen)
290 (c-safe (progn (c-forward-sexp -1)
291 t))))
292 (setq c-state-cache
293 (c-hack-state (point) 'open c-state-cache)))))
294 (c-indent-line))
295 (setq c-state-cache (c-adjust-state (c-point 'bol) here
296 (- (point) (c-point 'bol))
297 c-state-cache))
298 (goto-char (- (point-max) pos))
299 ;; if the buffer has changed due to the indentation, we
300 ;; need to recalculate syntax for the current line, but
301 ;; we won't need to update the state cache.
302 (if (/= (point) here)
303 (setq syntax (c-guess-basic-syntax))))
304 ;; must remove the newline we just stuck in (if we really did it)
305 (and delete-temp-newline
306 (save-excursion
307 ;; if there is whitespace before point, then preserve
308 ;; at least one space.
309 (delete-indentation)
310 (just-one-space)
311 (if (not preserve-p)
312 (delete-char -1))))
313 ;; since we're hanging the brace, we need to recalculate
314 ;; syntax. Update the state to accurately reflect the
315 ;; beginning of the line. We punt if we cross any open or
316 ;; closed parens because its just too hard to modify the
317 ;; known state. This limitation will be fixed in v5.
318 (save-excursion
319 (let ((bol (c-point 'bol)))
320 (if (zerop (car (parse-partial-sexp bol (1- (point)))))
321 (setq c-state-cache (c-whack-state bol c-state-cache)
322 syntax (c-guess-basic-syntax))
323 ;; gotta punt. this requires some horrible kludgery
324 (beginning-of-line)
325 (makunbound 'c-state-cache)
326 (setq c-state-cache (c-parse-state)
327 syntax nil))))
328 )
329 ;; now adjust the line's indentation. don't update the state
330 ;; cache since c-guess-basic-syntax isn't called when the
331 ;; syntax is passed to c-indent-line
332 (let* ((here (point)))
333 (c-indent-line syntax)
334 (setq c-state-cache (c-adjust-state (c-point 'bol) here
335 (- (c-point 'boi) (c-point 'bol))
336 c-state-cache)))
337 ;; Do all appropriate clean ups
338 (let ((here (point))
339 (pos (- (point-max) (point)))
340 mbeg mend tmp)
341 ;; clean up empty defun braces
342 (if (and c-auto-newline
343 (memq 'empty-defun-braces c-cleanup-list)
344 (eq last-command-char ?\})
345 (c-intersect-lists '(defun-close class-close inline-close)
346 syntax)
347 (progn
348 (forward-char -1)
349 (skip-chars-backward " \t\n")
350 (eq (char-before) ?\{))
351 ;; make sure matching open brace isn't in a comment
352 (not (c-in-literal)))
353 (delete-region (point) (1- here)))
354 ;; clean up brace-else-brace and brace-elseif-brace
355 (when (and c-auto-newline
356 (eq last-command-char ?\{)
357 (not (c-in-literal)))
358 (cond
359 ((and (memq 'brace-else-brace c-cleanup-list)
360 (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
361 (progn
362 (setq mbeg (match-beginning 0)
363 mend (match-end 0))
364 (eq (match-end 0) here)))
365 (delete-region mbeg mend)
366 (insert "} else {"))
367 ((and (memq 'brace-elseif-brace c-cleanup-list)
368 (progn
369 (goto-char (1- here))
370 (setq mend (point))
371 (skip-chars-backward " \t\n")
372 (setq mbeg (point))
373 (eq (char-before) ?\)))
374 (= (c-backward-token-1 1 t) 0)
375 (eq (char-after) ?\()
376 (progn
377 (setq tmp (point))
378 (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*"
379 nil t))
380 (eq (match-end 0) tmp))
381 (delete-region mbeg mend)
382 (goto-char mbeg)
383 (insert " "))))
384 (goto-char (- (point-max) pos))
385 )
386 ;; does a newline go after the brace?
387 (if (memq 'after newlines)
388 (progn
389 (newline)
390 ;; update on c-state-cache
391 (let* ((bufpos (- (point) 2))
392 (which (if (eq (char-after bufpos) ?{) 'open 'close))
393 (c-state-cache (c-hack-state bufpos which c-state-cache)))
394 (c-indent-line))))
395 ;; blink the paren
396 (and (eq last-command-char ?\})
397 old-blink-paren
398 (save-excursion
399 (c-backward-syntactic-ws safepos)
400 (funcall old-blink-paren)))
401 ))))
402
403 (defun c-electric-slash (arg)
404 "Insert a slash character.
405
406 Indent the line as a comment, if:
407
408 1. The slash is second of a `//' line oriented comment introducing
409 token and we are on a comment-only-line, or
410
411 2. The slash is part of a `*/' token that closes a block oriented
412 comment.
413
414 If numeric ARG is supplied or point is inside a literal, indentation
415 is inhibited."
416 (interactive "*P")
417 (let* ((ch (char-before))
418 (indentp (and (not arg)
419 (eq last-command-char ?/)
420 (or (and (eq ch ?/)
421 (not (c-in-literal)))
422 (and (eq ch ?*)
423 (c-in-literal)))
424 ))
425 ;; shut this up
426 (c-echo-syntactic-information-p nil))
427 (self-insert-command (prefix-numeric-value arg))
428 (if indentp
429 (c-indent-line))))
430
431 (defun c-electric-star (arg)
432 "Insert a star character.
433 If the star is the second character of a C style comment introducing
434 construct, and we are on a comment-only-line, indent line as comment.
435 If numeric ARG is supplied or point is inside a literal, indentation
436 is inhibited."
437 (interactive "*P")
438 (self-insert-command (prefix-numeric-value arg))
439 ;; if we are in a literal, or if arg is given do not re-indent the
440 ;; current line, unless this star introduces a comment-only line.
441 (if (and (not arg)
442 (memq (c-in-literal) '(c))
443 (eq (char-before) ?*)
444 (save-excursion
445 (forward-char -1)
446 (skip-chars-backward "*")
447 (if (eq (char-before) ?/)
448 (forward-char -1))
449 (skip-chars-backward " \t")
450 (bolp)))
451 ;; shut this up
452 (let (c-echo-syntactic-information-p)
453 (c-indent-line))
454 ))
455
456 (defun c-electric-semi&comma (arg)
457 "Insert a comma or semicolon.
458 When the auto-newline feature is turned on, as evidenced by the \"/a\"
459 or \"/ah\" string on the mode line, a newline might be inserted. See
460 the variable `c-hanging-semi&comma-criteria' for how newline insertion
461 is determined.
462
463 When semicolon is inserted, the line is re-indented unless a numeric
464 arg is supplied, point is inside a literal, or there are
465 non-whitespace characters on the line following the semicolon.
466
467 Based on the value of `c-cleanup-list', this function cleans up commas
468 following brace lists and semicolons following defuns."
469 (interactive "*P")
470 (let* ((lim (c-most-enclosing-brace (c-parse-state)))
471 (literal (c-in-literal lim))
472 (here (point))
473 ;; shut this up
474 (c-echo-syntactic-information-p nil))
475 (if (or literal
476 arg
477 (not (looking-at "[ \t]*$")))
478 (self-insert-command (prefix-numeric-value arg))
479 ;; do some special stuff with the character
480 (self-insert-command (prefix-numeric-value arg))
481 ;; do all cleanups and newline insertions if c-auto-newline is
482 ;; turned on
483 (if (not c-auto-newline)
484 (c-indent-line)
485 ;; clean ups
486 (let ((pos (- (point-max) (point))))
487 (if (and (or (and
488 (eq last-command-char ?,)
489 (memq 'list-close-comma c-cleanup-list))
490 (and
491 (eq last-command-char ?\;)
492 (memq 'defun-close-semi c-cleanup-list)))
493 (progn
494 (forward-char -1)
495 (skip-chars-backward " \t\n")
496 (eq (char-before) ?}))
497 ;; make sure matching open brace isn't in a comment
498 (not (c-in-literal lim)))
499 (delete-region (point) here))
500 (goto-char (- (point-max) pos)))
501 ;; re-indent line
502 (c-indent-line)
503 ;; check to see if a newline should be added
504 (let ((criteria c-hanging-semi&comma-criteria)
505 answer add-newline-p)
506 (while criteria
507 (setq answer (funcall (car criteria)))
508 ;; only nil value means continue checking
509 (if (not answer)
510 (setq criteria (cdr criteria))
511 (setq criteria nil)
512 ;; only 'stop specifically says do not add a newline
513 (setq add-newline-p (not (eq answer 'stop)))
514 ))
515 (if add-newline-p
516 (progn (newline)
517 (c-indent-line)))
518 )))))
519
520 (defun c-electric-colon (arg)
521 "Insert a colon.
522
523 If the auto-newline feature is turned on, as evidenced by the \"/a\"
524 or \"/ah\" string on the mode line, newlines are inserted before and
525 after colons based on the value of `c-hanging-colons-alist'.
526
527 Also, the line is re-indented unless a numeric ARG is supplied, there
528 are non-whitespace characters present on the line after the colon, or
529 the colon is inserted inside a literal.
530
531 This function cleans up double colon scope operators based on the
532 value of `c-cleanup-list'."
533 (interactive "*P")
534 (let* ((bod (c-point 'bod))
535 (literal (c-in-literal bod))
536 syntax newlines is-scope-op
537 ;; shut this up
538 (c-echo-syntactic-information-p nil))
539 (if (or literal
540 arg
541 (not (looking-at "[ \t]*$")))
542 (self-insert-command (prefix-numeric-value arg))
543 ;; insert the colon, then do any specified cleanups
544 (self-insert-command (prefix-numeric-value arg))
545 (let ((pos (- (point-max) (point)))
546 (here (point)))
547 (if (and c-auto-newline
548 (memq 'scope-operator c-cleanup-list)
549 (eq (char-before) ?:)
550 (progn
551 (forward-char -1)
552 (skip-chars-backward " \t\n")
553 (eq (char-before) ?:))
554 (not (c-in-literal))
555 (not (eq (char-after (- (point) 2)) ?:)))
556 (progn
557 (delete-region (point) (1- here))
558 (setq is-scope-op t)))
559 (goto-char (- (point-max) pos)))
560 ;; lets do some special stuff with the colon character
561 (setq syntax (c-guess-basic-syntax)
562 ;; some language elements can only be determined by
563 ;; checking the following line. Lets first look for ones
564 ;; that can be found when looking on the line with the
565 ;; colon
566 newlines
567 (and c-auto-newline
568 (or (c-lookup-lists '(case-label label access-label)
569 syntax c-hanging-colons-alist)
570 (c-lookup-lists '(member-init-intro inher-intro)
571 (let ((buffer-undo-list t))
572 (insert "\n")
573 (unwind-protect
574 (c-guess-basic-syntax)
575 (delete-char -1)))
576 c-hanging-colons-alist))))
577 ;; indent the current line
578 (c-indent-line syntax)
579 ;; does a newline go before the colon? Watch out for already
580 ;; non-hung colons. However, we don't unhang them because that
581 ;; would be a cleanup (and anti-social).
582 (if (and (memq 'before newlines)
583 (not is-scope-op)
584 (save-excursion
585 (skip-chars-backward ": \t")
586 (not (bolp))))
587 (let ((pos (- (point-max) (point))))
588 (forward-char -1)
589 (newline)
590 (c-indent-line)
591 (goto-char (- (point-max) pos))))
592 ;; does a newline go after the colon?
593 (if (and (memq 'after (cdr-safe newlines))
594 (not is-scope-op))
595 (progn
596 (newline)
597 (c-indent-line)))
598 )))
599
600 (defun c-electric-lt-gt (arg)
601 "Insert a less-than, or greater-than character.
602 The line will be re-indented if the character inserted is the second
603 of a C++ style stream operator and the buffer is in C++ mode.
604 Exceptions are when a numeric argument is supplied, or point is inside
605 a literal, in which case the line will not be re-indented."
606 (interactive "*P")
607 (let ((indentp (and (not arg)
608 (eq (char-before) last-command-char)
609 (not (c-in-literal))))
610 ;; shut this up
611 (c-echo-syntactic-information-p nil))
612 (self-insert-command (prefix-numeric-value arg))
613 (if indentp
614 (c-indent-line))))
615
616 (defun c-electric-paren (arg)
617 "Insert a parenthesis.
618
619 If the auto-newline feature is turned on, as evidenced by the \"/a\"
620 or \"/ah\" string on the mode line, some newline cleanups are done if
621 appropriate; see the variable `c-cleanup-list'.
622
623 Also, the line is re-indented unless a numeric ARG is supplied, there
624 are non-whitespace characters present on the line after the
625 parenthesis, or the parenthesis is inserted inside a literal."
626 (interactive "*P")
627 (let (;; shut this up
628 (c-echo-syntactic-information-p nil))
629 (if (or arg
630 (not (looking-at "[ \t]*$"))
631 (c-in-literal (c-point 'bod)))
632 (self-insert-command (prefix-numeric-value arg))
633 ;; do some special stuff with the character
634 (let* (;; We want to inhibit blinking the paren since this will
635 ;; be most disruptive. We'll blink it ourselves
636 ;; afterwards.
637 (old-blink-paren blink-paren-function)
638 blink-paren-function)
639 (self-insert-command (prefix-numeric-value arg))
640 (c-indent-line)
641 (when c-auto-newline
642 ;; Do all appropriate clean ups
643 (let ((here (point))
644 (pos (- (point-max) (point)))
645 mbeg mend)
646 ;; clean up brace-elseif-brace
647 (if (and (memq 'brace-elseif-brace c-cleanup-list)
648 (eq last-command-char ?\()
649 (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*("
650 nil t)
651 (save-excursion
652 (setq mbeg (match-beginning 0)
653 mend (match-end 0))
654 (= mend here))
655 (not (c-in-literal)))
656 (progn
657 (delete-region mbeg mend)
658 (insert "} else if (")))
659 ;; clean up brace-catch-brace
660 (if (and (memq 'brace-catch-brace c-cleanup-list)
661 (eq last-command-char ?\()
662 (re-search-backward "}[ \t\n]*catch[ \t\n]*(" nil t)
663 (save-excursion
664 (setq mbeg (match-beginning 0)
665 mend (match-end 0))
666 (= mend here))
667 (not (c-in-literal)))
668 (progn
669 (delete-region mbeg mend)
670 (insert "} catch (")))
671 (goto-char (- (point-max) pos))
672 ))
673 (if old-blink-paren
674 (funcall old-blink-paren))))))
675
676
677 \f
678 ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
679 ;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com
680 (defun c-forward-into-nomenclature (&optional arg)
681 "Move forward to end of a nomenclature section or word.
682 With arg, to it arg times."
683 (interactive "p")
684 (let ((case-fold-search nil))
685 (if (> arg 0)
686 (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg)
687 (while (and (< arg 0)
688 (re-search-backward
689 "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)"
690 (point-min) 0))
691 (forward-char 1)
692 (setq arg (1+ arg)))))
693 (c-keep-region-active))
694
695 (defun c-backward-into-nomenclature (&optional arg)
696 "Move backward to beginning of a nomenclature section or word.
697 With optional ARG, move that many times. If ARG is negative, move
698 forward."
699 (interactive "p")
700 (c-forward-into-nomenclature (- arg))
701 (c-keep-region-active))
702
703 (defun c-scope-operator ()
704 "Insert a double colon scope operator at point.
705 No indentation or other \"electric\" behavior is performed."
706 (interactive "*")
707 (insert "::"))
708
709 (defun c-beginning-of-defun (&optional arg)
710 "Move backward to the beginning of a defun.
711 With argument, do it that many times. Negative arg -N
712 means move forward to Nth following beginning of defun.
713 Returns t unless search stops due to beginning or end of buffer.
714
715 Unlike the built-in `beginning-of-defun' this tries to be smarter
716 about finding the char with open-parenthesis syntax that starts the
717 defun."
718 (interactive "p")
719 (unless arg (setq arg 1))
720 (if (< arg 0)
721 (c-end-of-defun (- arg))
722 (while (> arg 0)
723 (let ((state (nreverse (c-parse-state)))
724 prevbod bod)
725 (while (and state (not bod))
726 (setq bod (car state)
727 state (cdr state))
728 (if (consp bod)
729 (setq prevbod (car bod)
730 bod nil)))
731 (cond
732 (bod (goto-char bod))
733 (prevbod (goto-char prevbod))
734 (t (goto-char (point-min))
735 (setq arg 0)))
736 (setq arg (1- arg))))
737 (c-keep-region-active)
738 (= arg 0)))
739
740 (defun c-end-of-defun (&optional arg)
741 "Move forward to next end of defun. With argument, do it that many times.
742 Negative argument -N means move back to Nth preceding end of defun.
743 Returns t unless search stops due to beginning or end of buffer.
744
745 An end of a defun occurs right after the close-parenthesis that matches
746 the open-parenthesis that starts a defun; see `beginning-of-defun'."
747 (interactive "p")
748 (if (not arg)
749 (setq arg 1))
750 (if (< arg 0)
751 (c-beginning-of-defun (- arg))
752 (while (> arg 0)
753 (let ((pos (point))
754 eol)
755 (while (and (c-safe (down-list 1) t)
756 (not (eq (char-before) ?{)))
757 ;; skip down into the next defun-block
758 (forward-char -1)
759 (c-forward-sexp))
760 (c-beginning-of-defun 1)
761 (setq eol (c-point 'eol))
762 (c-forward-sexp)
763 (if (< eol (point))
764 ;; Don't move to next line for one line defuns.
765 (forward-line 1))
766 (when (<= (point) pos)
767 (goto-char (point-max))
768 (setq arg 0))
769 (setq arg (1- arg))))
770 (c-keep-region-active)
771 (= arg 0)))
772
773 \f
774 (defun c-beginning-of-statement (&optional count lim sentence-flag)
775 "Go to the beginning of the innermost C statement.
776 With prefix arg, go back N - 1 statements. If already at the
777 beginning of a statement then go to the beginning of the closest
778 preceding one, moving into nested blocks if necessary (use
779 \\[backward-sexp] to skip over a block). If within a comment, or next
780 to a comment (only whitespace between), move by sentences instead of
781 statements.
782
783 When called from a program, this function takes 3 optional args: the
784 repetition count, a buffer position limit which is the farthest back
785 to search, and a flag saying whether to do sentence motion when in a
786 comment."
787 (interactive (list (prefix-numeric-value current-prefix-arg)
788 nil t))
789 (let* ((count (or count 1))
790 here
791 (range (c-collect-line-comments (c-literal-limits lim))))
792 (while (and (/= count 0)
793 (or (not lim) (> (point) lim)))
794 (setq here (point))
795 (if (and (not range) sentence-flag)
796 (save-excursion
797 ;; Find the comment next to point if we're not in one.
798 (if (> count 0)
799 (setq range (if (c-forward-comment -1)
800 (cons (point)
801 (progn (c-forward-comment 1) (point)))))
802 (skip-chars-forward " \t\n")
803 (setq range (point))
804 (setq range (if (c-forward-comment 1)
805 (cons range (point))
806 nil)))
807 (setq range (c-collect-line-comments range))))
808 (if (and (< count 0) (= here (point-max)))
809 ;; Special case because eob might be in a literal.
810 (setq range nil))
811 (if range
812 (if (and sentence-flag
813 (/= (char-syntax (char-after (car range))) ?\"))
814 (let* ((lit-type (c-literal-type range))
815 (beg (save-excursion
816 (goto-char (car range))
817 (looking-at (if (eq lit-type 'c)
818 comment-start-skip
819 (concat "\\("
820 c-comment-prefix-regexp
821 "\\)[ \t]*")))
822 (goto-char (match-end 0))
823 (point)))
824 (end (save-excursion
825 (goto-char (- (cdr range)
826 (if (eq lit-type 'c) 2 1)))
827 (point))))
828 ;; move by sentence, but not past the limit of the literal
829 (save-restriction
830 (narrow-to-region beg end)
831 (c-safe (forward-sentence (if (< count 0) 1 -1)))
832 (if (and (memq lit-type '(c c++))
833 ;; Check if we stopped due to a comment
834 ;; prefix and not a sentence end.
835 (/= (point) beg)
836 (save-excursion
837 (beginning-of-line)
838 (looking-at (concat "[ \t]*\\("
839 c-comment-prefix-regexp
840 "\\)[ \t]*")))
841 (>= (point) (match-beginning 0))
842 (/= (match-beginning 1) (match-end 1))
843 (or (< (point) (match-end 0))
844 (and
845 (= (point) (match-end 0))
846 ;; The comment prefix may contain
847 ;; characters that is regarded as end
848 ;; of sentence.
849 (or (eolp)
850 (and
851 (save-excursion
852 (forward-paragraph -1)
853 (< (point) (match-beginning 0)))
854 (save-excursion
855 (beginning-of-line)
856 (or (not (re-search-backward
857 sentence-end
858 (c-point 'bopl)
859 t))
860 (< (match-end 0)
861 (c-point 'eol)))))))))
862 (setq count (+ count (if (< count 0) -1 1)))
863 (if (< count 0)
864 (progn
865 ;; In block comments, if there's only
866 ;; horizontal ws between the text and the
867 ;; comment ender, stop before it. Stop after
868 ;; the ender if there's either nothing or
869 ;; newlines between.
870 (when (and (eq lit-type 'c) (eq (point) end))
871 (widen)
872 (skip-chars-backward " \t")
873 (when (or (eq (point) end) (bolp))
874 (goto-char (cdr range)))))
875 (when (and (eq (point) beg) (looking-at "[ \t]*$"))
876 ;; Stop before instead of after the comment
877 ;; starter if nothing follows it.
878 (widen)
879 (goto-char (car range))))))
880 ;; See if we should escape the literal.
881 (if (> count 0)
882 (if (< (point) here)
883 (setq count (1- count))
884 (goto-char (car range))
885 (setq range nil))
886 (if (> (point) here)
887 (setq count (1+ count))
888 (goto-char (cdr range))
889 (setq range nil))))
890 (goto-char (if (> count 0) (car range) (cdr range)))
891 (setq range nil))
892 ;; Below we do approximately the same as
893 ;; c-beginning-of-statement-1 and c-end-of-statement-1, and
894 ;; perhaps they should be changed, but that'd likely break a
895 ;; lot in cc-engine.
896 (goto-char here)
897 (if (> count 0)
898 (condition-case nil
899 ;; Stop before `{' and after `;', `{', `}' and `};'
900 ;; when not followed by `}' or `)', but on the other
901 ;; side of the syntactic ws. Move by sexps and move
902 ;; into parens. Also stop before `#' when it's first
903 ;; on a line.
904 (let ((comment-pos (not sentence-flag))
905 (large-enough (- (point-max)))
906 last last-below-line)
907 (catch 'done
908 (while t
909 (setq last (point))
910 (when (and (looking-at "{\\|^#") (/= here last))
911 (unless (and c-special-brace-lists
912 (eq (char-after) ?{)
913 (c-looking-at-special-brace-list))
914 (if (and (eq (char-after) ?#)
915 (numberp last-below-line)
916 (not (eq last-below-line here)))
917 (goto-char last-below-line))
918 (throw 'done t)))
919 (if comment-pos
920 (c-forward-comment large-enough)
921 (when (c-forward-comment -1)
922 ;; Record position of first comment.
923 (save-excursion
924 (c-forward-comment 1)
925 (setq comment-pos (point)))
926 (c-forward-comment large-enough)))
927 (unless last-below-line
928 (if (save-excursion
929 (re-search-forward "\\(^\\|[^\\]\\)$" last t))
930 (setq last-below-line last)))
931 (cond ((bobp) ; Must handle bob specially.
932 (if (= here last)
933 (throw 'done t)
934 (goto-char last)
935 (throw 'done t)))
936 ((progn (backward-char)
937 (looking-at "[;{}]"))
938 (if (and c-special-brace-lists
939 (eq (char-after) ?{)
940 (c-looking-at-special-brace-list))
941 (skip-syntax-backward "w_") ; Speedup only.
942 (if (or (= here last)
943 (memq (char-after last) '(?\) ?})))
944 (if (and (eq (char-before) ?})
945 (eq (char-after) ?\;))
946 (backward-char))
947 (goto-char last)
948 (throw 'done t))))
949 ((= (char-syntax (char-after)) ?\")
950 (forward-char)
951 (c-backward-sexp))
952 (t (skip-syntax-backward "w_")) ; Speedup only.
953 )))
954 (if (and (numberp comment-pos)
955 (< (point) comment-pos))
956 ;; We jumped over a comment that should be investigated.
957 (goto-char comment-pos)
958 (setq count (1- count))))
959 (error
960 (goto-char (point-min))
961 (setq count 0)))
962 (condition-case nil
963 ;; Stop before `{', `}', and `#' when it's first on a
964 ;; line, but on the other side of the syntactic ws, and
965 ;; after `;', `}' and `};'. Only stop before `{' if at
966 ;; top level or inside braces, though. Move by sexps
967 ;; and move into parens. Also stop at eol of lines
968 ;; starting with `#'.
969 (let ((comment-pos (not sentence-flag))
970 (large-enough (point-max))
971 last)
972 (catch 'done
973 (while t
974 (setq last (point))
975 (if comment-pos
976 (c-forward-comment large-enough)
977 (if (progn
978 (skip-chars-forward " \t\n\r\f")
979 ;; Record position of first comment.
980 (setq comment-pos (point))
981 (c-forward-comment 1))
982 (c-forward-comment large-enough)
983 (setq comment-pos nil)))
984 (cond ((and (eq (char-after) ?{)
985 (not (and c-special-brace-lists
986 (c-looking-at-special-brace-list)))
987 (/= here last)
988 (save-excursion
989 (or (not (c-safe (up-list -1) t))
990 (= (char-after) ?{))))
991 (goto-char last)
992 (throw 'done t))
993 ((and c-special-brace-lists
994 (eq (char-after) ?})
995 (save-excursion
996 (and (c-safe (up-list -1) t)
997 (c-looking-at-special-brace-list))))
998 (forward-char 1)
999 (skip-syntax-forward "w_")) ; Speedup only.
1000 ((and (eq (char-after) ?})
1001 (/= here last))
1002 (goto-char last)
1003 (throw 'done t))
1004 ((looking-at "^#")
1005 (if (= here last)
1006 (or (re-search-forward "\\(^\\|[^\\]\\)$" nil t)
1007 (goto-char (point-max)))
1008 (goto-char last))
1009 (throw 'done t))
1010 ((looking-at ";\\|};?")
1011 (goto-char (match-end 0))
1012 (throw 'done t))
1013 ((= (char-syntax (char-after)) ?\")
1014 (c-forward-sexp))
1015 (t
1016 (forward-char 1)
1017 (skip-syntax-forward "w_")) ; Speedup only.
1018 )))
1019 (if (and (numberp comment-pos)
1020 (> (point) comment-pos))
1021 ;; We jumped over a comment that should be investigated.
1022 (goto-char comment-pos)
1023 (setq count (1+ count))))
1024 (error
1025 (goto-char (point-max))
1026 (setq count 0)))
1027 ))
1028 ;; If we haven't moved we're near a buffer limit.
1029 (when (and (not (zerop count)) (= (point) here))
1030 (goto-char (if (> count 0) (point-min) (point-max)))
1031 (setq count 0)))
1032 ;; its possible we've been left up-buf of lim
1033 (if lim (goto-char (max (point) lim))))
1034 (c-keep-region-active))
1035
1036 (defun c-end-of-statement (&optional count lim sentence-flag)
1037 "Go to the end of the innermost C statement.
1038 With prefix arg, go forward N - 1 statements. Move forward to the end
1039 of the next statement if already at end, and move into nested blocks
1040 \(use \\[forward-sexp] to skip over a block). If within a comment, or
1041 next to a comment (only whitespace between), move by sentences instead
1042 of statements.
1043
1044 When called from a program, this function takes 3 optional args: the
1045 repetition count, a buffer position limit which is the farthest back
1046 to search, and a flag saying whether to do sentence motion when in a
1047 comment."
1048 (interactive (list (prefix-numeric-value current-prefix-arg)
1049 nil t))
1050 (c-beginning-of-statement (- (or count 1)) lim sentence-flag)
1051 (c-keep-region-active))
1052
1053 \f
1054 ;; set up electric character functions to work with pending-del,
1055 ;; (a.k.a. delsel) mode. All symbols get the t value except
1056 ;; the functions which delete, which gets 'supersede.
1057 (mapcar
1058 (function
1059 (lambda (sym)
1060 (put sym 'delete-selection t) ; for delsel (Emacs)
1061 (put sym 'pending-delete t))) ; for pending-del (XEmacs)
1062 '(c-electric-pound
1063 c-electric-brace
1064 c-electric-slash
1065 c-electric-star
1066 c-electric-semi&comma
1067 c-electric-lt-gt
1068 c-electric-colon
1069 c-electric-paren))
1070 (put 'c-electric-delete 'delete-selection 'supersede) ; delsel
1071 (put 'c-electric-delete 'pending-delete 'supersede) ; pending-del
1072 (put 'c-electric-backspace 'delete-selection 'supersede) ; delsel
1073 (put 'c-electric-backspace 'pending-delete 'supersede) ; pending-del
1074
1075 \f
1076 ;; This is used by indent-for-comment to decide how much to indent a
1077 ;; comment in C code based on its context.
1078 (defun c-comment-indent ()
1079 (if (looking-at (concat "^\\(" c-comment-start-regexp "\\)"))
1080 0 ;Existing comment at bol stays there.
1081 (let ((opoint (point))
1082 placeholder)
1083 (save-excursion
1084 (beginning-of-line)
1085 (cond
1086 ;; CASE 1: A comment following a solitary close-brace should
1087 ;; have only one space.
1088 ((looking-at (concat "[ \t]*}[ \t]*\\($\\|"
1089 c-comment-start-regexp
1090 "\\)"))
1091 (search-forward "}")
1092 (1+ (current-column)))
1093 ;; CASE 2: 2 spaces after #endif
1094 ((or (looking-at "^#[ \t]*endif[ \t]*")
1095 (looking-at "^#[ \t]*else[ \t]*"))
1096 7)
1097 ;; CASE 3: when c-indent-comments-syntactically-p is t,
1098 ;; calculate the offset according to c-offsets-alist.
1099 ;; E.g. identical to hitting TAB.
1100 ((and c-indent-comments-syntactically-p
1101 (save-excursion
1102 (skip-chars-forward " \t")
1103 (or (looking-at c-comment-start-regexp)
1104 (eolp))))
1105 (let ((syntax (c-guess-basic-syntax)))
1106 ;; BOGOSITY ALERT: if we're looking at the eol, its
1107 ;; because indent-for-comment hasn't put the comment-start
1108 ;; in the buffer yet. this will screw up the syntactic
1109 ;; analysis so we kludge in the necessary info. Another
1110 ;; kludge is that if we're at the bol, then we really want
1111 ;; to ignore any anchoring as specified by
1112 ;; c-comment-only-line-offset since it doesn't apply here.
1113 (if (save-excursion
1114 (beginning-of-line)
1115 (skip-chars-forward " \t")
1116 (eolp))
1117 (c-add-syntax 'comment-intro))
1118 (let ((c-comment-only-line-offset
1119 (if (consp c-comment-only-line-offset)
1120 c-comment-only-line-offset
1121 (cons c-comment-only-line-offset
1122 c-comment-only-line-offset))))
1123 (apply '+ (mapcar 'c-get-offset syntax)))))
1124 ;; CASE 4: If previous line is a comment-only line, use its
1125 ;; indentation if it's greater than comment-column. Leave at
1126 ;; least one space between the comment and the last nonblank
1127 ;; character in any case.
1128 ((save-excursion
1129 (beginning-of-line)
1130 (and (not (bobp))
1131 (forward-line -1))
1132 (skip-chars-forward " \t")
1133 (prog1
1134 (looking-at c-comment-start-regexp)
1135 (setq placeholder (current-column))))
1136 (goto-char opoint)
1137 (skip-chars-backward " \t")
1138 (max (if (bolp) 0 (1+ (current-column)))
1139 placeholder
1140 comment-column))
1141 ;; CASE 5: If comment-column is 0, and nothing but space
1142 ;; before the comment, align it at 0 rather than 1.
1143 ((progn
1144 (goto-char opoint)
1145 (skip-chars-backward " \t")
1146 (and (= comment-column 0) (bolp)))
1147 0)
1148 ;; CASE 6: indent at comment column except leave at least one
1149 ;; space.
1150 (t (max (1+ (current-column))
1151 comment-column))
1152 )))))
1153
1154 \f
1155 ;; used by outline-minor-mode
1156 (defun c-outline-level ()
1157 (save-excursion
1158 (skip-chars-forward "\t ")
1159 (current-column)))
1160
1161 \f
1162 (defun c-up-conditional (count)
1163 "Move back to the containing preprocessor conditional, leaving mark behind.
1164 A prefix argument acts as a repeat count. With a negative argument,
1165 move forward to the end of the containing preprocessor conditional.
1166
1167 `#elif' is treated like `#else' followed by `#if', so the function
1168 stops at them when going backward, but not when going forward."
1169 (interactive "p")
1170 (c-forward-conditional (- count) -1)
1171 (c-keep-region-active))
1172
1173 (defun c-up-conditional-with-else (count)
1174 "Move back to the containing preprocessor conditional, including `#else'.
1175 Just like `c-up-conditional', except it also stops at `#else'
1176 directives."
1177 (interactive "p")
1178 (c-forward-conditional (- count) -1 t)
1179 (c-keep-region-active))
1180
1181 (defun c-down-conditional (count)
1182 "Move forward into the next preprocessor conditional, leaving mark behind.
1183 A prefix argument acts as a repeat count. With a negative argument,
1184 move backward into the previous preprocessor conditional.
1185
1186 `#elif' is treated like `#else' followed by `#if', so the function
1187 stops at them when going forward, but not when going backward."
1188 (interactive "p")
1189 (c-forward-conditional count 1)
1190 (c-keep-region-active))
1191
1192 (defun c-down-conditional-with-else (count)
1193 "Move forward into the next preprocessor conditional, including `#else'.
1194 Just like `c-down-conditional', except it also stops at `#else'
1195 directives."
1196 (interactive "p")
1197 (c-forward-conditional count 1 t)
1198 (c-keep-region-active))
1199
1200 (defun c-backward-conditional (count &optional target-depth with-else)
1201 "Move back across a preprocessor conditional, leaving mark behind.
1202 A prefix argument acts as a repeat count. With a negative argument,
1203 move forward across a preprocessor conditional."
1204 (interactive "p")
1205 (c-forward-conditional (- count) target-depth with-else)
1206 (c-keep-region-active))
1207
1208 (defun c-forward-conditional (count &optional target-depth with-else)
1209 "Move forward across a preprocessor conditional, leaving mark behind.
1210 A prefix argument acts as a repeat count. With a negative argument,
1211 move backward across a preprocessor conditional.
1212
1213 `#elif' is treated like `#else' followed by `#if', except that the
1214 nesting level isn't changed when tracking subconditionals.
1215
1216 The optional argument TARGET-DEPTH specifies the wanted nesting depth
1217 after each scan. I.e. if TARGET-DEPTH is -1, the function will move
1218 out of the enclosing conditional. A non-integer non-nil TARGET-DEPTH
1219 counts as -1.
1220
1221 If the optional argument WITH-ELSE is non-nil, `#else' directives are
1222 treated as conditional clause limits. Normally they are ignored."
1223 (interactive "p")
1224 (let* ((forward (> count 0))
1225 (increment (if forward -1 1))
1226 (search-function (if forward 're-search-forward 're-search-backward))
1227 (new))
1228 (unless (integerp target-depth)
1229 (setq target-depth (if target-depth -1 0)))
1230 (save-excursion
1231 (while (/= count 0)
1232 (let ((depth 0)
1233 ;; subdepth is the depth in "uninteresting" subtrees,
1234 ;; i.e. those that takes us farther from the target
1235 ;; depth instead of closer.
1236 (subdepth 0)
1237 found)
1238 (save-excursion
1239 ;; Find the "next" significant line in the proper direction.
1240 (while (and (not found)
1241 ;; Rather than searching for a # sign that
1242 ;; comes at the beginning of a line aside from
1243 ;; whitespace, search first for a string
1244 ;; starting with # sign. Then verify what
1245 ;; precedes it. This is faster on account of
1246 ;; the fastmap feature of the regexp matcher.
1247 (funcall search-function
1248 "#[ \t]*\\(if\\|elif\\|endif\\|else\\)"
1249 nil t))
1250 (beginning-of-line)
1251 ;; Now verify it is really a preproc line.
1252 (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\|else\\)")
1253 (let (dchange (directive (match-string 1)))
1254 (cond ((string= directive "if")
1255 (setq dchange (- increment)))
1256 ((string= directive "endif")
1257 (setq dchange increment))
1258 ((= subdepth 0)
1259 ;; When we're not in an "uninteresting"
1260 ;; subtree, we might want to act on "elif"
1261 ;; and "else" too.
1262 (if (cond (with-else
1263 ;; Always move toward the target depth.
1264 (setq dchange
1265 (if (> target-depth 0) 1 -1)))
1266 ((string= directive "elif")
1267 (setq dchange (- increment))))
1268 ;; Ignore the change if it'd take us
1269 ;; into an "uninteresting" subtree.
1270 (if (eq (> dchange 0) (<= target-depth 0))
1271 (setq dchange nil)))))
1272 (when dchange
1273 (when (or (/= subdepth 0)
1274 (eq (> dchange 0) (<= target-depth 0)))
1275 (setq subdepth (+ subdepth dchange)))
1276 (setq depth (+ depth dchange))
1277 ;; If we are trying to move across, and we find an
1278 ;; end before we find a beginning, get an error.
1279 (if (and (< depth target-depth) (< dchange 0))
1280 (error (if forward
1281 "No following conditional at this level"
1282 "No previous conditional at this level"))))
1283 ;; When searching forward, start from next line so
1284 ;; that we don't find the same line again.
1285 (if forward (forward-line 1))
1286 ;; We found something if we've arrived at the
1287 ;; target depth.
1288 (if (and dchange (= depth target-depth))
1289 (setq found (point))))
1290 ;; else
1291 (if forward (forward-line 1)))))
1292 (or found
1293 (error "No containing preprocessor conditional"))
1294 (goto-char (setq new found)))
1295 (setq count (+ count increment))))
1296 (push-mark)
1297 (goto-char new))
1298 (c-keep-region-active))
1299
1300 \f
1301 ;; commands to indent lines, regions, defuns, and expressions
1302 (defun c-indent-command (&optional whole-exp)
1303 "Indent current line as C code, and/or insert some whitespace.
1304
1305 If `c-tab-always-indent' is t, always just indent the current line.
1306 If nil, indent the current line only if point is at the left margin or
1307 in the line's indentation; otherwise insert some whitespace[*]. If
1308 other than nil or t, then some whitespace[*] is inserted only within
1309 literals (comments and strings) and inside preprocessor directives,
1310 but the line is always reindented.
1311
1312 A numeric argument, regardless of its value, means indent rigidly all
1313 the lines of the expression starting after point so that this line
1314 becomes properly indented. The relative indentation among the lines
1315 of the expression is preserved.
1316
1317 [*] The amount and kind of whitespace inserted is controlled by the
1318 variable `c-insert-tab-function', which is called to do the actual
1319 insertion of whitespace. Normally the function in this variable
1320 just inserts a tab character, or the equivalent number of spaces,
1321 depending on the variable `indent-tabs-mode'."
1322
1323 (interactive "P")
1324 (let ((bod (c-point 'bod)))
1325 (if whole-exp
1326 ;; If arg, always indent this line as C
1327 ;; and shift remaining lines of expression the same amount.
1328 (let ((shift-amt (c-indent-line))
1329 beg end)
1330 (save-excursion
1331 (if (eq c-tab-always-indent t)
1332 (beginning-of-line))
1333 (setq beg (point))
1334 (c-forward-sexp 1)
1335 (setq end (point))
1336 (goto-char beg)
1337 (forward-line 1)
1338 (setq beg (point)))
1339 (if (> end beg)
1340 (indent-code-rigidly beg end (- shift-amt) "#")))
1341 ;; No arg supplied, use c-tab-always-indent to determine
1342 ;; behavior
1343 (cond
1344 ;; CASE 1: indent when at column zero or in lines indentation,
1345 ;; otherwise insert a tab
1346 ((not c-tab-always-indent)
1347 (if (save-excursion
1348 (skip-chars-backward " \t")
1349 (not (bolp)))
1350 (funcall c-insert-tab-function)
1351 (c-indent-line)))
1352 ;; CASE 2: just indent the line
1353 ((eq c-tab-always-indent t)
1354 (c-indent-line))
1355 ;; CASE 3: if in a literal, insert a tab, but always indent the
1356 ;; line
1357 (t
1358 (if (c-in-literal bod)
1359 (funcall c-insert-tab-function))
1360 (c-indent-line)
1361 )))))
1362
1363 (defun c-indent-exp (&optional shutup-p)
1364 "Indent each line in balanced expression following point.
1365 Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
1366 (interactive "*P")
1367 (let ((here (point-marker))
1368 end progress-p)
1369 (set-marker-insertion-type here t)
1370 (unwind-protect
1371 (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
1372 (start (progn
1373 ;; try to be smarter about finding the range of
1374 ;; lines to indent. skip all following
1375 ;; whitespace. failing that, try to find any
1376 ;; opening brace on the current line
1377 (skip-chars-forward " \t\n")
1378 (if (memq (char-after) '(?\( ?\[ ?\{))
1379 (point)
1380 (let ((state (parse-partial-sexp (point)
1381 (c-point 'eol))))
1382 (and (nth 1 state)
1383 (goto-char (nth 1 state))
1384 (memq (char-after) '(?\( ?\[ ?\{))
1385 (point)))))))
1386 ;; find balanced expression end
1387 (setq end (and (c-safe (progn (c-forward-sexp 1) t))
1388 (point-marker)))
1389 ;; sanity check
1390 (and (not start)
1391 (not shutup-p)
1392 (error "Cannot find start of balanced expression to indent."))
1393 (and (not end)
1394 (not shutup-p)
1395 (error "Cannot find end of balanced expression to indent."))
1396 (c-progress-init start end 'c-indent-exp)
1397 (setq progress-p t)
1398 (goto-char start)
1399 (beginning-of-line)
1400 (while (< (point) end)
1401 (if (not (looking-at "[ \t]*$"))
1402 (c-indent-line))
1403 (c-progress-update)
1404 (forward-line 1)))
1405 ;; make sure marker is deleted
1406 (and end
1407 (set-marker end nil))
1408 (and progress-p
1409 (c-progress-fini 'c-indent-exp))
1410 (goto-char here)
1411 (set-marker here nil))))
1412
1413 (defun c-indent-defun ()
1414 "Re-indents the current top-level function def, struct or class declaration."
1415 (interactive "*")
1416 (let ((here (point-marker))
1417 (c-echo-syntactic-information-p nil)
1418 (brace (c-least-enclosing-brace (c-parse-state))))
1419 (goto-char (or brace (c-point 'bod)))
1420 ;; if we're sitting at b-o-b, it might be because there was no
1421 ;; least enclosing brace and we were sitting on the defun's open
1422 ;; brace.
1423 (if (and (bobp) (not (eq (char-after) ?\{)))
1424 (goto-char here))
1425 ;; if defun-prompt-regexp is non-nil, b-o-d might not leave us at
1426 ;; the open brace. I consider this an Emacs bug.
1427 (and (boundp 'defun-prompt-regexp)
1428 defun-prompt-regexp
1429 (looking-at defun-prompt-regexp)
1430 (goto-char (match-end 0)))
1431 ;; catch all errors in c-indent-exp so we can 1. give more
1432 ;; meaningful error message, and 2. restore point
1433 (unwind-protect
1434 (c-indent-exp)
1435 (goto-char here)
1436 (set-marker here nil))))
1437
1438 (defun c-indent-region (start end)
1439 ;; Indent every line whose first char is between START and END inclusive.
1440 (save-excursion
1441 (goto-char start)
1442 ;; Advance to first nonblank line.
1443 (skip-chars-forward " \t\n")
1444 (beginning-of-line)
1445 (let (endmark)
1446 (unwind-protect
1447 (let ((c-tab-always-indent t)
1448 ;; shut up any echo msgs on indiv lines
1449 (c-echo-syntactic-information-p nil)
1450 fence)
1451 (c-progress-init start end 'c-indent-region)
1452 (setq endmark (copy-marker end))
1453 (while (and (bolp)
1454 (not (eobp))
1455 (< (point) endmark))
1456 ;; update progress
1457 (c-progress-update)
1458 ;; Indent one line as with TAB.
1459 (let (nextline sexpend sexpbeg)
1460 ;; skip blank lines
1461 (skip-chars-forward " \t\n")
1462 (beginning-of-line)
1463 ;; indent the current line
1464 (c-indent-line)
1465 (setq fence (point))
1466 (if (save-excursion
1467 (beginning-of-line)
1468 (looking-at "[ \t]*#"))
1469 (forward-line 1)
1470 (save-excursion
1471 ;; Find beginning of following line.
1472 (setq nextline (c-point 'bonl))
1473 ;; Find first beginning-of-sexp for sexp extending past
1474 ;; this line.
1475 (beginning-of-line)
1476 (while (< (point) nextline)
1477 (condition-case nil
1478 (progn
1479 (c-forward-sexp 1)
1480 (setq sexpend (point)))
1481 (error (setq sexpend nil)
1482 (goto-char nextline)))
1483 (c-forward-syntactic-ws))
1484 (if sexpend
1485 (progn
1486 ;; make sure the sexp we found really starts on the
1487 ;; current line and extends past it
1488 (goto-char sexpend)
1489 (setq sexpend (point-marker))
1490 (c-safe (c-backward-sexp 1))
1491 (setq sexpbeg (point))))
1492 (if (and sexpbeg (< sexpbeg fence))
1493 (setq sexpbeg fence)))
1494 ;; Since we move by sexps we might have missed
1495 ;; comment-only lines.
1496 (if sexpbeg
1497 (save-excursion
1498 (while (progn
1499 (forward-line 1)
1500 (skip-chars-forward " \t")
1501 (< (point) sexpbeg))
1502 (if (looking-at c-comment-start-regexp)
1503 (setq sexpbeg (c-point 'bol))))))
1504 ;; If that sexp ends within the region, indent it all at
1505 ;; once, fast.
1506 (condition-case nil
1507 (if (and sexpend
1508 (> sexpend nextline)
1509 (<= sexpend endmark))
1510 (progn
1511 (goto-char sexpbeg)
1512 (c-indent-exp 'shutup)
1513 (c-progress-update)
1514 (goto-char sexpend)))
1515 (error
1516 (goto-char sexpbeg)
1517 (c-indent-line)))
1518 ;; Move to following line and try again.
1519 (and sexpend
1520 (markerp sexpend)
1521 (set-marker sexpend nil))
1522 (forward-line 1)
1523 (setq fence (point))))))
1524 (set-marker endmark nil)
1525 (c-progress-fini 'c-indent-region)
1526 (c-echo-parsing-error)
1527 ))))
1528
1529 (defun c-mark-function ()
1530 "Put mark at end of current top-level defun, point at beginning."
1531 (interactive)
1532 (let ((here (point))
1533 (eod (c-point 'eod))
1534 (state (c-parse-state)))
1535 ;; Are we sitting at the top level, someplace between either the
1536 ;; beginning of buffer, or the nearest preceding defun? If so,
1537 ;; try first to figure out whether we're sitting on the
1538 ;; introduction to a top-level defun, in which case we want to
1539 ;; mark the entire defun we're sitting on.
1540 ;;
1541 ;; If we're sitting on anything else at the top-level, we want to
1542 ;; just mark the statement that we're on
1543 (if (or (and (consp (car state))
1544 (= (length state) 1))
1545 (null state))
1546 ;; Are we in the whitespace after the nearest preceding defun?
1547 (if (and state
1548 (looking-at "[ \t]*$")
1549 (= (save-excursion
1550 (c-backward-syntactic-ws)
1551 (skip-chars-backward ";")
1552 (point))
1553 (cdar state)))
1554 (progn
1555 (setq eod (point))
1556 (goto-char (caar state))
1557 (c-beginning-of-statement-1))
1558 (if (= ?{ (save-excursion
1559 (c-end-of-statement-1)
1560 (char-before)))
1561 ;; We must be in a defuns's introduction
1562 (progn
1563 (c-end-of-statement-1)
1564 (skip-chars-backward "{")
1565 (c-beginning-of-statement-1)
1566 (c-forward-syntactic-ws))
1567 ;; Just mark the statement
1568 (c-end-of-statement-1)
1569 (forward-line 1)
1570 (setq eod (point))
1571 (c-beginning-of-statement-1)))
1572 ;; We are inside some enclosing brace structure, so we first
1573 ;; need to find our way to the least enclosing brace. Then, in
1574 ;; both cases, we to mark the region from the beginning of the
1575 ;; current statement, until the end of the next following defun
1576 (while (and state)
1577 (or (consp (car state))
1578 (goto-char (car state)))
1579 (setq state (cdr state)))
1580 (c-beginning-of-statement-1))
1581 (push-mark here)
1582 (push-mark eod nil t)))
1583
1584 (defun c-indent-line-or-region ()
1585 "When the region is active, indent it. Otherwise indent the current line."
1586 ;; Emacs has a variable called mark-active, XEmacs uses region-active-p
1587 (interactive)
1588 (if (c-region-is-active-p)
1589 (c-indent-region (region-beginning) (region-end))
1590 (c-indent-command)))
1591
1592 \f
1593 ;; for progress reporting
1594 (defvar c-progress-info nil)
1595
1596 (defun c-progress-init (start end context)
1597 (cond
1598 ;; Be silent
1599 ((not c-progress-interval))
1600 ;; Start the progress update messages. If this Emacs doesn't have
1601 ;; a built-in timer, just be dumb about it.
1602 ((not (fboundp 'current-time))
1603 (message "indenting region... (this may take a while)"))
1604 ;; If progress has already been initialized, do nothing. otherwise
1605 ;; initialize the counter with a vector of:
1606 ;; [start end lastsec context]
1607 (c-progress-info)
1608 (t (setq c-progress-info (vector start
1609 (save-excursion
1610 (goto-char end)
1611 (point-marker))
1612 (nth 1 (current-time))
1613 context))
1614 (message "indenting region..."))
1615 ))
1616
1617 (defun c-progress-update ()
1618 ;; update progress
1619 (if (not (and c-progress-info c-progress-interval))
1620 nil
1621 (let ((now (nth 1 (current-time)))
1622 (start (aref c-progress-info 0))
1623 (end (aref c-progress-info 1))
1624 (lastsecs (aref c-progress-info 2)))
1625 ;; should we update? currently, update happens every 2 seconds,
1626 ;; what's the right value?
1627 (if (< c-progress-interval (- now lastsecs))
1628 (progn
1629 (message "indenting region... (%d%% complete)"
1630 (/ (* 100 (- (point) start)) (- end start)))
1631 (aset c-progress-info 2 now)))
1632 )))
1633
1634 (defun c-progress-fini (context)
1635 ;; finished
1636 (if (not c-progress-interval)
1637 nil
1638 (if (or (eq context (aref c-progress-info 3))
1639 (eq context t))
1640 (progn
1641 (set-marker (aref c-progress-info 1) nil)
1642 (setq c-progress-info nil)
1643 (message "indenting region...done")))))
1644
1645
1646 \f
1647 ;;; This page handles insertion and removal of backslashes for C macros.
1648
1649 (defun c-backslash-region (from to delete-flag)
1650 "Insert, align, or delete end-of-line backslashes on the lines in the region.
1651 With no argument, inserts backslashes and aligns existing backslashes.
1652 With an argument, deletes the backslashes.
1653
1654 This function does not modify blank lines at the start of the region.
1655 If the region ends at the start of a line, it always deletes the
1656 backslash (if any) at the end of the previous line.
1657
1658 You can put the region around an entire macro definition and use this
1659 command to conveniently insert and align the necessary backslashes."
1660 (interactive "*r\nP")
1661 (save-excursion
1662 (goto-char from)
1663 (let ((column c-backslash-column)
1664 (endmark (make-marker)))
1665 (move-marker endmark to)
1666 ;; Compute the smallest column number past the ends of all the lines.
1667 (if (not delete-flag)
1668 (while (< (point) to)
1669 (end-of-line)
1670 (if (eq (char-before) ?\\)
1671 (progn (forward-char -1)
1672 (skip-chars-backward " \t")))
1673 (setq column (max column (1+ (current-column))))
1674 (forward-line 1)))
1675 ;; Adjust upward to a tab column, if that doesn't push past the margin.
1676 (if (> (% column tab-width) 0)
1677 (let ((adjusted (* (/ (+ column tab-width -1) tab-width) tab-width)))
1678 (if (< adjusted (window-width))
1679 (setq column adjusted))))
1680 ;; Don't modify blank lines at start of region.
1681 (goto-char from)
1682 (while (and (< (point) endmark) (eolp))
1683 (forward-line 1))
1684 ;; Add or remove backslashes on all the lines.
1685 (while (< (point) endmark)
1686 (if (and (not delete-flag)
1687 ;; Un-backslashify the last line
1688 ;; if the region ends right at the start of the next line.
1689 (save-excursion
1690 (forward-line 1)
1691 (< (point) endmark)))
1692 (c-append-backslash column)
1693 (c-delete-backslash))
1694 (forward-line 1))
1695 (move-marker endmark nil))))
1696
1697 (defun c-append-backslash (column)
1698 (end-of-line)
1699 (if (eq (char-before) ?\\)
1700 (progn (forward-char -1)
1701 (delete-horizontal-space)
1702 (indent-to column))
1703 (indent-to column)
1704 (insert "\\")))
1705
1706 (defun c-delete-backslash ()
1707 (end-of-line)
1708 (or (bolp)
1709 (progn
1710 (forward-char -1)
1711 (if (looking-at "\\\\")
1712 (delete-region (1+ (point))
1713 (progn (skip-chars-backward " \t") (point)))))))
1714
1715
1716 \f
1717 ;;; Line breaking and paragraph filling.
1718
1719 ;; The filling code is based on a simple theory; leave the intricacies
1720 ;; of the text handling to the currently active mode for that
1721 ;; (e.g. adaptive-fill-mode or filladapt-mode) and do as little as
1722 ;; possible to make them work correctly wrt the comment and string
1723 ;; separators, one-line paragraphs etc. Unfortunately, when it comes
1724 ;; to it, there's quite a lot of special cases to handle which makes
1725 ;; the code anything but simple. The intention is that it will work
1726 ;; with any well-written text filling package that preserves a fill
1727 ;; prefix.
1728 ;;
1729 ;; We temporarily mask comment starters and enders as necessary for
1730 ;; the filling code to do its job on a seemingly normal text block.
1731 ;; We do _not_ mask the fill prefix, so it's up to the filling code to
1732 ;; preserve it correctly (especially important when filling C++ style
1733 ;; line comments). By default, we set up and use adaptive-fill-mode,
1734 ;; which is standard in all supported Emacs flavors.
1735
1736 (defun c-guess-fill-prefix (lit-limits lit-type)
1737 ;; Determine the appropriate comment fill prefix for a block or line
1738 ;; comment. Return a cons of the prefix string and the column where
1739 ;; it ends. If fill-prefix is set, it'll override. Note that this
1740 ;; function also uses the value of point in some heuristics.
1741 (let* ((here (point))
1742 (prefix-regexp (concat "[ \t]*\\("
1743 c-comment-prefix-regexp
1744 "\\)[ \t]*"))
1745 (comment-start-regexp (if (eq lit-type 'c++)
1746 prefix-regexp
1747 comment-start-skip))
1748 prefix-line comment-prefix res)
1749 (cond
1750 (fill-prefix
1751 (setq res (cons fill-prefix
1752 ;; Ugly way of getting the column after the fill
1753 ;; prefix; it'd be nice with a current-column
1754 ;; that works on strings..
1755 (let ((buffer-modified (buffer-modified-p))
1756 (buffer-undo-list t)
1757 (start (point)))
1758 (unwind-protect
1759 (progn
1760 (insert ?\n fill-prefix)
1761 (current-column))
1762 (delete-region start (point))
1763 (set-buffer-modified-p buffer-modified))))))
1764 ((eq lit-type 'c++)
1765 (save-excursion
1766 ;; Set fallback for comment-prefix if none is found.
1767 (setq comment-prefix "// ")
1768 (beginning-of-line)
1769 (if (> (point) (car lit-limits))
1770 ;; The current line is not the comment starter, so the
1771 ;; comment has more than one line, and it can therefore be
1772 ;; used to find the comment fill prefix.
1773 (setq prefix-line (point))
1774 (goto-char (car lit-limits))
1775 (if (and (= (forward-line 1) 0)
1776 (< (point) (cdr lit-limits)))
1777 ;; The line after the comment starter is inside the
1778 ;; comment, so we can use it.
1779 (setq prefix-line (point))
1780 ;; The comment is only one line. Take the comment prefix
1781 ;; from it and keep the indentation.
1782 (goto-char (car lit-limits))
1783 (if (looking-at prefix-regexp)
1784 (goto-char (match-end 0))
1785 (forward-char 2)
1786 (skip-chars-forward " \t"))
1787 (setq res
1788 (if (eq (c-point 'boi) (car lit-limits))
1789 ;; There is only whitespace before the comment
1790 ;; starter; take the prefix straight from this
1791 ;; line.
1792 (cons (buffer-substring-no-properties
1793 (c-point 'bol) (point))
1794 (current-column))
1795 ;; There is code before the comment starter, so we
1796 ;; have to temporarily insert and indent a new
1797 ;; line to get the right space/tab mix in the
1798 ;; indentation.
1799 (let ((buffer-modified (buffer-modified-p))
1800 (buffer-undo-list t)
1801 (prefix-len (- (point) (car lit-limits)))
1802 tmp)
1803 (unwind-protect
1804 (progn
1805 (goto-char (car lit-limits))
1806 (indent-to (prog1 (current-column)
1807 (insert ?\n)))
1808 (setq tmp (point))
1809 (forward-char prefix-len)
1810 (cons (buffer-substring-no-properties
1811 (c-point 'bol) (point))
1812 (current-column)))
1813 (delete-region (car lit-limits) tmp)
1814 (set-buffer-modified-p buffer-modified))))
1815 )))))
1816 (t
1817 (save-excursion
1818 (beginning-of-line)
1819 (if (and (> (point) (car lit-limits))
1820 (not (and (looking-at "[ \t]*\\*/")
1821 (eq (cdr lit-limits) (match-end 0)))))
1822 ;; The current line is not the comment starter and
1823 ;; contains more than just the ender, so it's good enough
1824 ;; to be used for the comment fill prefix.
1825 (setq prefix-line (point))
1826 (goto-char (car lit-limits))
1827 (if (or (/= (forward-line 1) 0)
1828 (>= (point) (cdr lit-limits))
1829 (and (looking-at "[ \t]*\\*/")
1830 (eq (cdr lit-limits) (match-end 0)))
1831 (and (looking-at prefix-regexp)
1832 (<= (1- (cdr lit-limits)) (match-end 0)))
1833 (and (< here (point))
1834 (or (not (match-beginning 0))
1835 (looking-at "[ \t]*$"))))
1836 ;; The comment is either one line or the next line
1837 ;; contains just the comment ender. Also, if point is
1838 ;; on the comment opener line and the following line is
1839 ;; empty or doesn't match c-comment-prefix-regexp we
1840 ;; assume that this is in fact a not yet closed one line
1841 ;; comment, so we shouldn't look for the comment prefix
1842 ;; on the next line. In these cases we have no
1843 ;; information about a suitable comment prefix, so we
1844 ;; resort to c-block-comment-prefix.
1845 (setq comment-prefix (or c-block-comment-prefix "")
1846 res (let ((buffer-modified (buffer-modified-p))
1847 (buffer-undo-list t)
1848 tmp-pre tmp-post)
1849 ;; The comment doesn't give any information
1850 ;; about the indentation column. We'll have to
1851 ;; temporarily insert a new comment line and
1852 ;; indent it to find the correct column.
1853 (unwind-protect
1854 (progn
1855 (goto-char (car lit-limits))
1856 (if (looking-at comment-start-regexp)
1857 (goto-char (match-end 0))
1858 (forward-char 2)
1859 (skip-chars-forward " \t"))
1860 (when (eq (char-syntax (char-before)) ?\ )
1861 ;; If there's ws on the current
1862 ;; line, we'll use it instead of
1863 ;; what's ending comment-prefix.
1864 (setq comment-prefix
1865 (concat (substring comment-prefix
1866 0 (string-match
1867 "\\s *\\'"
1868 comment-prefix))
1869 (buffer-substring-no-properties
1870 (save-excursion
1871 (skip-chars-backward " \t")
1872 (point))
1873 (point)))))
1874 (setq tmp-pre (point-marker))
1875 ;; We insert an extra non-whitespace
1876 ;; character before the line break and
1877 ;; after comment-prefix in case it's
1878 ;; "" or ends with whitespace.
1879 (insert "x\n" comment-prefix ?x)
1880 (setq tmp-post (point-marker))
1881 (c-indent-line)
1882 (goto-char (1- tmp-post))
1883 (cons (buffer-substring-no-properties
1884 (c-point 'bol) (point))
1885 (current-column)))
1886 (when tmp-post
1887 (delete-region tmp-pre tmp-post)
1888 (set-marker tmp-pre nil)
1889 (set-marker tmp-post nil))
1890 (set-buffer-modified-p buffer-modified))))
1891 ;; Otherwise the line after the comment starter is good
1892 ;; enough to find the prefix in.
1893 (setq prefix-line (point)))))))
1894 (or res
1895 (save-excursion
1896 ;; prefix-line is the bol of a line on which we should try
1897 ;; to find the prefix.
1898 (let* (fb-string fb-endpos ; Contains any fallback prefix found.
1899 (test-line
1900 (lambda ()
1901 (when (and (looking-at prefix-regexp)
1902 (< (match-end 0) (1- (cdr lit-limits))))
1903 (unless fb-string
1904 (setq fb-string (buffer-substring-no-properties
1905 (match-beginning 0) (match-end 0))
1906 fb-endpos (match-end 0)))
1907 (unless (eq (match-end 0) (c-point 'eol))
1908 (throw 'found t))
1909 t))))
1910 (if (catch 'found
1911 ;; Search for a line which has text after the prefix
1912 ;; so that we get the proper amount of whitespace
1913 ;; after it. We start with the current line, then
1914 ;; search backwards, then forwards.
1915 (goto-char prefix-line)
1916 (when (and (funcall test-line)
1917 (/= (match-end 1) (match-end 0)))
1918 ;; If the current line doesn't have text but do
1919 ;; have whitespace after the prefix, we'll use it.
1920 (throw 'found t))
1921 (while (and (zerop (forward-line -1))
1922 (> (point) (car lit-limits)))
1923 (funcall test-line))
1924 (goto-char prefix-line)
1925 (while (and (zerop (forward-line 1))
1926 (< (point) (cdr lit-limits)))
1927 (funcall test-line))
1928 nil)
1929 ;; A good line with text after the prefix was found.
1930 (cons (buffer-substring-no-properties (point) (match-end 0))
1931 (progn (goto-char (match-end 0)) (current-column)))
1932 (if fb-string
1933 ;; A good line wasn't found, but at least we have a
1934 ;; fallback that matches the comment prefix regexp.
1935 (cond ((string-match "\\s \\'" fb-string)
1936 ;; There are ws after the prefix, so let's use it.
1937 (cons fb-string
1938 (progn (goto-char fb-endpos) (current-column))))
1939 ((progn
1940 ;; Check if there's any whitespace padding
1941 ;; on the comment start line that we can
1942 ;; use after the prefix.
1943 (goto-char (car lit-limits))
1944 (if (looking-at comment-start-regexp)
1945 (goto-char (match-end 0))
1946 (forward-char 2)
1947 (skip-chars-forward " \t"))
1948 (eq (char-syntax (char-before)) ?\ ))
1949 (setq fb-string (buffer-substring-no-properties
1950 (save-excursion
1951 (skip-chars-backward " \t")
1952 (point))
1953 (point)))
1954 (goto-char fb-endpos)
1955 (skip-chars-backward " \t")
1956 (let ((buffer-modified (buffer-modified-p))
1957 (buffer-undo-list t)
1958 (tmp (point)))
1959 ;; Got to mess in the buffer once again to
1960 ;; ensure the column gets correct. :P
1961 (unwind-protect
1962 (progn
1963 (insert fb-string)
1964 (cons (buffer-substring-no-properties
1965 (c-point 'bol)
1966 (point))
1967 (current-column)))
1968 (delete-region tmp (point)))))
1969 (t
1970 ;; Last resort: Just add a single space after
1971 ;; the prefix.
1972 (cons (concat fb-string " ")
1973 (progn (goto-char fb-endpos)
1974 (1+ (current-column))))))
1975 ;; The line doesn't match the comment prefix regexp.
1976 (if comment-prefix
1977 ;; We have a fallback for line comments that we must use.
1978 (cons (concat (buffer-substring-no-properties
1979 prefix-line (c-point 'boi))
1980 comment-prefix)
1981 (progn (back-to-indentation)
1982 (+ (current-column) (length comment-prefix))))
1983 ;; Assume we are dealing with a "free text" block
1984 ;; comment where the lines doesn't have any comment
1985 ;; prefix at all and we should just fill it as
1986 ;; normal text.
1987 '("" . 0)))))))
1988 ))
1989
1990 (defun c-fill-paragraph (&optional arg)
1991 "Like \\[fill-paragraph] but handles C and C++ style comments.
1992 If any of the current line is a comment or within a comment, fill the
1993 comment or the paragraph of it that point is in, preserving the
1994 comment indentation or line-starting decorations (see the
1995 `c-comment-prefix-regexp' and `c-block-comment-prefix' variables for
1996 details).
1997
1998 If point is inside multiline string literal, fill it. This currently
1999 does not respect escaped newlines, except for the special case when it
2000 is the very first thing in the string. The intended use for this rule
2001 is in situations like the following:
2002
2003 char description[] = \"\\
2004 A very long description of something that you want to fill to make
2005 nicely formatted output.\"\;
2006
2007 If point is in any other situation, i.e. in normal code, do nothing.
2008
2009 Optional prefix ARG means justify paragraph as well."
2010 (interactive "*P")
2011 (let (lit-limits lit-type fill
2012 ;; beg and end limits the region to be filled. end is a marker.
2013 beg end
2014 ;; tmp-pre and tmp-post marks strings that are temporarily
2015 ;; inserted at the start and end of the region. tmp-pre is a
2016 ;; cons of the positions of the prepended string. tmp-post is
2017 ;; a marker pointing to the single character of the appended
2018 ;; string.
2019 tmp-pre tmp-post
2020 hang-ender-stuck)
2021 ;; Restore point on undo. It's necessary since we do a lot of
2022 ;; hidden inserts and deletes below that should be as transparent
2023 ;; as possible.
2024 (if (and buffer-undo-list (not (eq buffer-undo-list t)))
2025 (setq buffer-undo-list (cons (point) buffer-undo-list)))
2026 (save-excursion
2027 (save-restriction
2028 ;; Widen to catch comment limits correctly.
2029 (widen)
2030 (setq lit-limits (c-collect-line-comments (c-literal-limits nil t))
2031 lit-type (c-literal-type lit-limits)))
2032 (forward-paragraph)
2033 (setq end (point-marker))
2034 (backward-paragraph)
2035 (setq beg (point)))
2036 (when (and (>= (point) beg) (<= (point) end))
2037 (unwind-protect
2038 (progn
2039 (cond
2040 ((eq lit-type 'c++) ; Line comment.
2041 (save-excursion
2042 ;; Fill to the comment or paragraph end, whichever
2043 ;; comes first.
2044 (set-marker end (min end (cdr lit-limits)))
2045 (when (<= beg (car lit-limits))
2046 ;; The region to be filled includes the comment
2047 ;; starter, so we must check it.
2048 (goto-char (car lit-limits))
2049 (back-to-indentation)
2050 (if (eq (point) (car lit-limits))
2051 ;; Include the first line in the fill.
2052 (setq beg (c-point 'bol))
2053 ;; The first line contains code before the
2054 ;; comment. We must fake a line that doesn't.
2055 (setq tmp-pre t)))
2056 ))
2057 ((eq lit-type 'c) ; Block comment.
2058 (save-excursion
2059 (when (>= end (cdr lit-limits))
2060 ;; The region to be filled includes the comment ender.
2061 (goto-char (cdr lit-limits))
2062 (beginning-of-line)
2063 (if (and (looking-at (concat "[ \t]*\\("
2064 c-comment-prefix-regexp
2065 "\\)\\*/"))
2066 (eq (cdr lit-limits) (match-end 0)))
2067 ;; Leave the comment ender on its own line.
2068 (set-marker end (point))
2069 ;; The comment ender should hang. Replace all
2070 ;; cruft between it and the last word with a 'x'
2071 ;; and include it in the fill. We'll change it
2072 ;; back to a space afterwards.
2073 (let ((ender-start (progn
2074 (goto-char (cdr lit-limits))
2075 (skip-syntax-backward "^w ")
2076 (point)))
2077 spaces)
2078 (goto-char (cdr lit-limits))
2079 (setq tmp-post (point-marker))
2080 (insert ?\n)
2081 (set-marker end (point))
2082 (forward-line -1)
2083 (if (and (looking-at (concat "[ \t]*\\(\\("
2084 c-comment-prefix-regexp
2085 "\\)[ \t]*\\)"))
2086 (eq ender-start (match-end 0)))
2087 ;; The comment ender is prefixed by nothing
2088 ;; but a comment line prefix. Remove it
2089 ;; along with surrounding ws.
2090 (setq spaces (- (match-end 1) (match-end 2)))
2091 (goto-char ender-start))
2092 (skip-chars-backward " \t\r\n")
2093 (when (/= (point) ender-start)
2094 ;; Keep one or two spaces between the text and
2095 ;; the ender, depending on how many there are now.
2096 (unless spaces (setq spaces (- ender-start (point))))
2097 (setq spaces (max (min spaces 2) 1))
2098 ; Insert the filler first to keep marks right.
2099 (insert (make-string spaces ?x))
2100 (delete-region (point) (+ ender-start spaces))
2101 (setq hang-ender-stuck spaces)))))
2102 (when (<= beg (car lit-limits))
2103 ;; The region to be filled includes the comment starter.
2104 (goto-char (car lit-limits))
2105 (if (looking-at (concat "\\(" comment-start-skip "\\)$"))
2106 ;; Begin filling with the next line.
2107 (setq beg (c-point 'bonl))
2108 ;; Fake the fill prefix in the first line.
2109 (setq tmp-pre t)))
2110 ))
2111 ((eq lit-type 'string) ; String.
2112 (save-excursion
2113 (when (>= end (cdr lit-limits))
2114 (goto-char (1- (cdr lit-limits)))
2115 (setq tmp-post (point-marker))
2116 (insert ?\n)
2117 (set-marker end (point)))
2118 (when (<= beg (car lit-limits))
2119 (goto-char (1+ (car lit-limits)))
2120 (setq beg (if (looking-at "\\\\$")
2121 ;; Leave the start line if it's
2122 ;; nothing but an escaped newline.
2123 (1+ (match-end 0))
2124 (point))))))
2125 (t (setq beg nil)))
2126 (when tmp-pre
2127 ;; Temporarily insert the fill prefix after the comment
2128 ;; starter so that the first line looks like any other
2129 ;; comment line in the narrowed region.
2130 (setq fill (c-guess-fill-prefix lit-limits lit-type))
2131 (unless (string-match (concat "\\`[ \t]*\\("
2132 c-comment-prefix-regexp
2133 "\\)[ \t]*\\'")
2134 (car fill))
2135 ;; Oops, the prefix doesn't match the comment prefix
2136 ;; regexp. This could produce very confusing
2137 ;; results with adaptive fill packages together with
2138 ;; the insert prefix magic below, since the prefix
2139 ;; often doesn't appear at all. So let's warn about
2140 ;; it.
2141 (message "\
2142 Warning: `c-comment-prefix-regexp' doesn't match the comment prefix %S"
2143 (car fill)))
2144 ;; Find the right spot on the line, break it, insert
2145 ;; the fill prefix and make sure we're back in the
2146 ;; same column by temporarily prefixing the first word
2147 ;; with a number of 'x'.
2148 (save-excursion
2149 (goto-char (car lit-limits))
2150 (if (looking-at (if (eq lit-type 'c++)
2151 c-comment-prefix-regexp
2152 comment-start-skip))
2153 (goto-char (match-end 0))
2154 (forward-char 2)
2155 (skip-chars-forward " \t"))
2156 (while (< (current-column) (cdr fill)) (forward-char 1))
2157 (let ((col (current-column)))
2158 (setq beg (1+ (point))
2159 tmp-pre (list (point)))
2160 (unwind-protect
2161 (progn
2162 (insert ?\n (car fill))
2163 (insert (make-string (- col (current-column)) ?x)))
2164 (setcdr tmp-pre (point))))))
2165 (when beg
2166 (let ((fill-paragraph-function
2167 ;; Avoid infinite recursion.
2168 (if (not (eq fill-paragraph-function 'c-fill-paragraph))
2169 fill-paragraph-function))
2170 (fill-prefix
2171 (or fill-prefix
2172 (when (and (eq lit-type 'c++)
2173 (not (string-match
2174 "\\`[ \t]*//"
2175 (or (fill-context-prefix beg end)
2176 ""))))
2177 ;; Kludge: If the function that adapts the
2178 ;; fill prefix doesn't produce the required
2179 ;; comment starter for line comments, then
2180 ;; force it by setting fill-prefix.
2181 (car (or fill (c-guess-fill-prefix
2182 lit-limits lit-type)))))))
2183 ;; Preparations finally done! Now we can call the
2184 ;; real fill function.
2185 (save-restriction
2186 (narrow-to-region beg end)
2187 (fill-paragraph arg)))))
2188 (when (consp tmp-pre)
2189 (delete-region (car tmp-pre) (cdr tmp-pre)))
2190 (when tmp-post
2191 (save-excursion
2192 (goto-char tmp-post)
2193 (delete-char 1)
2194 (when hang-ender-stuck
2195 (skip-syntax-backward "^w ")
2196 (forward-char (- hang-ender-stuck))
2197 (insert (make-string hang-ender-stuck ?\ ))
2198 (delete-char hang-ender-stuck))
2199 (set-marker tmp-post nil)))))
2200 (set-marker end nil))
2201 ;; Always return t. This has the effect that if filling isn't done
2202 ;; above, it isn't done at all, and it's therefore effectively
2203 ;; disabled in normal code.
2204 t)
2205
2206 (defun c-do-auto-fill ()
2207 ;; Do automatic filling if not inside a context where it should be
2208 ;; ignored.
2209 (let ((c-auto-fill-prefix
2210 ;; The decision whether the line should be broken is actually
2211 ;; done in c-indent-new-comment-line, which do-auto-fill
2212 ;; calls to break lines. We just set this special variable
2213 ;; so that we'll know when we're called from there. It's
2214 ;; also used to detect whether fill-prefix is user set or
2215 ;; generated automatically by do-auto-fill.
2216 fill-prefix))
2217 (do-auto-fill)))
2218
2219 (defun c-indent-new-comment-line (&optional soft)
2220 "Break line at point and indent, continuing comment if within one.
2221 If inside a comment and `comment-multi-line' is non-nil, the
2222 indentation and line prefix are preserved (see the
2223 `c-comment-prefix-regexp' and `c-block-comment-prefix' variables for
2224 details). If inside a comment and `comment-multi-line' is nil, a new
2225 comment of the same type is started on the next line and indented as
2226 appropriate for comments.
2227
2228 If a fill prefix is specified, it overrides all the above."
2229 (interactive)
2230 (let ((fill-prefix fill-prefix)
2231 (do-line-break
2232 (lambda ()
2233 (delete-region (progn (skip-chars-backward " \t") (point))
2234 (progn (skip-chars-forward " \t") (point)))
2235 (if soft (insert-and-inherit ?\n) (newline 1))))
2236 ;; Already know the literal type and limits when called from
2237 ;; c-context-line-break.
2238 (c-lit-limits (if (boundp 'c-lit-limits) c-lit-limits))
2239 (c-lit-type (if (boundp 'c-lit-type) c-lit-type)))
2240 (when (boundp 'c-auto-fill-prefix)
2241 ;; Called from do-auto-fill.
2242 (unless c-lit-limits
2243 (setq c-lit-limits (c-literal-limits nil nil t)))
2244 (unless c-lit-type
2245 (setq c-lit-type (c-literal-type c-lit-limits)))
2246 (if (memq (cond ((eq c-lit-type 'pound)
2247 ;; Come to think about it, "pound" is a bit
2248 ;; of a misnomer, so call it "cpp" instead
2249 ;; in user interaction.
2250 'cpp)
2251 ((null c-lit-type) 'code)
2252 (t c-lit-type))
2253 c-ignore-auto-fill)
2254 (setq fill-prefix t) ; Used as flag in the cond.
2255 (if (null c-auto-fill-prefix)
2256 (setq fill-prefix nil))))
2257 (cond ((eq fill-prefix t)
2258 ;; A call from do-auto-fill which should be ignored.
2259 )
2260 (fill-prefix
2261 ;; A fill-prefix overrides anything.
2262 (funcall do-line-break)
2263 (insert-and-inherit fill-prefix))
2264 ((progn
2265 (unless c-lit-limits
2266 (setq c-lit-limits (c-literal-limits nil nil t)))
2267 (unless c-lit-type
2268 (setq c-lit-type (c-literal-type c-lit-limits)))
2269 (memq c-lit-type '(c c++)))
2270 (if comment-multi-line
2271 ;; Inside a comment that should be continued.
2272 (let ((fill (c-guess-fill-prefix
2273 (setq c-lit-limits
2274 (c-collect-line-comments c-lit-limits))
2275 c-lit-type))
2276 (pos (point)))
2277 (if (save-excursion
2278 (back-to-indentation)
2279 (> (point) (car c-lit-limits))
2280 (looking-at c-comment-prefix-regexp))
2281 (progn
2282 ;; Skip forward past the fill prefix in case
2283 ;; we're standing in it.
2284 (while (and (< (current-column) (cdr fill))
2285 (not (eolp)))
2286 (forward-char 1))
2287 (if (> (point) (if (and (eq c-lit-type 'c)
2288 (save-excursion
2289 (forward-char -2)
2290 (looking-at "\\*/")))
2291 (- (cdr c-lit-limits) 2)
2292 (cdr c-lit-limits)))
2293 (progn
2294 ;; The skip takes us out of the comment;
2295 ;; insert the fill prefix at bol instead
2296 ;; and keep the position.
2297 (setq pos (copy-marker pos t))
2298 (beginning-of-line)
2299 (insert-and-inherit (car fill))
2300 (if soft (insert-and-inherit ?\n) (newline 1))
2301 (goto-char pos)
2302 (set-marker pos nil))
2303 (funcall do-line-break)
2304 (insert-and-inherit (car fill))))
2305 (funcall do-line-break)
2306 (insert-and-inherit (car fill))))
2307 ;; Inside a comment that should be broken.
2308 (let ((comment-start comment-start)
2309 (comment-end comment-end)
2310 col)
2311 (if (eq c-lit-type 'c)
2312 (unless (string-match "[ \t]*/\\*" comment-start)
2313 (setq comment-start "/* " comment-end " */"))
2314 (unless (string-match "[ \t]*//" comment-start)
2315 (setq comment-start "// " comment-end "")))
2316 (setq col (save-excursion
2317 (back-to-indentation)
2318 (current-column)))
2319 (funcall do-line-break)
2320 (when (and comment-end (not (equal comment-end "")))
2321 (forward-char -1)
2322 (insert-and-inherit comment-end)
2323 (forward-char 1))
2324 ;; c-comment-indent may look at the current
2325 ;; indentation, so let's start out with the same
2326 ;; indentation as the previous one.
2327 (indent-to col)
2328 (insert-and-inherit comment-start)
2329 (indent-for-comment))))
2330 (t
2331 ;; Somewhere else in the code.
2332 (let ((col (save-excursion
2333 (while (progn (back-to-indentation)
2334 (and (looking-at "^\\s *$")
2335 (= (forward-line -1) 0))))
2336 (current-column))))
2337 (funcall do-line-break)
2338 (indent-to col))))))
2339
2340 (defalias 'c-comment-line-break-function 'c-indent-new-comment-line)
2341 (make-obsolete 'c-comment-line-break-function 'c-indent-new-comment-line)
2342
2343 ;; advice for indent-new-comment-line for older Emacsen
2344 (unless (boundp 'comment-line-break-function)
2345 (defadvice indent-new-comment-line (around c-line-break-advice
2346 activate preactivate)
2347 "Call `c-indent-new-comment-line' if in CC Mode."
2348 (if (or (boundp 'c-inside-line-break-advice)
2349 (not c-buffer-is-cc-mode))
2350 ad-do-it
2351 (let (c-inside-line-break-advice)
2352 (c-indent-new-comment-line (ad-get-arg 0))))))
2353
2354 (defun c-context-line-break ()
2355 "Do a line break suitable to the context.
2356
2357 When point is outside a comment, insert a newline and indent according
2358 to the syntactic context.
2359
2360 When point is inside a comment, continue it with the appropriate
2361 comment prefix (see the `c-comment-prefix-regexp' and
2362 `c-block-comment-prefix' variables for details). The end of a
2363 C++-style line comment doesn't count as inside the comment, though."
2364 (interactive "*")
2365 (let* ((c-lit-limits (c-literal-limits nil nil t))
2366 (c-lit-type (c-literal-type c-lit-limits)))
2367 (if (or (eq c-lit-type 'c)
2368 (and (eq c-lit-type 'c++)
2369 (< (point)
2370 (1- (cdr (setq c-lit-limits
2371 (c-collect-line-comments c-lit-limits)))))))
2372 (let ((comment-multi-line t)
2373 (fill-prefix nil))
2374 (c-indent-new-comment-line))
2375 (delete-region (point) (progn (skip-chars-backward " \t") (point)))
2376 (newline)
2377 ;; c-indent-line may look at the current indentation, so let's
2378 ;; start out with the same indentation as the previous line.
2379 (let ((col (save-excursion
2380 (forward-line -1)
2381 (while (progn (back-to-indentation)
2382 (and (looking-at "^\\s *$")
2383 (= (forward-line -1) 0))))
2384 (current-column))))
2385 (indent-to col))
2386 (c-indent-line))))
2387
2388 \f
2389 (provide 'cc-cmds)
2390 ;;; cc-cmds.el ends here