]> code.delx.au - gnu-emacs/blob - lisp/progmodes/cc-cmds.el
(Info-default-directory-list): Add sysdir last.
[gnu-emacs] / lisp / progmodes / cc-cmds.el
1 ;;; cc-cmds.el --- user level commands for CC Mode
2
3 ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
4
5 ;; Authors: 1992-1997 Barry A. Warsaw
6 ;; 1987 Dave Detlefs and Stewart Clamen
7 ;; 1985 Richard M. Stallman
8 ;; Maintainer: cc-mode-help@python.org
9 ;; Created: 22-Apr-1997 (split from cc-mode.el)
10 ;; Version: See cc-mode.el
11 ;; Keywords: c languages oop
12
13 ;; This file is part of GNU Emacs.
14
15 ;; GNU Emacs is free software; you can redistribute it and/or modify
16 ;; it under the terms of the GNU General Public License as published by
17 ;; the Free Software Foundation; either version 2, or (at your option)
18 ;; any later version.
19
20 ;; GNU Emacs is distributed in the hope that it will be useful,
21 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 ;; GNU General Public License for more details.
24
25 ;; You should have received a copy of the GNU General Public License
26 ;; along with GNU Emacs; see the file COPYING. If not, write to the
27 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28 ;; Boston, MA 02111-1307, USA.
29
30
31 \f
32 (defun c-calculate-state (arg prevstate)
33 ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
34 ;; arg is nil or zero, toggle the state. If arg is negative, turn
35 ;; the state off, and if arg is positive, turn the state on
36 (if (or (not arg)
37 (zerop (setq arg (prefix-numeric-value arg))))
38 (not prevstate)
39 (> arg 0)))
40
41 ;; Auto-newline and hungry-delete
42 (defun c-toggle-auto-state (arg)
43 "Toggle auto-newline feature.
44 Optional numeric ARG, if supplied turns on auto-newline when positive,
45 turns it off when negative, and just toggles it when zero.
46
47 When the auto-newline feature is enabled (as evidenced by the `/a' or
48 `/ah' on the modeline after the mode name) newlines are automatically
49 inserted after special characters such as brace, comma, semi-colon,
50 and colon."
51 (interactive "P")
52 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
53 (c-update-modeline)
54 (c-keep-region-active))
55
56 (defun c-toggle-hungry-state (arg)
57 "Toggle hungry-delete-key feature.
58 Optional numeric ARG, if supplied turns on hungry-delete when positive,
59 turns it off when negative, and just toggles it when zero.
60
61 When the hungry-delete-key feature is enabled (as evidenced by the
62 `/h' or `/ah' on the modeline after the mode name) the delete key
63 gobbles all preceding whitespace in one fell swoop."
64 (interactive "P")
65 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
66 (c-update-modeline)
67 (c-keep-region-active))
68
69 (defun c-toggle-auto-hungry-state (arg)
70 "Toggle auto-newline and hungry-delete-key features.
71 Optional numeric ARG, if supplied turns on auto-newline and
72 hungry-delete when positive, turns them off when negative, and just
73 toggles them when zero.
74
75 See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
76 (interactive "P")
77 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
78 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
79 (c-update-modeline)
80 (c-keep-region-active))
81
82 \f
83 ;; Electric keys
84
85 ;; Note: In XEmacs 20.3 the Delete and BackSpace keysyms have been
86 ;; separated and "\177" is no longer an alias for both keys. Also,
87 ;; the variable delete-key-deletes-forward controls in which direction
88 ;; the Delete keysym deletes characters. The functions
89 ;; c-electric-delete and c-electric-backspace attempt to deal with
90 ;; this new functionality. For Emacs 19 and XEmacs 19 backwards
91 ;; compatibility, the old behavior has moved to c-electric-backspace
92 ;; and c-backspace-function.
93
94 (defun c-electric-backspace (arg)
95 "Deletes preceding character or whitespace.
96 If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
97 \"/ah\" string on the mode line, then all preceding whitespace is
98 consumed. If however an ARG is supplied, or `c-hungry-delete-key' is
99 nil, or point is inside a literal then the function in the variable
100 `c-backspace-function' is called.
101
102 See also \\[c-electric-delete]."
103 (interactive "*P")
104 (if (or (not c-hungry-delete-key)
105 arg
106 (c-in-literal))
107 (funcall c-backspace-function (prefix-numeric-value arg))
108 (let ((here (point)))
109 (skip-chars-backward " \t\n")
110 (if (/= (point) here)
111 (delete-region (point) here)
112 (funcall c-backspace-function 1)
113 ))))
114
115 (defun c-electric-delete (arg)
116 "Deletes preceding or following character or whitespace.
117
118 The behavior of this function depends on the variable
119 `delete-key-deletes-forward'. If this variable is nil (or does not
120 exist, as in older Emacsen), then this function behaves identical to
121 \\[c-electric-backspace].
122
123 If `delete-key-deletes-forward' is non-nil and is supported in your
124 Emacs, then deletion occurs in the forward direction. So if
125 `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
126 \"/ah\" string on the mode line, then all following whitespace is
127 consumed. If however an ARG is supplied, or `c-hungry-delete-key' is
128 nil, or point is inside a literal then the function in the variable
129 `c-delete-function' is called."
130 (interactive "*P")
131 (if (and (boundp 'delete-key-deletes-forward)
132 delete-key-deletes-forward)
133 (if (or (not c-hungry-delete-key)
134 arg
135 (c-in-literal))
136 (funcall c-delete-function (prefix-numeric-value arg))
137 (let ((here (point)))
138 (skip-chars-forward " \t\n")
139 (if (/= (point) here)
140 (delete-region (point) here)
141 (funcall c-delete-function 1))))
142 ;; act just like c-electric-backspace
143 (c-electric-backspace arg)))
144
145 (defun c-electric-pound (arg)
146 "Electric pound (`#') insertion.
147 Inserts a `#' character specially depending on the variable
148 `c-electric-pound-behavior'. If a numeric ARG is supplied, or if
149 point is inside a literal, nothing special happens."
150 (interactive "*P")
151 (if (or (c-in-literal)
152 arg
153 (not (memq 'alignleft c-electric-pound-behavior)))
154 ;; do nothing special
155 (self-insert-command (prefix-numeric-value arg))
156 ;; place the pound character at the left edge
157 (let ((pos (- (point-max) (point)))
158 (bolp (bolp)))
159 (beginning-of-line)
160 (delete-horizontal-space)
161 (insert-char last-command-char 1)
162 (and (not bolp)
163 (goto-char (- (point-max) pos)))
164 )))
165
166 (defun c-electric-brace (arg)
167 "Insert a brace.
168
169 If the auto-newline feature is turned on, as evidenced by the \"/a\"
170 or \"/ah\" string on the mode line, newlines are inserted before and
171 after braces based on the value of `c-hanging-braces-alist'.
172
173 Also, the line is re-indented unless a numeric ARG is supplied, there
174 are non-whitespace characters present on the line after the brace, or
175 the brace is inserted inside a literal."
176 (interactive "*P")
177 (let* ((c-state-cache (c-parse-state))
178 (safepos (c-safe-position (point) c-state-cache))
179 (literal (c-in-literal safepos)))
180 ;; if we're in a literal, or we're not at the end of the line, or
181 ;; a numeric arg is provided, or auto-newlining is turned off,
182 ;; then just insert the character.
183 (if (or literal arg
184 ; (not c-auto-newline)
185 (not (looking-at "[ \t]*$")))
186 (self-insert-command (prefix-numeric-value arg))
187 (let* ((syms
188 ;; This is the list of brace syntactic symbols that can
189 ;; hang. If any new ones are added to c-offsets-alist,
190 ;; they should be added here as well.
191 '(class-open class-close defun-open defun-close
192 inline-open inline-close
193 brace-list-open brace-list-close
194 brace-list-intro brace-list-entry
195 block-open block-close
196 substatement-open statement-case-open
197 extern-lang-open extern-lang-close
198 namespace-open namespace-close
199 ))
200 ;; we want to inhibit blinking the paren since this will
201 ;; be most disruptive. we'll blink it ourselves later on
202 (old-blink-paren blink-paren-function)
203 blink-paren-function
204 (insertion-point (point))
205 delete-temp-newline
206 (preserve-p (and (not (bobp))
207 (eq ?\ (char-syntax (char-before)))))
208 ;; shut this up too
209 (c-echo-syntactic-information-p nil)
210 (syntax (progn
211 ;; only insert a newline if there is
212 ;; non-whitespace behind us
213 (if (save-excursion
214 (skip-chars-backward " \t")
215 (not (bolp)))
216 (progn (newline)
217 (setq delete-temp-newline t)))
218 (self-insert-command (prefix-numeric-value arg))
219 ;; state cache doesn't change
220 (c-guess-basic-syntax)))
221 (newlines (and
222 c-auto-newline
223 (or (c-lookup-lists syms syntax c-hanging-braces-alist)
224 '(ignore before after)))))
225 ;; If syntax is a function symbol, then call it using the
226 ;; defined semantics.
227 (if (and (not (consp (cdr newlines)))
228 (functionp (cdr newlines)))
229 (let ((c-syntactic-context syntax))
230 (setq newlines
231 (funcall (cdr newlines) (car newlines) insertion-point))))
232 ;; does a newline go before the open brace?
233 (if (memq 'before newlines)
234 ;; we leave the newline we've put in there before,
235 ;; but we need to re-indent the line above
236 (let ((pos (- (point-max) (point)))
237 (here (point))
238 (c-state-cache c-state-cache))
239 (forward-line -1)
240 ;; we may need to update the cache. this should still be
241 ;; faster than recalculating the state in many cases
242 (save-excursion
243 (save-restriction
244 (narrow-to-region here (point))
245 (if (and (c-safe (progn (backward-up-list -1) t))
246 (memq (char-before) '(?\) ?}))
247 (progn (widen)
248 (c-safe (progn (forward-sexp -1) t))))
249 (setq c-state-cache
250 (c-hack-state (point) 'open c-state-cache))
251 (if (and (car c-state-cache)
252 (not (consp (car c-state-cache)))
253 (<= (point) (car c-state-cache)))
254 (setq c-state-cache (cdr c-state-cache))
255 ))))
256 (let ((here (point))
257 (shift (c-indent-line)))
258 (setq c-state-cache (c-adjust-state (c-point 'bol) here
259 (- shift) c-state-cache)))
260 (goto-char (- (point-max) pos))
261 ;; if the buffer has changed due to the indentation, we
262 ;; need to recalculate syntax for the current line, but
263 ;; we won't need to update the state cache.
264 (if (/= (point) here)
265 (setq syntax (c-guess-basic-syntax))))
266 ;; must remove the newline we just stuck in (if we really did it)
267 (and delete-temp-newline
268 (save-excursion
269 ;; if there is whitespace before point, then preserve
270 ;; at least one space.
271 (delete-indentation)
272 (just-one-space)
273 (if (not preserve-p)
274 (delete-char -1))))
275 ;; since we're hanging the brace, we need to recalculate
276 ;; syntax. Update the state to accurately reflect the
277 ;; beginning of the line. We punt if we cross any open or
278 ;; closed parens because its just too hard to modify the
279 ;; known state. This limitation will be fixed in v5.
280 (save-excursion
281 (let ((bol (c-point 'bol)))
282 (if (zerop (car (parse-partial-sexp bol (1- (point)))))
283 (setq c-state-cache (c-whack-state bol c-state-cache)
284 syntax (c-guess-basic-syntax))
285 ;; gotta punt. this requires some horrible kludgery
286 (beginning-of-line)
287 (makunbound 'c-state-cache)
288 (setq c-state-cache (c-parse-state)
289 syntax nil))))
290 )
291 ;; now adjust the line's indentation. don't update the state
292 ;; cache since c-guess-basic-syntax isn't called when the
293 ;; syntax is passed to c-indent-line
294 (let ((here (point))
295 (shift (c-indent-line syntax)))
296 (setq c-state-cache (c-adjust-state (c-point 'bol) here
297 (- shift) c-state-cache)))
298 ;; Do all appropriate clean ups
299 (let ((here (point))
300 (pos (- (point-max) (point)))
301 mbeg mend)
302 ;; clean up empty defun braces
303 (if (and c-auto-newline
304 (memq 'empty-defun-braces c-cleanup-list)
305 (eq last-command-char ?\})
306 (c-intersect-lists '(defun-close class-close inline-close)
307 syntax)
308 (progn
309 (forward-char -1)
310 (skip-chars-backward " \t\n")
311 (eq (char-before) ?\{))
312 ;; make sure matching open brace isn't in a comment
313 (not (c-in-literal)))
314 (delete-region (point) (1- here)))
315 ;; clean up brace-else-brace
316 (if (and c-auto-newline
317 (memq 'brace-else-brace c-cleanup-list)
318 (eq last-command-char ?\{)
319 (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
320 (progn
321 (setq mbeg (match-beginning 0)
322 mend (match-end 0))
323 (= mend here))
324 (not (c-in-literal)))
325 (progn
326 (delete-region mbeg mend)
327 (insert "} else {")))
328 ;; clean up brace-elseif-brace
329 (if (and c-auto-newline
330 (memq 'brace-elseif-brace c-cleanup-list)
331 (eq last-command-char ?\{)
332 (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*" nil t)
333 (save-excursion
334 (goto-char (match-end 0))
335 (c-safe (forward-sexp 1))
336 (skip-chars-forward " \t\n")
337 (setq mbeg (match-beginning 0)
338 mend (match-end 0))
339 (= here (1+ (point))))
340 (not (c-in-literal)))
341 (progn
342 (delete-region mbeg mend)
343 (insert "} else if ")))
344 (goto-char (- (point-max) pos))
345 )
346 ;; does a newline go after the brace?
347 (if (memq 'after newlines)
348 (progn
349 (newline)
350 ;; update on c-state-cache
351 (let* ((bufpos (- (point) 2))
352 (which (if (eq (char-after bufpos) ?{) 'open 'close))
353 (c-state-cache (c-hack-state bufpos which c-state-cache)))
354 (c-indent-line))))
355 ;; blink the paren
356 (and (eq last-command-char ?\})
357 old-blink-paren
358 (save-excursion
359 (c-backward-syntactic-ws safepos)
360 (funcall old-blink-paren)))
361 ))))
362
363 (defun c-electric-slash (arg)
364 "Insert a slash character.
365
366 Indent the line as a comment, if:
367
368 1. The slash is second of a `//' line oriented comment introducing
369 token and we are on a comment-only-line, or
370
371 2. The slash is part of a `*/' token that closes a block oriented
372 comment.
373
374 If numeric ARG is supplied or point is inside a literal, indentation
375 is inhibited."
376 (interactive "*P")
377 (let* ((ch (char-before))
378 (indentp (and (not arg)
379 (eq last-command-char ?/)
380 (or (and (eq ch ?/)
381 (not (c-in-literal)))
382 (and (eq ch ?*)
383 (c-in-literal)))
384 ))
385 ;; shut this up
386 (c-echo-syntactic-information-p nil))
387 (self-insert-command (prefix-numeric-value arg))
388 (if indentp
389 (c-indent-line))))
390
391 (defun c-electric-star (arg)
392 "Insert a star character.
393 If the star is the second character of a C style comment introducing
394 construct, and we are on a comment-only-line, indent line as comment.
395 If numeric ARG is supplied or point is inside a literal, indentation
396 is inhibited."
397 (interactive "*P")
398 (self-insert-command (prefix-numeric-value arg))
399 ;; if we are in a literal, or if arg is given do not re-indent the
400 ;; current line, unless this star introduces a comment-only line.
401 (if (and (not arg)
402 (memq (c-in-literal) '(c))
403 (eq (char-before) ?*)
404 (save-excursion
405 (forward-char -1)
406 (skip-chars-backward "*")
407 (if (eq (char-before) ?/)
408 (forward-char -1))
409 (skip-chars-backward " \t")
410 (bolp)))
411 ;; shut this up
412 (let (c-echo-syntactic-information-p)
413 (c-indent-line))
414 ))
415
416 (defun c-electric-semi&comma (arg)
417 "Insert a comma or semicolon.
418 When the auto-newline feature is turned on, as evidenced by the \"/a\"
419 or \"/ah\" string on the mode line, a newline might be inserted. See
420 the variable `c-hanging-semi&comma-criteria' for how newline insertion
421 is determined.
422
423 When semicolon is inserted, the line is re-indented unless a numeric
424 arg is supplied, point is inside a literal, or there are
425 non-whitespace characters on the line following the semicolon."
426 (interactive "*P")
427 (let* ((lim (c-most-enclosing-brace (c-parse-state)))
428 (literal (c-in-literal lim))
429 (here (point))
430 ;; shut this up
431 (c-echo-syntactic-information-p nil))
432 (if (or literal
433 arg
434 (not (looking-at "[ \t]*$")))
435 (self-insert-command (prefix-numeric-value arg))
436 ;; do some special stuff with the character
437 (self-insert-command (prefix-numeric-value arg))
438 ;; do all cleanups, reindentations, and newline insertions, but
439 ;; only if c-auto-newline is turned on
440 (if (not c-auto-newline) nil
441 ;; clean ups
442 (let ((pos (- (point-max) (point))))
443 (if (and (or (and
444 (eq last-command-char ?,)
445 (memq 'list-close-comma c-cleanup-list))
446 (and
447 (eq last-command-char ?\;)
448 (memq 'defun-close-semi c-cleanup-list)))
449 (progn
450 (forward-char -1)
451 (skip-chars-backward " \t\n")
452 (eq (char-before) ?}))
453 ;; make sure matching open brace isn't in a comment
454 (not (c-in-literal lim)))
455 (delete-region (point) here))
456 (goto-char (- (point-max) pos)))
457 ;; re-indent line
458 (c-indent-line)
459 ;; check to see if a newline should be added
460 (let ((criteria c-hanging-semi&comma-criteria)
461 answer add-newline-p)
462 (while criteria
463 (setq answer (funcall (car criteria)))
464 ;; only nil value means continue checking
465 (if (not answer)
466 (setq criteria (cdr criteria))
467 (setq criteria nil)
468 ;; only 'stop specifically says do not add a newline
469 (setq add-newline-p (not (eq answer 'stop)))
470 ))
471 (if add-newline-p
472 (progn (newline)
473 (c-indent-line)))
474 )))))
475
476 (defun c-electric-colon (arg)
477 "Insert a colon.
478
479 If the auto-newline feature is turned on, as evidenced by the \"/a\"
480 or \"/ah\" string on the mode line, newlines are inserted before and
481 after colons based on the value of `c-hanging-colons-alist'.
482
483 Also, the line is re-indented unless a numeric ARG is supplied, there
484 are non-whitespace characters present on the line after the colon, or
485 the colon is inserted inside a literal.
486
487 This function cleans up double colon scope operators based on the
488 value of `c-cleanup-list'."
489 (interactive "*P")
490 (let* ((bod (c-point 'bod))
491 (literal (c-in-literal bod))
492 syntax newlines is-scope-op
493 ;; shut this up
494 (c-echo-syntactic-information-p nil))
495 (if (or literal
496 arg
497 (not (looking-at "[ \t]*$")))
498 (self-insert-command (prefix-numeric-value arg))
499 ;; insert the colon, then do any specified cleanups
500 (self-insert-command (prefix-numeric-value arg))
501 (let ((pos (- (point-max) (point)))
502 (here (point)))
503 (if (and c-auto-newline
504 (memq 'scope-operator c-cleanup-list)
505 (eq (char-before) ?:)
506 (progn
507 (forward-char -1)
508 (skip-chars-backward " \t\n")
509 (eq (char-before) ?:))
510 (not (c-in-literal))
511 (not (eq (char-after (- (point) 2)) ?:)))
512 (progn
513 (delete-region (point) (1- here))
514 (setq is-scope-op t)))
515 (goto-char (- (point-max) pos)))
516 ;; lets do some special stuff with the colon character
517 (setq syntax (c-guess-basic-syntax)
518 ;; some language elements can only be determined by
519 ;; checking the following line. Lets first look for ones
520 ;; that can be found when looking on the line with the
521 ;; colon
522 newlines
523 (and c-auto-newline
524 (or (c-lookup-lists '(case-label label access-label)
525 syntax c-hanging-colons-alist)
526 (c-lookup-lists '(member-init-intro inher-intro)
527 (prog2
528 (insert "\n")
529 (c-guess-basic-syntax)
530 (delete-char -1))
531 c-hanging-colons-alist))))
532 ;; indent the current line
533 (c-indent-line syntax)
534 ;; does a newline go before the colon? Watch out for already
535 ;; non-hung colons. However, we don't unhang them because that
536 ;; would be a cleanup (and anti-social).
537 (if (and (memq 'before newlines)
538 (not is-scope-op)
539 (save-excursion
540 (skip-chars-backward ": \t")
541 (not (bolp))))
542 (let ((pos (- (point-max) (point))))
543 (forward-char -1)
544 (newline)
545 (c-indent-line)
546 (goto-char (- (point-max) pos))))
547 ;; does a newline go after the colon?
548 (if (and (memq 'after (cdr-safe newlines))
549 (not is-scope-op))
550 (progn
551 (newline)
552 (c-indent-line)))
553 )))
554
555 (defun c-electric-lt-gt (arg)
556 "Insert a less-than, or greater-than character.
557 When the auto-newline feature is turned on, as evidenced by the \"/a\"
558 or \"/ah\" string on the mode line, the line will be re-indented if
559 the character inserted is the second of a C++ style stream operator
560 and the buffer is in C++ mode.
561
562 The line will also not be re-indented if a numeric argument is
563 supplied, or point is inside a literal."
564 (interactive "*P")
565 (let ((indentp (and (not arg)
566 (eq (char-before) last-command-char)
567 (not (c-in-literal))))
568 ;; shut this up
569 (c-echo-syntactic-information-p nil))
570 (self-insert-command (prefix-numeric-value arg))
571 (if indentp
572 (c-indent-line))))
573
574
575 \f
576 ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
577 ;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com
578 (defun c-forward-into-nomenclature (&optional arg)
579 "Move forward to end of a nomenclature section or word.
580 With arg, to it arg times."
581 (interactive "p")
582 (let ((case-fold-search nil))
583 (if (> arg 0)
584 (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg)
585 (while (and (< arg 0)
586 (re-search-backward
587 "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)"
588 (point-min) 0))
589 (forward-char 1)
590 (setq arg (1+ arg)))))
591 (c-keep-region-active))
592
593 (defun c-backward-into-nomenclature (&optional arg)
594 "Move backward to beginning of a nomenclature section or word.
595 With optional ARG, move that many times. If ARG is negative, move
596 forward."
597 (interactive "p")
598 (c-forward-into-nomenclature (- arg))
599 (c-keep-region-active))
600
601 (defun c-scope-operator ()
602 "Insert a double colon scope operator at point.
603 No indentation or other \"electric\" behavior is performed."
604 (interactive "*")
605 (insert "::"))
606
607 (defun c-beginning-of-defun (&optional arg)
608 "Move backward to the beginning of a defun.
609 With argument, do it that many times. Negative arg -N
610 means move forward to Nth following beginning of defun.
611 Returns t unless search stops due to beginning or end of buffer.
612
613 Unlike the built-in `beginning-of-defun' this tries to be smarter
614 about finding the char with open-parenthesis syntax that starts the
615 defun."
616 (interactive "p")
617 (if (< arg 0)
618 (c-end-of-defun (- arg))
619 (while (> arg 0)
620 (let ((state (nreverse (c-parse-state)))
621 prevbod bod)
622 (while (and state (not bod))
623 (setq bod (car state)
624 state (cdr state))
625 (if (consp bod)
626 (setq prevbod (car bod)
627 bod nil)))
628 (cond
629 (bod (goto-char bod))
630 (prevbod (goto-char prevbod))
631 (t (goto-char (c-point 'bod)))))
632 (setq arg (1- arg))))
633 (c-keep-region-active))
634
635 (defun c-end-of-defun (&optional arg)
636 "Move forward to next end of defun. With argument, do it that many times.
637 Negative argument -N means move back to Nth preceding end of defun.
638
639 An end of a defun occurs right after the close-parenthesis that matches
640 the open-parenthesis that starts a defun; see `beginning-of-defun'."
641 (interactive "p")
642 (if (< arg 0)
643 (c-beginning-of-defun (- arg))
644 (while (> arg 0)
645 ;; skip down into the next defun-block
646 (while (and (c-safe (down-list 1) t)
647 (not (eq (char-before) ?{)))
648 (forward-char -1)
649 (forward-sexp))
650 (c-beginning-of-defun 1)
651 (forward-sexp 1)
652 (setq arg (1- arg)))
653 (forward-line 1))
654 (c-keep-region-active))
655
656 \f
657 (defun c-beginning-of-statement (&optional count lim sentence-flag)
658 "Go to the beginning of the innermost C statement.
659 With prefix arg, go back N - 1 statements. If already at the
660 beginning of a statement then go to the beginning of the closest
661 preceding one, moving into nested blocks if necessary (use
662 \\[backward-sexp] to skip over a block). If within a comment, or next
663 to a comment (only whitespace between), move by sentences instead of
664 statements.
665
666 When called from a program, this function takes 3 optional args: the
667 repetition count, a buffer position limit which is the farthest back
668 to search, and a flag saying whether to do sentence motion when in a
669 comment."
670 (interactive (list (prefix-numeric-value current-prefix-arg)
671 nil t))
672 (let* ((count (or count 1))
673 here
674 (range (c-collect-line-comments (c-literal-limits lim))))
675 (while (and (/= count 0)
676 (or (not lim) (> (point) lim)))
677 (setq here (point))
678 (if (and (not range) sentence-flag)
679 (save-excursion
680 ;; Find the comment next to point if we're not in one.
681 (if (> count 0)
682 ;; Finding a comment backwards is a bit cumbersome
683 ;; because `forward-comment' regards every newline as
684 ;; a comment when searching backwards (Emacs 19.34).
685 (while (and (progn (skip-chars-backward " \t")
686 (setq range (point))
687 (setq range (if (forward-comment -1)
688 (cons (point) range)
689 nil)))
690 (= (char-after) ?\n)))
691 (skip-chars-forward " \t\n")
692 (setq range (point))
693 (setq range (if (forward-comment 1)
694 (cons range (point))
695 nil)))
696 (setq range (c-collect-line-comments range))))
697 (if (and (< count 0) (= here (point-max)))
698 ;; Special case because eob might be in a literal.
699 (setq range nil))
700 (if range
701 (if (and sentence-flag
702 (/= (char-syntax (char-after (car range))) ?\"))
703 (progn
704 ;; move by sentence, but not past the limit of the literal
705 (save-restriction
706 (narrow-to-region (save-excursion
707 (goto-char (car range))
708 (looking-at comment-start-skip)
709 (goto-char (match-end 0))
710 (point))
711 (save-excursion
712 (goto-char (cdr range))
713 (if (save-excursion
714 (goto-char (car range))
715 (looking-at "/\\*"))
716 (backward-char 2))
717 (skip-chars-backward " \t\n")
718 (point)))
719 (c-safe (forward-sentence (if (> count 0) -1 1))))
720 ;; See if we should escape the literal.
721 (if (> count 0)
722 (if (< (point) here)
723 (setq count (1- count))
724 (goto-char (car range))
725 (setq range nil))
726 (if (> (point) here)
727 (setq count (1+ count))
728 (goto-char (cdr range))
729 (setq range nil))))
730 (goto-char (if (> count 0) (car range) (cdr range)))
731 (setq range nil))
732 ;; Below we do approximately the same as
733 ;; c-beginning-of-statement-1 and c-end-of-statement-1 and
734 ;; perhaps they should be changed, but that'd likely break a
735 ;; lot in cc-engine.
736 (goto-char here)
737 ;; Move out of any enclosing non-`{ }' parens.
738 (let ((last (point)))
739 (while (and (c-safe (progn (up-list 1) t))
740 (/= (char-before) ?\}))
741 (setq last (point)))
742 (goto-char last))
743 (if (> count 0)
744 (if (condition-case nil
745 ;; Stop before `{' and after `;', `{', `}' and
746 ;; `};' when not followed by `}', but on the other
747 ;; side of the syntactic ws. Also stop before
748 ;; `}', but only to catch comments. Move by sexps
749 ;; and move into `{ }', but not into any other
750 ;; other type of paren.
751 (catch 'done
752 (let (last)
753 (while t
754 (setq last (point))
755 (if (and (looking-at "[{}]")
756 (/= here last))
757 (throw 'done (= (char-after) ?{)))
758 (c-backward-syntactic-ws)
759 (cond ((bobp) ; Must handle bob specially.
760 (if (= here last)
761 (if (= last (point-min))
762 (throw 'done t)
763 (goto-char last)
764 (throw 'done nil))
765 (goto-char last)
766 (throw 'done t)))
767 ((progn (backward-char)
768 (looking-at "[;{}]"))
769 (if (or (= here last)
770 (= (char-after last) ?}))
771 (if (and (= (char-before) ?})
772 (= (char-after) ?\;))
773 (backward-char))
774 (goto-char last)
775 (throw 'done t)))
776 ((or (= (char-syntax (char-after)) ?\))
777 (= (char-syntax (char-after)) ?\"))
778 (forward-char)
779 (backward-sexp))
780 ))))
781 (error
782 (goto-char (point-min))
783 t))
784 (setq count (1- count)))
785 (if (condition-case nil
786 ;; Stop before `{' and `}' and after `;', `}' and
787 ;; `};'. Also stop after `{', but only to catch
788 ;; comments. Move by sexps and move into `{ }', but
789 ;; not into any other other type of paren.
790 (catch 'done
791 (let (last)
792 (while t
793 (setq last (point))
794 (c-forward-syntactic-ws)
795 (cond ((= (char-after) ?{)
796 (if (= here last)
797 (progn (forward-char)
798 (throw 'done nil))
799 (goto-char last)
800 (throw 'done t)))
801 ((and (= (char-after) ?})
802 (/= here last))
803 (goto-char last)
804 (throw 'done t))
805 ((looking-at ";\\|};?")
806 (goto-char (match-end 0))
807 (throw 'done t))
808 ((or (= (char-syntax (char-after)) ?\()
809 (= (char-syntax (char-after)) ?\"))
810 (forward-sexp))
811 (t
812 (forward-char))
813 ))))
814 (error
815 (goto-char (point-max))
816 t))
817 (setq count (1+ count)))))
818 ;; If we haven't moved we're near a buffer limit.
819 (when (= (point) here)
820 (goto-char (if (> count 0) (point-min) (point-max)))
821 (setq count 0)))
822 ;; its possible we've been left up-buf of lim
823 (if lim (goto-char (max (point) lim))))
824 (c-keep-region-active))
825
826 (defun c-end-of-statement (&optional count lim sentence-flag)
827 "Go to the end of the innermost C statement.
828 With prefix arg, go forward N - 1 statements. Move forward to the end
829 of the next statement if already at end, and move into nested blocks
830 \(use \\[forward-sexp] to skip over a block). If within a comment, or
831 next to a comment (only whitespace between), move by sentences instead
832 of statements.
833
834 When called from a program, this function takes 3 optional args: the
835 repetition count, a buffer position limit which is the farthest back
836 to search, and a flag saying whether to do sentence motion when in a
837 comment."
838 (interactive (list (prefix-numeric-value current-prefix-arg)
839 nil t))
840 (c-beginning-of-statement (- (or count 1)) lim sentence-flag)
841 (c-keep-region-active))
842
843 \f
844 ;; set up electric character functions to work with pending-del,
845 ;; (a.k.a. delsel) mode. All symbols get the t value except
846 ;; the functions which delete, which gets 'supersede.
847 (mapcar
848 (function
849 (lambda (sym)
850 (put sym 'delete-selection t) ; for delsel (Emacs)
851 (put sym 'pending-delete t))) ; for pending-del (XEmacs)
852 '(c-electric-pound
853 c-electric-brace
854 c-electric-slash
855 c-electric-star
856 c-electric-semi&comma
857 c-electric-lt-gt
858 c-electric-colon))
859 (put 'c-electric-delete 'delete-selection 'supersede) ; delsel
860 (put 'c-electric-delete 'pending-delete 'supersede) ; pending-del
861 (put 'c-electric-backspace 'delete-selection 'supersede) ; delsel
862 (put 'c-electric-backspace 'pending-delete 'supersede) ; pending-del
863
864 \f
865 ;; This is used by indent-for-comment to decide how much to indent a
866 ;; comment in C code based on its context.
867 (defun c-comment-indent ()
868 (if (looking-at (concat "^\\(" c-comment-start-regexp "\\)"))
869 0 ;Existing comment at bol stays there.
870 (let ((opoint (point))
871 placeholder)
872 (save-excursion
873 (beginning-of-line)
874 (cond
875 ;; CASE 1: A comment following a solitary close-brace should
876 ;; have only one space.
877 ((looking-at (concat "[ \t]*}[ \t]*\\($\\|"
878 c-comment-start-regexp
879 "\\)"))
880 (search-forward "}")
881 (1+ (current-column)))
882 ;; CASE 2: 2 spaces after #endif
883 ((or (looking-at "^#[ \t]*endif[ \t]*")
884 (looking-at "^#[ \t]*else[ \t]*"))
885 7)
886 ;; CASE 3: when comment-column is nil, calculate the offset
887 ;; according to c-offsets-alist. E.g. identical to hitting
888 ;; TAB.
889 ((and c-indent-comments-syntactically-p
890 (save-excursion
891 (skip-chars-forward " \t")
892 (or (looking-at comment-start)
893 (eolp))))
894 (let ((syntax (c-guess-basic-syntax)))
895 ;; BOGOSITY ALERT: if we're looking at the eol, its
896 ;; because indent-for-comment hasn't put the comment-start
897 ;; in the buffer yet. this will screw up the syntactic
898 ;; analysis so we kludge in the necessary info. Another
899 ;; kludge is that if we're at the bol, then we really want
900 ;; to ignore any anchoring as specified by
901 ;; c-comment-only-line-offset since it doesn't apply here.
902 (if (save-excursion
903 (beginning-of-line)
904 (skip-chars-forward " \t")
905 (eolp))
906 (c-add-syntax 'comment-intro))
907 (let ((c-comment-only-line-offset
908 (if (consp c-comment-only-line-offset)
909 c-comment-only-line-offset
910 (cons c-comment-only-line-offset
911 c-comment-only-line-offset))))
912 (apply '+ (mapcar 'c-get-offset syntax)))))
913 ;; CASE 4: use comment-column if previous line is a
914 ;; comment-only line indented to the left of comment-column
915 ((save-excursion
916 (beginning-of-line)
917 (and (not (bobp))
918 (forward-line -1))
919 (skip-chars-forward " \t")
920 (prog1
921 (looking-at c-comment-start-regexp)
922 (setq placeholder (point))))
923 (goto-char placeholder)
924 (if (< (current-column) comment-column)
925 comment-column
926 (current-column)))
927 ;; CASE 5: If comment-column is 0, and nothing but space
928 ;; before the comment, align it at 0 rather than 1.
929 ((progn
930 (goto-char opoint)
931 (skip-chars-backward " \t")
932 (and (= comment-column 0) (bolp)))
933 0)
934 ;; CASE 6: indent at comment column except leave at least one
935 ;; space.
936 (t (max (1+ (current-column))
937 comment-column))
938 )))))
939
940 \f
941 ;; for proposed new variable comment-line-break-function
942 (defun c-comment-line-break-function (&optional soft)
943 ;; we currently don't do anything with soft line breaks
944 (let ((literal (c-in-literal))
945 at-comment-col)
946 (cond
947 ((eq literal 'string))
948 ((or (not c-comment-continuation-stars)
949 (not literal))
950 (indent-new-comment-line soft))
951 (t (let ((here (point))
952 (leader c-comment-continuation-stars))
953 (back-to-indentation)
954 ;; comment could be hanging
955 (if (not (c-in-literal))
956 (progn
957 (forward-line 1)
958 (forward-comment -1)
959 (setq at-comment-col (= (current-column) comment-column))))
960 ;; are we looking at a block or lines style comment?
961 (if (and (looking-at (concat "\\(" c-comment-start-regexp
962 "\\)[ \t]+"))
963 (string-equal (match-string 1) "//"))
964 ;; line style
965 (setq leader (match-string 0)))
966 (goto-char here)
967 (delete-region (progn (skip-chars-backward " \t") (point))
968 (progn (skip-chars-forward " \t") (point)))
969 (newline)
970 ;; to avoid having an anchored comment that c-indent-line will
971 ;; trip up on
972 (insert " " leader)
973 (if at-comment-col
974 (indent-for-comment))
975 (c-indent-line))))))
976
977 ;; advice for indent-new-comment-line for older Emacsen
978 (if (boundp 'comment-line-break-function)
979 nil
980 (require 'advice)
981 (defadvice indent-new-comment-line (around c-line-break-advice activate)
982 (if (or (not c-buffer-is-cc-mode)
983 (not (c-in-literal))
984 (not c-comment-continuation-stars))
985 ad-do-it
986 (c-comment-line-break-function (ad-get-arg 0)))))
987
988 ;; used by outline-minor-mode
989 (defun c-outline-level ()
990 (save-excursion
991 (skip-chars-forward "\t ")
992 (current-column)))
993
994 \f
995 (defun c-up-conditional (count)
996 "Move back to the containing preprocessor conditional, leaving mark behind.
997 A prefix argument acts as a repeat count. With a negative argument,
998 move forward to the end of the containing preprocessor conditional.
999 When going backwards, `#elif' is treated like `#else' followed by
1000 `#if'. When going forwards, `#elif' is ignored."
1001 (interactive "p")
1002 (c-forward-conditional (- count) t)
1003 (c-keep-region-active))
1004
1005 (defun c-backward-conditional (count &optional up-flag)
1006 "Move back across a preprocessor conditional, leaving mark behind.
1007 A prefix argument acts as a repeat count. With a negative argument,
1008 move forward across a preprocessor conditional."
1009 (interactive "p")
1010 (c-forward-conditional (- count) up-flag)
1011 (c-keep-region-active))
1012
1013 (defun c-forward-conditional (count &optional up-flag)
1014 "Move forward across a preprocessor conditional, leaving mark behind.
1015 A prefix argument acts as a repeat count. With a negative argument,
1016 move backward across a preprocessor conditional."
1017 (interactive "p")
1018 (let* ((forward (> count 0))
1019 (increment (if forward -1 1))
1020 (search-function (if forward 're-search-forward 're-search-backward))
1021 (new))
1022 (save-excursion
1023 (while (/= count 0)
1024 (let ((depth (if up-flag 0 -1)) found)
1025 (save-excursion
1026 ;; Find the "next" significant line in the proper direction.
1027 (while (and (not found)
1028 ;; Rather than searching for a # sign that
1029 ;; comes at the beginning of a line aside from
1030 ;; whitespace, search first for a string
1031 ;; starting with # sign. Then verify what
1032 ;; precedes it. This is faster on account of
1033 ;; the fastmap feature of the regexp matcher.
1034 (funcall search-function
1035 "#[ \t]*\\(if\\|elif\\|endif\\)"
1036 nil t))
1037 (beginning-of-line)
1038 ;; Now verify it is really a preproc line.
1039 (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
1040 (let ((prev depth))
1041 ;; Update depth according to what we found.
1042 (beginning-of-line)
1043 (cond ((looking-at "[ \t]*#[ \t]*endif")
1044 (setq depth (+ depth increment)))
1045 ((looking-at "[ \t]*#[ \t]*elif")
1046 (if (and forward (= depth 0))
1047 (setq found (point))))
1048 (t (setq depth (- depth increment))))
1049 ;; If we are trying to move across, and we find an
1050 ;; end before we find a beginning, get an error.
1051 (if (and (< prev 0) (< depth prev))
1052 (error (if forward
1053 "No following conditional at this level"
1054 "No previous conditional at this level")))
1055 ;; When searching forward, start from next line so
1056 ;; that we don't find the same line again.
1057 (if forward (forward-line 1))
1058 ;; If this line exits a level of conditional, exit
1059 ;; inner loop.
1060 (if (< depth 0)
1061 (setq found (point))))
1062 ;; else
1063 (if forward (forward-line 1))
1064 )))
1065 (or found
1066 (error "No containing preprocessor conditional"))
1067 (goto-char (setq new found)))
1068 (setq count (+ count increment))))
1069 (push-mark)
1070 (goto-char new))
1071 (c-keep-region-active))
1072
1073 \f
1074 ;; commands to indent lines, regions, defuns, and expressions
1075 (defun c-indent-command (&optional whole-exp)
1076 "Indent current line as C code, and/or insert some whitespace.
1077
1078 If `c-tab-always-indent' is t, always just indent the current line.
1079 If nil, indent the current line only if point is at the left margin or
1080 in the line's indentation; otherwise insert some whitespace[*]. If
1081 other than nil or t, then some whitespace[*] is inserted only within
1082 literals (comments and strings) and inside preprocessor directives,
1083 but the line is always reindented.
1084
1085 A numeric argument, regardless of its value, means indent rigidly all
1086 the lines of the expression starting after point so that this line
1087 becomes properly indented. The relative indentation among the lines
1088 of the expression are preserved.
1089
1090 [*] The amount and kind of whitespace inserted is controlled by the
1091 variable `c-insert-tab-function', which is called to do the actual
1092 insertion of whitespace. Normally the function in this variable
1093 just inserts a tab character, or the equivalent number of spaces,
1094 depending on the variable `indent-tabs-mode'."
1095
1096 (interactive "*P")
1097 (let ((bod (c-point 'bod)))
1098 (if whole-exp
1099 ;; If arg, always indent this line as C
1100 ;; and shift remaining lines of expression the same amount.
1101 (let ((shift-amt (c-indent-line))
1102 beg end)
1103 (save-excursion
1104 (if (eq c-tab-always-indent t)
1105 (beginning-of-line))
1106 (setq beg (point))
1107 (forward-sexp 1)
1108 (setq end (point))
1109 (goto-char beg)
1110 (forward-line 1)
1111 (setq beg (point)))
1112 (if (> end beg)
1113 (indent-code-rigidly beg end (- shift-amt) "#")))
1114 ;; No arg supplied, use c-tab-always-indent to determine
1115 ;; behavior
1116 (cond
1117 ;; CASE 1: indent when at column zero or in lines indentation,
1118 ;; otherwise insert a tab
1119 ((not c-tab-always-indent)
1120 (if (save-excursion
1121 (skip-chars-backward " \t")
1122 (not (bolp)))
1123 (funcall c-insert-tab-function)
1124 (c-indent-line)))
1125 ;; CASE 2: just indent the line
1126 ((eq c-tab-always-indent t)
1127 (c-indent-line))
1128 ;; CASE 3: if in a literal, insert a tab, but always indent the
1129 ;; line
1130 (t
1131 (if (c-in-literal bod)
1132 (funcall c-insert-tab-function))
1133 (c-indent-line)
1134 )))))
1135
1136 (defun c-indent-exp (&optional shutup-p)
1137 "Indent each line in balanced expression following point.
1138 Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
1139 (interactive "*P")
1140 (let ((here (point))
1141 end progress-p)
1142 (unwind-protect
1143 (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
1144 (start (progn
1145 ;; try to be smarter about finding the range of
1146 ;; lines to indent. skip all following
1147 ;; whitespace. failing that, try to find any
1148 ;; opening brace on the current line
1149 (skip-chars-forward " \t\n")
1150 (if (memq (char-after) '(?\( ?\[ ?\{))
1151 (point)
1152 (let ((state (parse-partial-sexp (point)
1153 (c-point 'eol))))
1154 (and (nth 1 state)
1155 (goto-char (nth 1 state))
1156 (memq (char-after) '(?\( ?\[ ?\{))
1157 (point)))))))
1158 ;; find balanced expression end
1159 (setq end (and (c-safe (progn (forward-sexp 1) t))
1160 (point-marker)))
1161 ;; sanity check
1162 (and (not start)
1163 (not shutup-p)
1164 (error "Cannot find start of balanced expression to indent."))
1165 (and (not end)
1166 (not shutup-p)
1167 (error "Cannot find end of balanced expression to indent."))
1168 (c-progress-init start end 'c-indent-exp)
1169 (setq progress-p t)
1170 (goto-char start)
1171 (beginning-of-line)
1172 (while (< (point) end)
1173 (if (not (looking-at "[ \t]*$"))
1174 (c-indent-line))
1175 (c-progress-update)
1176 (forward-line 1)))
1177 ;; make sure marker is deleted
1178 (and end
1179 (set-marker end nil))
1180 (and progress-p
1181 (c-progress-fini 'c-indent-exp))
1182 (goto-char here))))
1183
1184 (defun c-indent-defun ()
1185 "Re-indents the current top-level function def, struct or class declaration."
1186 (interactive "*")
1187 (let ((here (point-marker))
1188 (c-echo-syntactic-information-p nil)
1189 (brace (c-least-enclosing-brace (c-parse-state))))
1190 (goto-char (or brace (c-point 'bod)))
1191 ;; if we're sitting at b-o-b, it might be because there was no
1192 ;; least enclosing brace and we were sitting on the defun's open
1193 ;; brace.
1194 (if (and (bobp) (not (eq (char-after) ?\{)))
1195 (goto-char here))
1196 ;; if defun-prompt-regexp is non-nil, b-o-d might not leave us at
1197 ;; the open brace. I consider this an Emacs bug.
1198 (and (boundp 'defun-prompt-regexp)
1199 defun-prompt-regexp
1200 (looking-at defun-prompt-regexp)
1201 (goto-char (match-end 0)))
1202 ;; catch all errors in c-indent-exp so we can 1. give more
1203 ;; meaningful error message, and 2. restore point
1204 (unwind-protect
1205 (c-indent-exp)
1206 (goto-char here)
1207 (set-marker here nil))))
1208
1209 (defun c-indent-region (start end)
1210 ;; Indent every line whose first char is between START and END inclusive.
1211 (save-excursion
1212 (goto-char start)
1213 ;; Advance to first nonblank line.
1214 (skip-chars-forward " \t\n")
1215 (beginning-of-line)
1216 (let (endmark)
1217 (unwind-protect
1218 (let ((c-tab-always-indent t)
1219 ;; shut up any echo msgs on indiv lines
1220 (c-echo-syntactic-information-p nil)
1221 fence)
1222 (c-progress-init start end 'c-indent-region)
1223 (setq endmark (copy-marker end))
1224 (while (and (bolp)
1225 (not (eobp))
1226 (< (point) endmark))
1227 ;; update progress
1228 (c-progress-update)
1229 ;; Indent one line as with TAB.
1230 (let (nextline sexpend sexpbeg)
1231 ;; skip blank lines
1232 (skip-chars-forward " \t\n")
1233 (beginning-of-line)
1234 ;; indent the current line
1235 (c-indent-line)
1236 (setq fence (point))
1237 (if (save-excursion
1238 (beginning-of-line)
1239 (looking-at "[ \t]*#"))
1240 (forward-line 1)
1241 (save-excursion
1242 ;; Find beginning of following line.
1243 (setq nextline (c-point 'bonl))
1244 ;; Find first beginning-of-sexp for sexp extending past
1245 ;; this line.
1246 (beginning-of-line)
1247 (while (< (point) nextline)
1248 (condition-case nil
1249 (progn
1250 (forward-sexp 1)
1251 (setq sexpend (point)))
1252 (error (setq sexpend nil)
1253 (goto-char nextline)))
1254 (c-forward-syntactic-ws))
1255 (if sexpend
1256 (progn
1257 ;; make sure the sexp we found really starts on the
1258 ;; current line and extends past it
1259 (goto-char sexpend)
1260 (setq sexpend (point-marker))
1261 (c-safe (backward-sexp 1))
1262 (setq sexpbeg (point))))
1263 (if (and sexpbeg (< sexpbeg fence))
1264 (setq sexpbeg fence)))
1265 ;; check to see if the next line starts a
1266 ;; comment-only line
1267 (save-excursion
1268 (forward-line 1)
1269 (skip-chars-forward " \t")
1270 (if (looking-at c-comment-start-regexp)
1271 (setq sexpbeg (c-point 'bol))))
1272 ;; If that sexp ends within the region, indent it all at
1273 ;; once, fast.
1274 (condition-case nil
1275 (if (and sexpend
1276 (> sexpend nextline)
1277 (<= sexpend endmark))
1278 (progn
1279 (goto-char sexpbeg)
1280 (c-indent-exp 'shutup)
1281 (c-progress-update)
1282 (goto-char sexpend)))
1283 (error
1284 (goto-char sexpbeg)
1285 (c-indent-line)))
1286 ;; Move to following line and try again.
1287 (and sexpend
1288 (markerp sexpend)
1289 (set-marker sexpend nil))
1290 (forward-line 1)
1291 (setq fence (point))))))
1292 (set-marker endmark nil)
1293 (c-progress-fini 'c-indent-region)
1294 (c-echo-parsing-error)
1295 ))))
1296
1297 (defun c-mark-function ()
1298 "Put mark at end of a C, C++, or Objective-C defun, point at beginning."
1299 (interactive)
1300 (let ((here (point))
1301 ;; there should be a c-point position for 'eod
1302 (eod (save-excursion (end-of-defun) (point)))
1303 (state (c-parse-state))
1304 brace)
1305 (while state
1306 (setq brace (car state))
1307 (if (consp brace)
1308 (goto-char (cdr brace))
1309 (goto-char brace))
1310 (setq state (cdr state)))
1311 (if (eq (char-after) ?{)
1312 (progn
1313 (forward-line -1)
1314 (while (not (or (bobp)
1315 (looking-at "[ \t]*$")))
1316 (forward-line -1)))
1317 (forward-line 1)
1318 (skip-chars-forward " \t\n"))
1319 (push-mark here)
1320 (push-mark eod nil t)))
1321
1322 \f
1323 ;; for progress reporting
1324 (defvar c-progress-info nil)
1325
1326 (defun c-progress-init (start end context)
1327 (cond
1328 ;; Be silent
1329 ((not c-progress-interval))
1330 ;; Start the progress update messages. If this Emacs doesn't have
1331 ;; a built-in timer, just be dumb about it.
1332 ((not (fboundp 'current-time))
1333 (message "indenting region... (this may take a while)"))
1334 ;; If progress has already been initialized, do nothing. otherwise
1335 ;; initialize the counter with a vector of:
1336 ;; [start end lastsec context]
1337 (c-progress-info)
1338 (t (setq c-progress-info (vector start
1339 (save-excursion
1340 (goto-char end)
1341 (point-marker))
1342 (nth 1 (current-time))
1343 context))
1344 (message "indenting region..."))
1345 ))
1346
1347 (defun c-progress-update ()
1348 ;; update progress
1349 (if (not (and c-progress-info c-progress-interval))
1350 nil
1351 (let ((now (nth 1 (current-time)))
1352 (start (aref c-progress-info 0))
1353 (end (aref c-progress-info 1))
1354 (lastsecs (aref c-progress-info 2)))
1355 ;; should we update? currently, update happens every 2 seconds,
1356 ;; what's the right value?
1357 (if (< c-progress-interval (- now lastsecs))
1358 (progn
1359 (message "indenting region... (%d%% complete)"
1360 (/ (* 100 (- (point) start)) (- end start)))
1361 (aset c-progress-info 2 now)))
1362 )))
1363
1364 (defun c-progress-fini (context)
1365 ;; finished
1366 (if (not c-progress-interval)
1367 nil
1368 (if (or (eq context (aref c-progress-info 3))
1369 (eq context t))
1370 (progn
1371 (set-marker (aref c-progress-info 1) nil)
1372 (setq c-progress-info nil)
1373 (message "indenting region...done")))))
1374
1375
1376 \f
1377 ;;; This page handles insertion and removal of backslashes for C macros.
1378
1379 (defun c-backslash-region (from to delete-flag)
1380 "Insert, align, or delete end-of-line backslashes on the lines in the region.
1381 With no argument, inserts backslashes and aligns existing backslashes.
1382 With an argument, deletes the backslashes.
1383
1384 This function does not modify blank lines at the start of the region.
1385 If the region ends at the start of a line, it always deletes the
1386 backslash (if any) at the end of the previous line.
1387
1388 You can put the region around an entire macro definition and use this
1389 command to conveniently insert and align the necessary backslashes."
1390 (interactive "*r\nP")
1391 (save-excursion
1392 (goto-char from)
1393 (let ((column c-backslash-column)
1394 (endmark (make-marker)))
1395 (move-marker endmark to)
1396 ;; Compute the smallest column number past the ends of all the lines.
1397 (if (not delete-flag)
1398 (while (< (point) to)
1399 (end-of-line)
1400 (if (eq (char-before) ?\\)
1401 (progn (forward-char -1)
1402 (skip-chars-backward " \t")))
1403 (setq column (max column (1+ (current-column))))
1404 (forward-line 1)))
1405 ;; Adjust upward to a tab column, if that doesn't push past the margin.
1406 (if (> (% column tab-width) 0)
1407 (let ((adjusted (* (/ (+ column tab-width -1) tab-width) tab-width)))
1408 (if (< adjusted (window-width))
1409 (setq column adjusted))))
1410 ;; Don't modify blank lines at start of region.
1411 (goto-char from)
1412 (while (and (< (point) endmark) (eolp))
1413 (forward-line 1))
1414 ;; Add or remove backslashes on all the lines.
1415 (while (< (point) endmark)
1416 (if (and (not delete-flag)
1417 ;; Un-backslashify the last line
1418 ;; if the region ends right at the start of the next line.
1419 (save-excursion
1420 (forward-line 1)
1421 (< (point) endmark)))
1422 (c-append-backslash column)
1423 (c-delete-backslash))
1424 (forward-line 1))
1425 (move-marker endmark nil))))
1426
1427 (defun c-append-backslash (column)
1428 (end-of-line)
1429 (if (eq (char-before) ?\\)
1430 (progn (forward-char -1)
1431 (delete-horizontal-space)
1432 (indent-to column))
1433 (indent-to column)
1434 (insert "\\")))
1435
1436 (defun c-delete-backslash ()
1437 (end-of-line)
1438 (or (bolp)
1439 (progn
1440 (forward-char -1)
1441 (if (looking-at "\\\\")
1442 (delete-region (1+ (point))
1443 (progn (skip-chars-backward " \t") (point)))))))
1444
1445 \f
1446 (defun c-fill-paragraph (&optional arg)
1447 "Like \\[fill-paragraph] but handles C and C++ style comments.
1448 If any of the current line is a comment or within a comment,
1449 fill the comment or the paragraph of it that point is in,
1450 preserving the comment indentation or line-starting decorations.
1451
1452 If point is inside multiline string literal, fill it. This currently
1453 does not respect escaped newlines, except for the special case when it
1454 is the very first thing in the string. The intended use for this rule
1455 is in situations like the following:
1456
1457 char description[] = \"\\
1458 A very long description of something that you want to fill to make
1459 nicely formatted output.\"\;
1460
1461 If point is in any other situation, i.e. in normal code, do nothing.
1462
1463 Optional prefix ARG means justify paragraph as well."
1464 (interactive "*P")
1465 (let* ((point-save (point-marker))
1466 limits
1467 comment-start-place
1468 (first-line
1469 ;; Check for obvious entry to comment.
1470 (save-excursion
1471 (beginning-of-line)
1472 (skip-chars-forward " \t")
1473 (and (looking-at comment-start-skip)
1474 (setq comment-start-place (point)))))
1475 (re1 "\\|\\([ \t]*/\\*[ \t]*\\|[ \t]*\\*/[ \t]*\\|[ \t/*]*\\)"))
1476 (if (save-excursion
1477 (beginning-of-line)
1478 (looking-at ".*//"))
1479 (let ((fill-prefix fill-prefix)
1480 ;; Lines containing just a comment start or just an end
1481 ;; should not be filled into paragraphs they are next
1482 ;; to.
1483 (paragraph-start (concat paragraph-start re1 "$"))
1484 (paragraph-separate (concat paragraph-separate re1 "$")))
1485 (save-excursion
1486 (beginning-of-line)
1487 ;; Move up to first line of this comment.
1488 (while (and (not (bobp))
1489 (looking-at "[ \t]*//[ \t]*[^ \t\n]"))
1490 (forward-line -1))
1491 (if (not (looking-at ".*//[ \t]*[^ \t\n]"))
1492 (forward-line 1))
1493 ;; Find the comment start in this line.
1494 (re-search-forward "[ \t]*//[ \t]*")
1495 ;; Set the fill-prefix to be what all lines except the first
1496 ;; should start with. But do not alter a user set fill-prefix.
1497 (if (null fill-prefix)
1498 (setq fill-prefix (buffer-substring (match-beginning 0)
1499 (match-end 0))))
1500 (save-restriction
1501 ;; Narrow down to just the lines of this comment.
1502 (narrow-to-region (c-point 'bol)
1503 (save-excursion
1504 (forward-line 1)
1505 (while
1506 (looking-at (regexp-quote fill-prefix))
1507 (forward-line 1))
1508 (point)))
1509 (or (c-safe
1510 ;; fill-paragraph sometimes fails to detect when we
1511 ;; are between paragraphs.
1512 (beginning-of-line)
1513 (search-forward fill-prefix (c-point 'eol))
1514 (looking-at paragraph-separate))
1515 ;; Avoids recursion
1516 (let (fill-paragraph-function)
1517 (fill-paragraph arg))))))
1518 ;; else C style comments
1519 (if (or first-line
1520 ;; t if we enter a comment between start of function and
1521 ;; this line.
1522 (save-excursion
1523 (setq limits (c-literal-limits))
1524 (and (consp limits)
1525 (save-excursion
1526 (goto-char (car limits))
1527 (looking-at c-comment-start-regexp))))
1528 ;; t if this line contains a comment starter.
1529 (setq first-line
1530 (save-excursion
1531 (beginning-of-line)
1532 (prog1
1533 (re-search-forward comment-start-skip
1534 (save-excursion (end-of-line)
1535 (point))
1536 t)
1537 (setq comment-start-place (point)))))
1538 ;; t if we're in the whitespace after a comment ender
1539 ;; which ends its line.
1540 (and (not limits)
1541 (when (and (looking-at "[ \t]*$")
1542 (save-excursion
1543 (beginning-of-line)
1544 (looking-at ".*\\*/[ \t]*$")))
1545 (save-excursion
1546 (forward-comment -1)
1547 (setq comment-start-place (point)))
1548 t)))
1549 ;; Inside a comment: fill one comment paragraph.
1550 (let ((fill-prefix
1551 ;; The prefix for each line of this paragraph
1552 ;; is the appropriate part of the start of this line,
1553 ;; up to the column at which text should be indented.
1554 (save-excursion
1555 (beginning-of-line)
1556 (if (looking-at ".*/\\*.*\\*/")
1557 (progn (re-search-forward comment-start-skip)
1558 (make-string (current-column) ?\ ))
1559 (if first-line
1560 (forward-line 1)
1561 (if (and (looking-at "[ \t]*\\*/")
1562 (not (save-excursion
1563 (forward-line -1)
1564 (looking-at ".*/\\*"))))
1565 (forward-line -1)))
1566
1567 (let ((line-width (progn (end-of-line) (current-column))))
1568 (beginning-of-line)
1569 (prog1
1570 (buffer-substring
1571 (point)
1572
1573 ;; How shall we decide where the end of the
1574 ;; fill-prefix is?
1575 (progn
1576 (skip-chars-forward " \t*" (c-point 'eol))
1577 ;; kludge alert, watch out for */, in
1578 ;; which case fill-prefix should *not*
1579 ;; be "*"!
1580 (if (and (eq (char-after) ?/)
1581 (eq (char-before) ?*))
1582 (forward-char -1))
1583 (point)))
1584
1585 ;; If the comment is only one line followed
1586 ;; by a blank line, calling move-to-column
1587 ;; above may have added some spaces and tabs
1588 ;; to the end of the line; the fill-paragraph
1589 ;; function will then delete it and the
1590 ;; newline following it, so we'll lose a
1591 ;; blank line when we shouldn't. So delete
1592 ;; anything move-to-column added to the end
1593 ;; of the line. We record the line width
1594 ;; instead of the position of the old line
1595 ;; end because move-to-column might break a
1596 ;; tab into spaces, and the new characters
1597 ;; introduced there shouldn't be deleted.
1598
1599 ;; If you can see a better way to do this,
1600 ;; please make the change. This seems very
1601 ;; messy to me.
1602 (delete-region (progn (move-to-column line-width)
1603 (point))
1604 (progn (end-of-line) (point))))))))
1605
1606 ;; Lines containing just a comment start or just an end
1607 ;; should not be filled into paragraphs they are next
1608 ;; to.
1609 (paragraph-start (if (eq major-mode 'java-mode)
1610 (concat paragraph-start
1611 re1 "\\("
1612 c-Java-javadoc-paragraph-start
1613 "\\|$\\)")
1614 (concat paragraph-start re1 "$")))
1615 (paragraph-separate (concat paragraph-separate re1 "$"))
1616 (chars-to-delete 0)
1617 )
1618 (save-restriction
1619 ;; Don't fill the comment together with the code
1620 ;; following it. So temporarily exclude everything
1621 ;; before the comment start, and everything after the
1622 ;; line where the comment ends. If comment-start-place
1623 ;; is non-nil, the comment starter is there. Otherwise,
1624 ;; point is inside the comment.
1625 (narrow-to-region (save-excursion
1626 (if comment-start-place
1627 (goto-char comment-start-place)
1628 (search-backward "/*"))
1629 (if (and (not c-hanging-comment-starter-p)
1630 (looking-at
1631 (concat c-comment-start-regexp
1632 "[ \t]*$")))
1633 (forward-line 1))
1634 ;; Protect text before the comment
1635 ;; start by excluding it. Add
1636 ;; spaces to bring back proper
1637 ;; indentation of that point.
1638 (let ((column (current-column)))
1639 (prog1 (point)
1640 (setq chars-to-delete column)
1641 (insert-char ?\ column))))
1642 (save-excursion
1643 (if comment-start-place
1644 (goto-char (+ comment-start-place 2)))
1645 (search-forward "*/" nil 'move)
1646 (if (and (not c-hanging-comment-ender-p)
1647 (save-excursion
1648 (beginning-of-line)
1649 (looking-at "[ \t]*\\*/")))
1650 (beginning-of-line)
1651 (forward-line 1))
1652 (point)))
1653 (or (c-safe
1654 ;; fill-paragraph sometimes fails to detect when we
1655 ;; are between paragraphs.
1656 (beginning-of-line)
1657 (search-forward fill-prefix (c-point 'eol))
1658 (looking-at paragraph-separate))
1659 ;; Avoids recursion
1660 (let (fill-paragraph-function)
1661 (fill-paragraph arg)))
1662 (save-excursion
1663 ;; Delete the chars we inserted to avoid clobbering
1664 ;; the stuff before the comment start.
1665 (goto-char (point-min))
1666 (if (> chars-to-delete 0)
1667 (delete-region (point) (+ (point) chars-to-delete)))
1668 ;; Find the comment ender (should be on last line of
1669 ;; buffer, given the narrowing) and don't leave it on
1670 ;; its own line, unless that's the style that's desired.
1671 (goto-char (point-max))
1672 (forward-line -1)
1673 (search-forward "*/" nil 'move)
1674 (beginning-of-line)
1675 (if (and c-hanging-comment-ender-p
1676 (looking-at "[ \t]*\\*/"))
1677 ;(delete-indentation)))))
1678 (let ((fill-column (+ fill-column 9999)))
1679 (forward-line -1)
1680 (fill-region-as-paragraph (point) (point-max))
1681 ;; If fill-prefix ended with a `*', it may be
1682 ;; taken away from the comment ender. We got to
1683 ;; check this and put it back if that is the
1684 ;; case.
1685 (goto-char (- (point-max) 2))
1686 (if (not (= (char-before) ?*))
1687 (insert ?*))
1688 )))))
1689 ;; Else maybe a string. Fill it if it's a multiline string.
1690 ;; FIXME: This currently doesn't handle escaped newlines.
1691 ;; Doing that correctly is a bit tricky.
1692 (if (and limits
1693 (eq (char-syntax (char-after (car limits))) ?\")
1694 (save-excursion
1695 (goto-char (car limits))
1696 (end-of-line)
1697 (< (point) (cdr limits))))
1698 (let (fill-prefix
1699 fill-paragraph-function)
1700 (save-restriction
1701 (narrow-to-region (save-excursion
1702 (goto-char (1+ (car limits)))
1703 (if (looking-at "\\\\$")
1704 ;; Some DWIM: Leave the start
1705 ;; line if it's nothing but an
1706 ;; escaped newline.
1707 (1+ (match-end 0))
1708 (point)))
1709 (save-excursion
1710 (goto-char (1- (cdr limits)))
1711 ;; Inserting a newline and
1712 ;; removing it again after
1713 ;; fill-paragraph makes it more
1714 ;; predictable.
1715 (insert ?\n)
1716 (point)))
1717 ;; Do not compensate for the narrowed column. This
1718 ;; way the literal will always be filled at the same
1719 ;; column internally.
1720 (fill-paragraph arg)
1721 (goto-char (1- (point-max)))
1722 (delete-char 1)))
1723 )))
1724 (goto-char (marker-position point-save))
1725 (set-marker point-save nil)
1726 ;; Always return t. This has the effect that if filling isn't
1727 ;; done above, it isn't done at all, and it's therefore
1728 ;; effectively disabled in normal code.
1729 t))
1730
1731 \f
1732 (provide 'cc-cmds)
1733 ;;; cc-cmds.el ends here