1 ;;; cc-cmds.el --- user level commands for CC Mode
3 ;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
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
13 ;; This file is part of GNU Emacs.
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)
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.
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.
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
37 (zerop (setq arg (prefix-numeric-value arg))))
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.
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,
52 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
54 (c-keep-region-active))
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.
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."
65 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
67 (c-keep-region-active))
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.
75 See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
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))
80 (c-keep-region-active))
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.
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.
102 See also \\[c-electric-delete]."
104 (if (or (not c-hungry-delete-key)
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)
115 (defun c-electric-delete (arg)
116 "Deletes preceding or following character or whitespace.
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].
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."
131 (if (and (boundp 'delete-key-deletes-forward)
132 delete-key-deletes-forward)
133 (if (or (not c-hungry-delete-key)
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)))
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."
151 (if (or (c-in-literal)
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)))
160 (delete-horizontal-space)
161 (insert-char last-command-char 1)
163 (goto-char (- (point-max) pos)))
166 (defun c-electric-brace (arg)
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'.
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."
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.
184 ; (not c-auto-newline)
185 (not (looking-at "[ \t]*$")))
186 (self-insert-command (prefix-numeric-value arg))
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
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)
204 (insertion-point (point))
206 (preserve-p (and (not (bobp))
207 (eq ?\ (char-syntax (char-before)))))
209 (c-echo-syntactic-information-p nil)
211 ;; only insert a newline if there is
212 ;; non-whitespace behind us
214 (skip-chars-backward " \t")
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)))
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))
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)))
238 (c-state-cache c-state-cache))
240 ;; we may need to update the cache. this should still be
241 ;; faster than recalculating the state in many cases
244 (narrow-to-region here (point))
245 (if (and (c-safe (progn (backward-up-list -1) t))
246 (memq (char-before) '(?\) ?}))
248 (c-safe (progn (forward-sexp -1) t))))
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))
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
269 ;; if there is whitespace before point, then preserve
270 ;; at least one space.
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.
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
287 (makunbound 'c-state-cache)
288 (setq c-state-cache (c-parse-state)
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
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
300 (pos (- (point-max) (point)))
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)
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)
321 (setq mbeg (match-beginning 0)
324 (not (c-in-literal)))
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)
334 (goto-char (match-end 0))
335 (c-safe (forward-sexp 1))
336 (skip-chars-forward " \t\n")
337 (setq mbeg (match-beginning 0)
339 (= here (1+ (point))))
340 (not (c-in-literal)))
342 (delete-region mbeg mend)
343 (insert "} else if ")))
344 (goto-char (- (point-max) pos))
346 ;; does a newline go after the brace?
347 (if (memq 'after newlines)
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)))
356 (and (eq last-command-char ?\})
359 (c-backward-syntactic-ws safepos)
360 (funcall old-blink-paren)))
363 (defun c-electric-slash (arg)
364 "Insert a slash character.
366 Indent the line as a comment, if:
368 1. The slash is second of a `//' line oriented comment introducing
369 token and we are on a comment-only-line, or
371 2. The slash is part of a `*/' token that closes a block oriented
374 If numeric ARG is supplied or point is inside a literal, indentation
377 (let* ((ch (char-before))
378 (indentp (and (not arg)
379 (eq last-command-char ?/)
381 (not (c-in-literal)))
386 (c-echo-syntactic-information-p nil))
387 (self-insert-command (prefix-numeric-value arg))
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
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.
402 (memq (c-in-literal) '(c))
403 (eq (char-before) ?*)
406 (skip-chars-backward "*")
407 (if (eq (char-before) ?/)
409 (skip-chars-backward " \t")
412 (let (c-echo-syntactic-information-p)
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
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."
427 (let* ((lim (c-most-enclosing-brace (c-parse-state)))
428 (literal (c-in-literal lim))
431 (c-echo-syntactic-information-p nil))
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
442 (let ((pos (- (point-max) (point))))
444 (eq last-command-char ?,)
445 (memq 'list-close-comma c-cleanup-list))
447 (eq last-command-char ?\;)
448 (memq 'defun-close-semi c-cleanup-list)))
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)))
459 ;; check to see if a newline should be added
460 (let ((criteria c-hanging-semi&comma-criteria)
461 answer add-newline-p)
463 (setq answer (funcall (car criteria)))
464 ;; only nil value means continue checking
466 (setq criteria (cdr criteria))
468 ;; only 'stop specifically says do not add a newline
469 (setq add-newline-p (not (eq answer 'stop)))
476 (defun c-electric-colon (arg)
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'.
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.
487 This function cleans up double colon scope operators based on the
488 value of `c-cleanup-list'."
490 (let* ((bod (c-point 'bod))
491 (literal (c-in-literal bod))
492 syntax newlines is-scope-op
494 (c-echo-syntactic-information-p nil))
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)))
503 (if (and c-auto-newline
504 (memq 'scope-operator c-cleanup-list)
505 (eq (char-before) ?:)
508 (skip-chars-backward " \t\n")
509 (eq (char-before) ?:))
511 (not (eq (char-after (- (point) 2)) ?:)))
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
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)
529 (c-guess-basic-syntax)
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)
540 (skip-chars-backward ": \t")
542 (let ((pos (- (point-max) (point))))
546 (goto-char (- (point-max) pos))))
547 ;; does a newline go after the colon?
548 (if (and (memq 'after (cdr-safe newlines))
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.
562 The line will also not be re-indented if a numeric argument is
563 supplied, or point is inside a literal."
565 (let ((indentp (and (not arg)
566 (eq (char-before) last-command-char)
567 (not (c-in-literal))))
569 (c-echo-syntactic-information-p nil))
570 (self-insert-command (prefix-numeric-value arg))
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."
582 (let ((case-fold-search nil))
584 (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg)
585 (while (and (< arg 0)
587 "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)"
590 (setq arg (1+ arg)))))
591 (c-keep-region-active))
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
598 (c-forward-into-nomenclature (- arg))
599 (c-keep-region-active))
601 (defun c-scope-operator ()
602 "Insert a double colon scope operator at point.
603 No indentation or other \"electric\" behavior is performed."
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.
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
618 (c-end-of-defun (- arg))
620 (let ((state (nreverse (c-parse-state)))
622 (while (and state (not bod))
623 (setq bod (car state)
626 (setq prevbod (car bod)
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))
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.
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'."
643 (c-beginning-of-defun (- arg))
645 ;; skip down into the next defun-block
646 (while (and (c-safe (down-list 1) t)
647 (not (eq (char-before) ?{)))
650 (c-beginning-of-defun 1)
654 (c-keep-region-active))
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
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
670 (interactive (list (prefix-numeric-value current-prefix-arg)
672 (let* ((count (or count 1))
674 (range (c-collect-line-comments (c-literal-limits lim))))
675 (while (and (/= count 0)
676 (or (not lim) (> (point) lim)))
678 (if (and (not range) sentence-flag)
680 ;; Find the comment next to point if we're not in one.
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")
687 (setq range (if (forward-comment -1)
690 (= (char-after) ?\n)))
691 (skip-chars-forward " \t\n")
693 (setq range (if (forward-comment 1)
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.
701 (if (and sentence-flag
702 (/= (char-syntax (char-after (car range))) ?\"))
704 ;; move by sentence, but not past the limit of the literal
706 (narrow-to-region (save-excursion
707 (goto-char (car range))
708 (looking-at comment-start-skip)
709 (goto-char (match-end 0))
712 (goto-char (cdr range))
714 (goto-char (car range))
717 (skip-chars-backward " \t\n")
719 (c-safe (forward-sentence (if (> count 0) -1 1))))
720 ;; See if we should escape the literal.
723 (setq count (1- count))
724 (goto-char (car range))
727 (setq count (1+ count))
728 (goto-char (cdr range))
730 (goto-char (if (> count 0) (car range) (cdr range)))
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
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) ?\}))
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.
755 (if (and (looking-at "[{}]")
757 (throw 'done (= (char-after) ?{)))
758 (c-backward-syntactic-ws)
759 (cond ((bobp) ; Must handle bob specially.
761 (if (= last (point-min))
767 ((progn (backward-char)
768 (looking-at "[;{}]"))
769 (if (or (= here last)
770 (= (char-after last) ?}))
771 (if (and (= (char-before) ?})
772 (= (char-after) ?\;))
776 ((or (= (char-syntax (char-after)) ?\))
777 (= (char-syntax (char-after)) ?\"))
782 (goto-char (point-min))
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.
794 (c-forward-syntactic-ws)
795 (cond ((= (char-after) ?{)
797 (progn (forward-char)
801 ((and (= (char-after) ?})
805 ((looking-at ";\\|};?")
806 (goto-char (match-end 0))
808 ((or (= (char-syntax (char-after)) ?\()
809 (= (char-syntax (char-after)) ?\"))
815 (goto-char (point-max))
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)))
822 ;; its possible we've been left up-buf of lim
823 (if lim (goto-char (max (point) lim))))
824 (c-keep-region-active))
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
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
838 (interactive (list (prefix-numeric-value current-prefix-arg)
840 (c-beginning-of-statement (- (or count 1)) lim sentence-flag)
841 (c-keep-region-active))
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.
850 (put sym 'delete-selection t) ; for delsel (Emacs)
851 (put sym 'pending-delete t))) ; for pending-del (XEmacs)
856 c-electric-semi&comma
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
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))
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
881 (1+ (current-column)))
882 ;; CASE 2: 2 spaces after #endif
883 ((or (looking-at "^#[ \t]*endif[ \t]*")
884 (looking-at "^#[ \t]*else[ \t]*"))
886 ;; CASE 3: when comment-column is nil, calculate the offset
887 ;; according to c-offsets-alist. E.g. identical to hitting
889 ((and c-indent-comments-syntactically-p
891 (skip-chars-forward " \t")
892 (or (looking-at comment-start)
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.
904 (skip-chars-forward " \t")
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
919 (skip-chars-forward " \t")
921 (looking-at c-comment-start-regexp)
922 (setq placeholder (point))))
923 (goto-char placeholder)
924 (if (< (current-column) comment-column)
927 ;; CASE 5: If comment-column is 0, and nothing but space
928 ;; before the comment, align it at 0 rather than 1.
931 (skip-chars-backward " \t")
932 (and (= comment-column 0) (bolp)))
934 ;; CASE 6: indent at comment column except leave at least one
936 (t (max (1+ (current-column))
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))
947 ((eq literal 'string))
948 ((or (not c-comment-continuation-stars)
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))
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
963 (string-equal (match-string 1) "//"))
965 (setq leader (match-string 0)))
967 (delete-region (progn (skip-chars-backward " \t") (point))
968 (progn (skip-chars-forward " \t") (point)))
970 ;; to avoid having an anchored comment that c-indent-line will
974 (indent-for-comment))
977 ;; advice for indent-new-comment-line for older Emacsen
978 (if (boundp 'comment-line-break-function)
981 (defadvice indent-new-comment-line (around c-line-break-advice activate)
982 (if (or (not c-buffer-is-cc-mode)
984 (not c-comment-continuation-stars))
986 (c-comment-line-break-function (ad-get-arg 0)))))
988 ;; used by outline-minor-mode
989 (defun c-outline-level ()
991 (skip-chars-forward "\t ")
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."
1002 (c-forward-conditional (- count) t)
1003 (c-keep-region-active))
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."
1010 (c-forward-conditional (- count) up-flag)
1011 (c-keep-region-active))
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."
1018 (let* ((forward (> count 0))
1019 (increment (if forward -1 1))
1020 (search-function (if forward 're-search-forward 're-search-backward))
1024 (let ((depth (if up-flag 0 -1)) found)
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\\)"
1038 ;; Now verify it is really a preproc line.
1039 (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
1041 ;; Update depth according to what we found.
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))
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
1061 (setq found (point))))
1063 (if forward (forward-line 1))
1066 (error "No containing preprocessor conditional"))
1067 (goto-char (setq new found)))
1068 (setq count (+ count increment))))
1071 (c-keep-region-active))
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.
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.
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.
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'."
1097 (let ((bod (c-point 'bod)))
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))
1104 (if (eq c-tab-always-indent t)
1105 (beginning-of-line))
1113 (indent-code-rigidly beg end (- shift-amt) "#")))
1114 ;; No arg supplied, use c-tab-always-indent to determine
1117 ;; CASE 1: indent when at column zero or in lines indentation,
1118 ;; otherwise insert a tab
1119 ((not c-tab-always-indent)
1121 (skip-chars-backward " \t")
1123 (funcall c-insert-tab-function)
1125 ;; CASE 2: just indent the line
1126 ((eq c-tab-always-indent t)
1128 ;; CASE 3: if in a literal, insert a tab, but always indent the
1131 (if (c-in-literal bod)
1132 (funcall c-insert-tab-function))
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."
1140 (let ((here (point))
1143 (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
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) '(?\( ?\[ ?\{))
1152 (let ((state (parse-partial-sexp (point)
1155 (goto-char (nth 1 state))
1156 (memq (char-after) '(?\( ?\[ ?\{))
1158 ;; find balanced expression end
1159 (setq end (and (c-safe (progn (forward-sexp 1) t))
1164 (error "Cannot find start of balanced expression to indent."))
1167 (error "Cannot find end of balanced expression to indent."))
1168 (c-progress-init start end 'c-indent-exp)
1172 (while (< (point) end)
1173 (if (not (looking-at "[ \t]*$"))
1177 ;; make sure marker is deleted
1179 (set-marker end nil))
1181 (c-progress-fini 'c-indent-exp))
1184 (defun c-indent-defun ()
1185 "Re-indents the current top-level function def, struct or class declaration."
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
1194 (if (and (bobp) (not (eq (char-after) ?\{)))
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)
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
1207 (set-marker here nil))))
1209 (defun c-indent-region (start end)
1210 ;; Indent every line whose first char is between START and END inclusive.
1213 ;; Advance to first nonblank line.
1214 (skip-chars-forward " \t\n")
1218 (let ((c-tab-always-indent t)
1219 ;; shut up any echo msgs on indiv lines
1220 (c-echo-syntactic-information-p nil)
1222 (c-progress-init start end 'c-indent-region)
1223 (setq endmark (copy-marker end))
1226 (< (point) endmark))
1229 ;; Indent one line as with TAB.
1230 (let (nextline sexpend sexpbeg)
1232 (skip-chars-forward " \t\n")
1234 ;; indent the current line
1236 (setq fence (point))
1239 (looking-at "[ \t]*#"))
1242 ;; Find beginning of following line.
1243 (setq nextline (c-point 'bonl))
1244 ;; Find first beginning-of-sexp for sexp extending past
1247 (while (< (point) nextline)
1251 (setq sexpend (point)))
1252 (error (setq sexpend nil)
1253 (goto-char nextline)))
1254 (c-forward-syntactic-ws))
1257 ;; make sure the sexp we found really starts on the
1258 ;; current line and extends past it
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
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
1276 (> sexpend nextline)
1277 (<= sexpend endmark))
1280 (c-indent-exp 'shutup)
1282 (goto-char sexpend)))
1286 ;; Move to following line and try again.
1289 (set-marker sexpend nil))
1291 (setq fence (point))))))
1292 (set-marker endmark nil)
1293 (c-progress-fini 'c-indent-region)
1294 (c-echo-parsing-error)
1297 (defun c-mark-function ()
1298 "Put mark at end of a C, C++, or Objective-C defun, point at beginning."
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))
1306 (setq brace (car state))
1308 (goto-char (cdr brace))
1310 (setq state (cdr state)))
1311 (if (eq (char-after) ?{)
1314 (while (not (or (bobp)
1315 (looking-at "[ \t]*$")))
1318 (skip-chars-forward " \t\n"))
1320 (push-mark eod nil t)))
1323 ;; for progress reporting
1324 (defvar c-progress-info nil)
1326 (defun c-progress-init (start end context)
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]
1338 (t (setq c-progress-info (vector start
1342 (nth 1 (current-time))
1344 (message "indenting region..."))
1347 (defun c-progress-update ()
1349 (if (not (and c-progress-info c-progress-interval))
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))
1359 (message "indenting region... (%d%% complete)"
1360 (/ (* 100 (- (point) start)) (- end start)))
1361 (aset c-progress-info 2 now)))
1364 (defun c-progress-fini (context)
1366 (if (not c-progress-interval)
1368 (if (or (eq context (aref c-progress-info 3))
1371 (set-marker (aref c-progress-info 1) nil)
1372 (setq c-progress-info nil)
1373 (message "indenting region...done")))))
1377 ;;; This page handles insertion and removal of backslashes for C macros.
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.
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.
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")
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)
1400 (if (eq (char-before) ?\\)
1401 (progn (forward-char -1)
1402 (skip-chars-backward " \t")))
1403 (setq column (max column (1+ (current-column))))
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.
1412 (while (and (< (point) endmark) (eolp))
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.
1421 (< (point) endmark)))
1422 (c-append-backslash column)
1423 (c-delete-backslash))
1425 (move-marker endmark nil))))
1427 (defun c-append-backslash (column)
1429 (if (eq (char-before) ?\\)
1430 (progn (forward-char -1)
1431 (delete-horizontal-space)
1436 (defun c-delete-backslash ()
1441 (if (looking-at "\\\\")
1442 (delete-region (1+ (point))
1443 (progn (skip-chars-backward " \t") (point)))))))
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.
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:
1457 char description[] = \"\\
1458 A very long description of something that you want to fill to make
1459 nicely formatted output.\"\;
1461 If point is in any other situation, i.e. in normal code, do nothing.
1463 Optional prefix ARG means justify paragraph as well."
1465 (let* ((point-save (point-marker))
1469 ;; Check for obvious entry to comment.
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/*]*\\)"))
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
1483 (paragraph-start (concat paragraph-start re1 "$"))
1484 (paragraph-separate (concat paragraph-separate re1 "$")))
1487 ;; Move up to first line of this comment.
1488 (while (and (not (bobp))
1489 (looking-at "[ \t]*//[ \t]*[^ \t\n]"))
1491 (if (not (looking-at ".*//[ \t]*[^ \t\n]"))
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)
1501 ;; Narrow down to just the lines of this comment.
1502 (narrow-to-region (c-point 'bol)
1506 (looking-at (regexp-quote fill-prefix))
1510 ;; fill-paragraph sometimes fails to detect when we
1511 ;; are between paragraphs.
1513 (search-forward fill-prefix (c-point 'eol))
1514 (looking-at paragraph-separate))
1516 (let (fill-paragraph-function)
1517 (fill-paragraph arg))))))
1518 ;; else C style comments
1520 ;; t if we enter a comment between start of function and
1523 (setq limits (c-literal-limits))
1526 (goto-char (car limits))
1527 (looking-at c-comment-start-regexp))))
1528 ;; t if this line contains a comment starter.
1533 (re-search-forward comment-start-skip
1534 (save-excursion (end-of-line)
1537 (setq comment-start-place (point)))))
1538 ;; t if we're in the whitespace after a comment ender
1539 ;; which ends its line.
1541 (when (and (looking-at "[ \t]*$")
1544 (looking-at ".*\\*/[ \t]*$")))
1546 (forward-comment -1)
1547 (setq comment-start-place (point)))
1549 ;; Inside a comment: fill one comment paragraph.
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.
1556 (if (looking-at ".*/\\*.*\\*/")
1557 (progn (re-search-forward comment-start-skip)
1558 (make-string (current-column) ?\ ))
1561 (if (and (looking-at "[ \t]*\\*/")
1562 (not (save-excursion
1564 (looking-at ".*/\\*"))))
1567 (let ((line-width (progn (end-of-line) (current-column))))
1573 ;; How shall we decide where the end of the
1576 (skip-chars-forward " \t*" (c-point 'eol))
1577 ;; kludge alert, watch out for */, in
1578 ;; which case fill-prefix should *not*
1580 (if (and (eq (char-after) ?/)
1581 (eq (char-before) ?*))
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.
1599 ;; If you can see a better way to do this,
1600 ;; please make the change. This seems very
1602 (delete-region (progn (move-to-column line-width)
1604 (progn (end-of-line) (point))))))))
1606 ;; Lines containing just a comment start or just an end
1607 ;; should not be filled into paragraphs they are next
1609 (paragraph-start (if (eq major-mode 'java-mode)
1610 (concat paragraph-start
1612 c-Java-javadoc-paragraph-start
1614 (concat paragraph-start re1 "$")))
1615 (paragraph-separate (concat paragraph-separate re1 "$"))
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)
1631 (concat c-comment-start-regexp
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)))
1640 (setq chars-to-delete column)
1641 (insert-char ?\ column))))
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)
1649 (looking-at "[ \t]*\\*/")))
1654 ;; fill-paragraph sometimes fails to detect when we
1655 ;; are between paragraphs.
1657 (search-forward fill-prefix (c-point 'eol))
1658 (looking-at paragraph-separate))
1660 (let (fill-paragraph-function)
1661 (fill-paragraph arg)))
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))
1673 (search-forward "*/" nil 'move)
1675 (if (and c-hanging-comment-ender-p
1676 (looking-at "[ \t]*\\*/"))
1677 ;(delete-indentation)))))
1678 (let ((fill-column (+ fill-column 9999)))
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
1685 (goto-char (- (point-max) 2))
1686 (if (not (= (char-before) ?*))
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.
1693 (eq (char-syntax (char-after (car limits))) ?\")
1695 (goto-char (car limits))
1697 (< (point) (cdr limits))))
1699 fill-paragraph-function)
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
1710 (goto-char (1- (cdr limits)))
1711 ;; Inserting a newline and
1712 ;; removing it again after
1713 ;; fill-paragraph makes it more
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)))
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.
1733 ;;; cc-cmds.el ends here