1 ;;; cc-cmds.el --- user level commands for CC Mode
3 ;; Copyright (C) 1985,87,92,93,94,95,96,97 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)
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.
34 (defun c-calculate-state (arg prevstate)
35 ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
36 ;; arg is nil or zero, toggle the state. If arg is negative, turn
37 ;; the state off, and if arg is positive, turn the state on
39 (zerop (setq arg (prefix-numeric-value arg))))
43 ;; Auto-newline and hungry-delete
44 (defun c-toggle-auto-state (arg)
45 "Toggle auto-newline feature.
46 Optional numeric ARG, if supplied turns on auto-newline when positive,
47 turns it off when negative, and just toggles it when zero.
49 When the auto-newline feature is enabled (as evidenced by the `/a' or
50 `/ah' on the modeline after the mode name) newlines are automatically
51 inserted after special characters such as brace, comma, semi-colon,
54 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
56 (c-keep-region-active))
58 (defun c-toggle-hungry-state (arg)
59 "Toggle hungry-delete-key feature.
60 Optional numeric ARG, if supplied turns on hungry-delete when positive,
61 turns it off when negative, and just toggles it when zero.
63 When the hungry-delete-key feature is enabled (as evidenced by the
64 `/h' or `/ah' on the modeline after the mode name) the delete key
65 gobbles all preceding whitespace in one fell swoop."
67 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
69 (c-keep-region-active))
71 (defun c-toggle-auto-hungry-state (arg)
72 "Toggle auto-newline and hungry-delete-key features.
73 Optional numeric ARG, if supplied turns on auto-newline and
74 hungry-delete when positive, turns them off when negative, and just
75 toggles them when zero.
77 See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
79 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
80 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
82 (c-keep-region-active))
87 ;; Note: In XEmacs 20.3 the Delete and BackSpace keysyms have been
88 ;; separated and "\177" is no longer an alias for both keys. Also,
89 ;; the variable delete-key-deletes-forward controls in which direction
90 ;; the Delete keysym deletes characters. The functions
91 ;; c-electric-delete and c-electric-backspace attempt to deal with
92 ;; this new functionality. For Emacs 19 and XEmacs 19 backwards
93 ;; compatibility, the old behavior has moved to c-electric-backspace
94 ;; and c-backspace-function.
96 (defun c-electric-backspace (arg)
97 "Deletes preceding character or whitespace.
98 If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
99 \"/ah\" string on the mode line, then all preceding whitespace is
100 consumed. If however an ARG is supplied, or `c-hungry-delete-key' is
101 nil, or point is inside a literal then the function in the variable
102 `c-backspace-function' is called.
104 See also \\[c-electric-delete]."
106 (if (or (not c-hungry-delete-key)
109 (funcall c-backspace-function (prefix-numeric-value arg))
110 (let ((here (point)))
111 (skip-chars-backward " \t\n")
112 (if (/= (point) here)
113 (delete-region (point) here)
114 (funcall c-backspace-function 1)
117 (defun c-electric-delete (arg)
118 "Deletes preceding or following character or whitespace.
120 The behavior of this function depends on the variable
121 `delete-key-deletes-forward'. If this variable is nil (or does not
122 exist, as in older Emacsen), then this function behaves identical to
123 \\[c-electric-backspace].
125 If `delete-key-deletes-forward' is non-nil, then deletion occurs in
126 the forward direction. So if `c-hungry-delete-key' is non-nil, as
127 evidenced by the \"/h\" or \"/ah\" string on the mode line, then all
128 following whitespace is consumed. If however an ARG is supplied, or
129 `c-hungry-delete-key' is nil, or point is inside a literal then the
130 function in the variable `c-delete-function' is called."
132 (if (and (boundp 'delete-key-deletes-forward)
133 delete-key-deletes-forward)
134 (if (or (not c-hungry-delete-key)
137 (funcall c-delete-function (prefix-numeric-value arg))
138 (let ((here (point)))
139 (skip-chars-forward " \t\n")
140 (if (/= (point) here)
141 (delete-region (point) here)
142 (funcall c-delete-function 1))))
143 ;; act just like c-electric-backspace
144 (c-electric-backspace arg)))
146 (defun c-electric-pound (arg)
147 "Electric pound (`#') insertion.
148 Inserts a `#' character specially depending on the variable
149 `c-electric-pound-behavior'. If a numeric ARG is supplied, or if
150 point is inside a literal, nothing special happens."
152 (if (or (c-in-literal)
154 (not (memq 'alignleft c-electric-pound-behavior)))
155 ;; do nothing special
156 (self-insert-command (prefix-numeric-value arg))
157 ;; place the pound character at the left edge
158 (let ((pos (- (point-max) (point)))
161 (delete-horizontal-space)
162 (insert-char last-command-char 1)
164 (goto-char (- (point-max) pos)))
167 (defun c-electric-brace (arg)
170 If the auto-newline feature is turned on, as evidenced by the \"/a\"
171 or \"/ah\" string on the mode line, newlines are inserted before and
172 after braces based on the value of `c-hanging-braces-alist'.
174 Also, the line is re-indented unless a numeric ARG is supplied, there
175 are non-whitespace characters present on the line after the brace, or
176 the brace is inserted inside a literal."
178 (let* ((c-state-cache (c-parse-state))
179 (safepos (c-safe-position (point) c-state-cache))
180 (literal (c-in-literal safepos)))
181 ;; if we're in a literal, or we're not at the end of the line, or
182 ;; a numeric arg is provided, or auto-newlining is turned off,
183 ;; then just insert the character.
185 ; (not c-auto-newline)
186 (not (looking-at "[ \t]*$")))
187 (self-insert-command (prefix-numeric-value arg))
188 (let* ((syms '(class-open class-close defun-open defun-close
189 inline-open inline-close brace-list-open brace-list-close
190 brace-list-intro brace-list-entry block-open block-close
191 substatement-open statement-case-open
192 extern-lang-open extern-lang-close))
193 ;; we want to inhibit blinking the paren since this will
194 ;; be most disruptive. we'll blink it ourselves later on
195 (old-blink-paren blink-paren-function)
197 (insertion-point (point))
199 (preserve-p (and (not (bobp))
200 (eq ?\ (char-syntax (char-before)))))
202 (c-echo-syntactic-information-p nil)
204 ;; only insert a newline if there is
205 ;; non-whitespace behind us
207 (skip-chars-backward " \t")
210 (setq delete-temp-newline t)))
211 (self-insert-command (prefix-numeric-value arg))
212 ;; state cache doesn't change
213 (c-guess-basic-syntax)))
216 (or (c-lookup-lists syms syntax c-hanging-braces-alist)
217 '(ignore before after)))))
218 ;; If syntax is a function symbol, then call it using the
219 ;; defined semantics.
220 (if (and (not (consp (cdr newlines)))
221 (functionp (cdr newlines)))
222 (let ((c-syntactic-context syntax))
224 (funcall (cdr newlines) (car newlines) insertion-point))))
225 ;; does a newline go before the open brace?
226 (if (memq 'before newlines)
227 ;; we leave the newline we've put in there before,
228 ;; but we need to re-indent the line above
229 (let ((pos (- (point-max) (point)))
231 (c-state-cache c-state-cache))
233 ;; we may need to update the cache. this should still be
234 ;; faster than recalculating the state in many cases
237 (narrow-to-region here (point))
238 (if (and (c-safe (progn (backward-up-list -1) t))
239 (memq (char-before) '(?\) ?}))
241 (c-safe (progn (forward-sexp -1) t))))
243 (c-hack-state (point) 'open c-state-cache))
244 (if (and (car c-state-cache)
245 (not (consp (car c-state-cache)))
246 (<= (point) (car c-state-cache)))
247 (setq c-state-cache (cdr c-state-cache))
250 (shift (c-indent-line)))
251 (setq c-state-cache (c-adjust-state (c-point 'bol) here
252 (- shift) c-state-cache)))
253 (goto-char (- (point-max) pos))
254 ;; if the buffer has changed due to the indentation, we
255 ;; need to recalculate syntax for the current line, but
256 ;; we won't need to update the state cache.
257 (if (/= (point) here)
258 (setq syntax (c-guess-basic-syntax))))
259 ;; must remove the newline we just stuck in (if we really did it)
260 (and delete-temp-newline
262 ;; if there is whitespace before point, then preserve
263 ;; at least one space.
268 ;; since we're hanging the brace, we need to recalculate
269 ;; syntax. Update the state to accurately reflect the
270 ;; beginning of the line. We punt if we cross any open or
271 ;; closed parens because its just too hard to modify the
272 ;; known state. This limitation will be fixed in v5.
274 (let ((bol (c-point 'bol)))
275 (if (zerop (car (parse-partial-sexp bol (1- (point)))))
276 (setq c-state-cache (c-whack-state bol c-state-cache)
277 syntax (c-guess-basic-syntax))
278 ;; gotta punt. this requires some horrible kludgery
280 (makunbound 'c-state-cache)
281 (setq c-state-cache (c-parse-state)
284 ;; now adjust the line's indentation. don't update the state
285 ;; cache since c-guess-basic-syntax isn't called when the
286 ;; syntax is passed to c-indent-line
288 (shift (c-indent-line syntax)))
289 (setq c-state-cache (c-adjust-state (c-point 'bol) here
290 (- shift) c-state-cache)))
291 ;; Do all appropriate clean ups
293 (pos (- (point-max) (point)))
295 ;; clean up empty defun braces
296 (if (and c-auto-newline
297 (memq 'empty-defun-braces c-cleanup-list)
298 (eq last-command-char ?\})
299 (c-intersect-lists '(defun-close class-close inline-close)
303 (skip-chars-backward " \t\n")
304 (eq (char-before) ?\{))
305 ;; make sure matching open brace isn't in a comment
306 (not (c-in-literal)))
307 (delete-region (point) (1- here)))
308 ;; clean up brace-else-brace
309 (if (and c-auto-newline
310 (memq 'brace-else-brace c-cleanup-list)
311 (eq last-command-char ?\{)
312 (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
314 (setq mbeg (match-beginning 0)
317 (not (c-in-literal)))
319 (delete-region mbeg mend)
320 (insert "} else {")))
321 ;; clean up brace-elseif-brace
322 (if (and c-auto-newline
323 (memq 'brace-elseif-brace c-cleanup-list)
324 (eq last-command-char ?\{)
325 (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*" nil t)
327 (goto-char (match-end 0))
328 (c-safe (forward-sexp 1))
329 (skip-chars-forward " \t\n")
330 (setq mbeg (match-beginning 0)
332 (= here (1+ (point))))
333 (not (c-in-literal)))
335 (delete-region mbeg mend)
336 (insert "} else if ")))
337 (goto-char (- (point-max) pos))
339 ;; does a newline go after the brace?
340 (if (memq 'after newlines)
343 ;; update on c-state-cache
344 (let* ((bufpos (- (point) 2))
345 (which (if (eq (char-after bufpos) ?{) 'open 'close))
346 (c-state-cache (c-hack-state bufpos which c-state-cache)))
349 (and (eq last-command-char ?\})
352 (c-backward-syntactic-ws safepos)
353 (funcall old-blink-paren)))
356 (defun c-electric-slash (arg)
357 "Insert a slash character.
359 Indent the line as a comment, if:
361 1. The slash is second of a `//' line oriented comment introducing
362 token and we are on a comment-only-line, or
364 2. The slash is part of a `*/' token that closes a block oriented
367 If numeric ARG is supplied or point is inside a literal, indentation
370 (let* ((ch (char-before))
371 (indentp (and (not arg)
372 (eq last-command-char ?/)
374 (not (c-in-literal)))
379 (c-echo-syntactic-information-p nil))
380 (self-insert-command (prefix-numeric-value arg))
384 (defun c-electric-star (arg)
385 "Insert a star character.
386 If the star is the second character of a C style comment introducing
387 construct, and we are on a comment-only-line, indent line as comment.
388 If numeric ARG is supplied or point is inside a literal, indentation
391 (self-insert-command (prefix-numeric-value arg))
392 ;; if we are in a literal, or if arg is given do not re-indent the
393 ;; current line, unless this star introduces a comment-only line.
395 (memq (c-in-literal) '(c))
396 (eq (char-before) ?*)
399 (skip-chars-backward "*")
400 (if (eq (char-before) ?/)
402 (skip-chars-backward " \t")
405 (let (c-echo-syntactic-information-p)
409 (defun c-electric-semi&comma (arg)
410 "Insert a comma or semicolon.
411 When the auto-newline feature is turned on, as evidenced by the \"/a\"
412 or \"/ah\" string on the mode line, a newline might be inserted. See
413 the variable `c-hanging-semi&comma-criteria' for how newline insertion
416 When semicolon is inserted, the line is re-indented unless a numeric
417 arg is supplied, point is inside a literal, or there are
418 non-whitespace characters on the line following the semicolon."
420 (let* ((lim (c-most-enclosing-brace (c-parse-state)))
421 (literal (c-in-literal lim))
424 (c-echo-syntactic-information-p nil))
427 (not (looking-at "[ \t]*$")))
428 (self-insert-command (prefix-numeric-value arg))
429 ;; do some special stuff with the character
430 (self-insert-command (prefix-numeric-value arg))
431 ;; do all cleanups, reindentations, and newline insertions, but
432 ;; only if c-auto-newline is turned on
433 (if (not c-auto-newline) nil
435 (let ((pos (- (point-max) (point))))
437 (eq last-command-char ?,)
438 (memq 'list-close-comma c-cleanup-list))
440 (eq last-command-char ?\;)
441 (memq 'defun-close-semi c-cleanup-list)))
444 (skip-chars-backward " \t\n")
445 (eq (char-before) ?}))
446 ;; make sure matching open brace isn't in a comment
447 (not (c-in-literal lim)))
448 (delete-region (point) here))
449 (goto-char (- (point-max) pos)))
452 ;; check to see if a newline should be added
453 (let ((criteria c-hanging-semi&comma-criteria)
454 answer add-newline-p)
456 (setq answer (funcall (car criteria)))
457 ;; only nil value means continue checking
459 (setq criteria (cdr criteria))
461 ;; only 'stop specifically says do not add a newline
462 (setq add-newline-p (not (eq answer 'stop)))
469 (defun c-electric-colon (arg)
472 If the auto-newline feature is turned on, as evidenced by the \"/a\"
473 or \"/ah\" string on the mode line, newlines are inserted before and
474 after colons based on the value of `c-hanging-colons-alist'.
476 Also, the line is re-indented unless a numeric ARG is supplied, there
477 are non-whitespace characters present on the line after the colon, or
478 the colon is inserted inside a literal.
480 This function cleans up double colon scope operators based on the
481 value of `c-cleanup-list'."
483 (let* ((bod (c-point 'bod))
484 (literal (c-in-literal bod))
487 (c-echo-syntactic-information-p nil))
490 (not (looking-at "[ \t]*$")))
491 (self-insert-command (prefix-numeric-value arg))
492 ;; insert the colon, then do any specified cleanups
493 (self-insert-command (prefix-numeric-value arg))
494 (let ((pos (- (point-max) (point)))
496 (if (and c-auto-newline
497 (memq 'scope-operator c-cleanup-list)
498 (eq (char-before) ?:)
501 (skip-chars-backward " \t\n")
502 (eq (char-before) ?:))
504 (not (eq (char-after (- (point) 2)) ?:)))
505 (delete-region (point) (1- here)))
506 (goto-char (- (point-max) pos)))
507 ;; lets do some special stuff with the colon character
508 (setq syntax (c-guess-basic-syntax)
509 ;; some language elements can only be determined by
510 ;; checking the following line. Lets first look for ones
511 ;; that can be found when looking on the line with the
515 (or (c-lookup-lists '(case-label label access-label)
516 syntax c-hanging-colons-alist)
517 (c-lookup-lists '(member-init-intro inher-intro)
520 (c-guess-basic-syntax)
522 c-hanging-colons-alist))))
523 ;; indent the current line
524 (c-indent-line syntax)
525 ;; does a newline go before the colon? Watch out for already
526 ;; non-hung colons. However, we don't unhang them because that
527 ;; would be a cleanup (and anti-social).
528 (if (and (memq 'before newlines)
530 (skip-chars-backward ": \t")
532 (let ((pos (- (point-max) (point))))
536 (goto-char (- (point-max) pos))))
537 ;; does a newline go after the colon?
538 (if (memq 'after (cdr-safe newlines))
544 (defun c-electric-lt-gt (arg)
545 "Insert a less-than, or greater-than character.
546 When the auto-newline feature is turned on, as evidenced by the \"/a\"
547 or \"/ah\" string on the mode line, the line will be re-indented if
548 the character inserted is the second of a C++ style stream operator
549 and the buffer is in C++ mode.
551 The line will also not be re-indented if a numeric argument is
552 supplied, or point is inside a literal."
554 (let ((indentp (and (not arg)
555 (eq (char-before) last-command-char)
556 (not (c-in-literal))))
558 (c-echo-syntactic-information-p nil))
559 (self-insert-command (prefix-numeric-value arg))
565 ;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
566 ;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com
567 (defun c-forward-into-nomenclature (&optional arg)
568 "Move forward to end of a nomenclature section or word.
569 With arg, to it arg times."
571 (let ((case-fold-search nil))
573 (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg)
574 (while (and (< arg 0)
576 "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)"
579 (setq arg (1+ arg)))))
580 (c-keep-region-active))
582 (defun c-backward-into-nomenclature (&optional arg)
583 "Move backward to beginning of a nomenclature section or word.
584 With optional ARG, move that many times. If ARG is negative, move
587 (c-forward-into-nomenclature (- arg))
588 (c-keep-region-active))
590 (defun c-scope-operator ()
591 "Insert a double colon scope operator at point.
592 No indentation or other \"electric\" behavior is performed."
597 (defun c-beginning-of-statement (&optional count lim sentence-flag)
598 "Go to the beginning of the innermost C statement.
599 With prefix arg, go back N - 1 statements. If already at the
600 beginning of a statement then go to the beginning of the preceding
601 one. If within a string or comment, or next to a comment (only
602 whitespace between), move by sentences instead of statements.
604 When called from a program, this function takes 3 optional args: the
605 repetition count, a buffer position limit which is the farthest back
606 to search, and a flag saying whether to do sentence motion when in a
608 (interactive (list (prefix-numeric-value current-prefix-arg)
612 (lim (or lim (c-point 'bod)))
616 (setq state (parse-partial-sexp (point) here nil nil)))
617 (if (and sentence-flag
620 ;; skipping forward into a comment?
623 (skip-chars-forward " \t\n")
625 (looking-at comment-start-skip))))
628 (skip-chars-backward " \t\n")
629 (goto-char (- (point) 2))
630 (looking-at "\\*/")))))
631 (forward-sentence (- count))
633 (c-beginning-of-statement-1 lim)
634 (setq count (1- count)))
636 (c-end-of-statement-1)
637 (setq count (1+ count))))
638 ;; its possible we've been left up-buf of lim
639 (goto-char (max (point) lim))
641 (c-keep-region-active))
643 (defun c-end-of-statement (&optional count lim sentence-flag)
644 "Go to the end of the innermost C statement.
646 With prefix arg, go forward N - 1 statements. Move forward to end of
647 the next statement if already at end. If within a string or comment,
648 move by sentences instead of statements.
650 When called from a program, this function takes 3 optional args: the
651 repetition count, a buffer position limit which is the farthest back
652 to search, and a flag saying whether to do sentence motion when in a
654 (interactive (list (prefix-numeric-value current-prefix-arg)
656 (c-beginning-of-statement (- (or count 1)) lim sentence-flag)
657 (c-keep-region-active))
660 ;; set up electric character functions to work with pending-del,
661 ;; (a.k.a. delsel) mode. All symbols get the t value except
662 ;; the functions which delete, which gets 'supersede.
666 (put sym 'delete-selection t) ; for delsel (Emacs)
667 (put sym 'pending-delete t))) ; for pending-del (XEmacs)
672 c-electric-semi&comma
675 (put 'c-electric-delete 'delete-selection 'supersede) ; delsel
676 (put 'c-electric-delete 'pending-delete 'supersede) ; pending-del
677 (put 'c-electric-backspace 'delete-selection 'supersede) ; delsel
678 (put 'c-electric-backspace 'pending-delete 'supersede) ; pending-del
681 ;; This is used by indent-for-comment to decide how much to indent a
682 ;; comment in C code based on its context.
683 (defun c-comment-indent ()
684 (if (looking-at (concat "^\\(" c-comment-start-regexp "\\)"))
685 0 ;Existing comment at bol stays there.
686 (let ((opoint (point))
691 ;; CASE 1: A comment following a solitary close-brace should
692 ;; have only one space.
693 ((looking-at (concat "[ \t]*}[ \t]*\\($\\|"
694 c-comment-start-regexp
697 (1+ (current-column)))
698 ;; CASE 2: 2 spaces after #endif
699 ((or (looking-at "^#[ \t]*endif[ \t]*")
700 (looking-at "^#[ \t]*else[ \t]*"))
702 ;; CASE 3: when comment-column is nil, calculate the offset
703 ;; according to c-offsets-alist. E.g. identical to hitting
705 ((and c-indent-comments-syntactically-p
707 (skip-chars-forward " \t")
708 (or (looking-at comment-start)
710 (let ((syntax (c-guess-basic-syntax)))
711 ;; BOGOSITY ALERT: if we're looking at the eol, its
712 ;; because indent-for-comment hasn't put the comment-start
713 ;; in the buffer yet. this will screw up the syntactic
714 ;; analysis so we kludge in the necessary info. Another
715 ;; kludge is that if we're at the bol, then we really want
716 ;; to ignore any anchoring as specified by
717 ;; c-comment-only-line-offset since it doesn't apply here.
720 (skip-chars-forward " \t")
722 (c-add-syntax 'comment-intro))
723 (let ((c-comment-only-line-offset
724 (if (consp c-comment-only-line-offset)
725 c-comment-only-line-offset
726 (cons c-comment-only-line-offset
727 c-comment-only-line-offset))))
728 (apply '+ (mapcar 'c-get-offset syntax)))))
729 ;; CASE 4: use comment-column if previous line is a
730 ;; comment-only line indented to the left of comment-column
735 (skip-chars-forward " \t")
737 (looking-at c-comment-start-regexp)
738 (setq placeholder (point))))
739 (goto-char placeholder)
740 (if (< (current-column) comment-column)
743 ;; CASE 5: If comment-column is 0, and nothing but space
744 ;; before the comment, align it at 0 rather than 1.
747 (skip-chars-backward " \t")
748 (and (= comment-column 0) (bolp)))
750 ;; CASE 6: indent at comment column except leave at least one
752 (t (max (1+ (current-column))
757 ;; for proposed new variable comment-line-break-function
758 (defun c-comment-line-break-function (&optional soft)
759 ;; we currently don't do anything with soft line breaks
760 (let ((literal (c-in-literal)))
762 ((eq literal 'string))
763 ((or (not c-comment-continuation-stars)
765 (indent-new-comment-line soft))
766 (t (let ((here (point))
767 (leader c-comment-continuation-stars))
768 (back-to-indentation)
769 ;; are we looking at a block or lines style comment?
770 (if (and (looking-at (concat "\\(" c-comment-start-regexp
772 (string-equal (match-string 1) "//"))
776 (delete-region (progn (skip-chars-backward " \t") (point))
777 (progn (skip-chars-forward " \t") (point)))
779 ;; to avoid having an anchored comment that c-indent-line will
784 ;; advice for indent-new-comment-line for older Emacsen
785 (if (boundp 'comment-line-break-function)
788 (defadvice indent-new-comment-line (around c-line-break-advice activate)
789 (if (or (not c-buffer-is-cc-mode)
791 (not c-comment-continuation-stars))
793 (c-comment-line-break-function (ad-get-arg 0)))))
795 ;; used by outline-minor-mode
796 (defun c-outline-level ()
798 (skip-chars-forward "\t ")
802 (defun c-up-conditional (count)
803 "Move back to the containing preprocessor conditional, leaving mark behind.
804 A prefix argument acts as a repeat count. With a negative argument,
805 move forward to the end of the containing preprocessor conditional.
806 When going backwards, `#elif' is treated like `#else' followed by
807 `#if'. When going forwards, `#elif' is ignored."
809 (c-forward-conditional (- count) t)
810 (c-keep-region-active))
812 (defun c-backward-conditional (count &optional up-flag)
813 "Move back across a preprocessor conditional, leaving mark behind.
814 A prefix argument acts as a repeat count. With a negative argument,
815 move forward across a preprocessor conditional."
817 (c-forward-conditional (- count) up-flag)
818 (c-keep-region-active))
820 (defun c-forward-conditional (count &optional up-flag)
821 "Move forward across a preprocessor conditional, leaving mark behind.
822 A prefix argument acts as a repeat count. With a negative argument,
823 move backward across a preprocessor conditional."
825 (let* ((forward (> count 0))
826 (increment (if forward -1 1))
827 (search-function (if forward 're-search-forward 're-search-backward))
831 (let ((depth (if up-flag 0 -1)) found)
833 ;; Find the "next" significant line in the proper direction.
834 (while (and (not found)
835 ;; Rather than searching for a # sign that
836 ;; comes at the beginning of a line aside from
837 ;; whitespace, search first for a string
838 ;; starting with # sign. Then verify what
839 ;; precedes it. This is faster on account of
840 ;; the fastmap feature of the regexp matcher.
841 (funcall search-function
842 "#[ \t]*\\(if\\|elif\\|endif\\)"
845 ;; Now verify it is really a preproc line.
846 (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
848 ;; Update depth according to what we found.
850 (cond ((looking-at "[ \t]*#[ \t]*endif")
851 (setq depth (+ depth increment)))
852 ((looking-at "[ \t]*#[ \t]*elif")
853 (if (and forward (= depth 0))
854 (setq found (point))))
855 (t (setq depth (- depth increment))))
856 ;; If we are trying to move across, and we find an
857 ;; end before we find a beginning, get an error.
858 (if (and (< prev 0) (< depth prev))
860 "No following conditional at this level"
861 "No previous conditional at this level")))
862 ;; When searching forward, start from next line so
863 ;; that we don't find the same line again.
864 (if forward (forward-line 1))
865 ;; If this line exits a level of conditional, exit
868 (setq found (point))))
870 (if forward (forward-line 1))
873 (error "No containing preprocessor conditional"))
874 (goto-char (setq new found)))
875 (setq count (+ count increment))))
878 (c-keep-region-active))
881 ;; commands to indent lines, regions, defuns, and expressions
882 (defun c-indent-command (&optional whole-exp)
883 "Indent current line as C code, and/or insert some whitespace.
885 If `c-tab-always-indent' is t, always just indent the current line.
886 If nil, indent the current line only if point is at the left margin or
887 in the line's indentation; otherwise insert some whitespace[*]. If
888 other than nil or t, then some whitespace[*] is inserted only within
889 literals (comments and strings) and inside preprocessor directives,
890 but the line is always reindented.
892 A numeric argument, regardless of its value, means indent rigidly all
893 the lines of the expression starting after point so that this line
894 becomes properly indented. The relative indentation among the lines
895 of the expression are preserved.
897 [*] The amount and kind of whitespace inserted is controlled by the
898 variable `c-insert-tab-function', which is called to do the actual
899 insertion of whitespace. Normally the function in this variable
900 just inserts a tab character, or the equivalent number of spaces,
901 depending on the variable `indent-tabs-mode'."
904 (let ((bod (c-point 'bod)))
906 ;; If arg, always indent this line as C
907 ;; and shift remaining lines of expression the same amount.
908 (let ((shift-amt (c-indent-line))
911 (if (eq c-tab-always-indent t)
920 (indent-code-rigidly beg end (- shift-amt) "#")))
921 ;; No arg supplied, use c-tab-always-indent to determine
924 ;; CASE 1: indent when at column zero or in lines indentation,
925 ;; otherwise insert a tab
926 ((not c-tab-always-indent)
928 (skip-chars-backward " \t")
930 (funcall c-insert-tab-function)
932 ;; CASE 2: just indent the line
933 ((eq c-tab-always-indent t)
935 ;; CASE 3: if in a literal, insert a tab, but always indent the
938 (if (c-in-literal bod)
939 (funcall c-insert-tab-function))
943 (defun c-indent-exp (&optional shutup-p)
944 "Indent each line in balanced expression following point.
945 Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
950 (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
952 ;; try to be smarter about finding the range of
953 ;; lines to indent. skip all following
954 ;; whitespace. failing that, try to find any
955 ;; opening brace on the current line
956 (skip-chars-forward " \t\n")
957 (if (memq (char-after) '(?\( ?\[ ?\{))
959 (let ((state (parse-partial-sexp (point)
962 (goto-char (nth 1 state))
963 (memq (char-after) '(?\( ?\[ ?\{))
965 ;; find balanced expression end
966 (setq end (and (c-safe (progn (forward-sexp 1) t))
971 (error "Cannot find start of balanced expression to indent."))
974 (error "Cannot find end of balanced expression to indent."))
975 (c-progress-init start end 'c-indent-exp)
979 (while (< (point) end)
980 (if (not (looking-at "[ \t]*$"))
984 ;; make sure marker is deleted
986 (set-marker end nil))
988 (c-progress-fini 'c-indent-exp))
991 (defun c-indent-defun ()
992 "Re-indents the current top-level function def, struct or class declaration."
994 (let ((here (point-marker))
995 (c-echo-syntactic-information-p nil)
996 (brace (c-least-enclosing-brace (c-parse-state))))
999 (beginning-of-defun))
1000 ;; if we're sitting at b-o-b, it might be because there was no
1001 ;; least enclosing brace and we were sitting on the defun's open
1003 (if (and (bobp) (not (eq (char-after) ?\{)))
1005 ;; if defun-prompt-regexp is non-nil, b-o-d might not leave us at
1006 ;; the open brace. I consider this an Emacs bug.
1007 (and (boundp 'defun-prompt-regexp)
1009 (looking-at defun-prompt-regexp)
1010 (goto-char (match-end 0)))
1011 ;; catch all errors in c-indent-exp so we can 1. give more
1012 ;; meaningful error message, and 2. restore point
1016 (set-marker here nil))))
1018 (defun c-indent-region (start end)
1019 ;; Indent every line whose first char is between START and END inclusive.
1022 ;; Advance to first nonblank line.
1023 (skip-chars-forward " \t\n")
1027 (let ((c-tab-always-indent t)
1028 ;; shut up any echo msgs on indiv lines
1029 (c-echo-syntactic-information-p nil)
1031 (c-progress-init start end 'c-indent-region)
1032 (setq endmark (copy-marker end))
1035 (< (point) endmark))
1038 ;; Indent one line as with TAB.
1039 (let (nextline sexpend sexpbeg)
1041 (skip-chars-forward " \t\n")
1043 ;; indent the current line
1045 (setq fence (point))
1048 (looking-at "[ \t]*#"))
1051 ;; Find beginning of following line.
1052 (setq nextline (c-point 'bonl))
1053 ;; Find first beginning-of-sexp for sexp extending past
1056 (while (< (point) nextline)
1060 (setq sexpend (point)))
1061 (error (setq sexpend nil)
1062 (goto-char nextline)))
1063 (c-forward-syntactic-ws))
1066 ;; make sure the sexp we found really starts on the
1067 ;; current line and extends past it
1069 (setq sexpend (point-marker))
1070 (c-safe (backward-sexp 1))
1071 (setq sexpbeg (point))))
1072 (if (and sexpbeg (< sexpbeg fence))
1073 (setq sexpbeg fence)))
1074 ;; check to see if the next line starts a
1075 ;; comment-only line
1078 (skip-chars-forward " \t")
1079 (if (looking-at c-comment-start-regexp)
1080 (setq sexpbeg (c-point 'bol))))
1081 ;; If that sexp ends within the region, indent it all at
1085 (> sexpend nextline)
1086 (<= sexpend endmark))
1089 (c-indent-exp 'shutup)
1091 (goto-char sexpend)))
1095 ;; Move to following line and try again.
1098 (set-marker sexpend nil))
1100 (setq fence (point))))))
1101 (set-marker endmark nil)
1102 (c-progress-fini 'c-indent-region)
1103 (c-echo-parsing-error)
1106 (defun c-mark-function ()
1107 "Put mark at end of a C, C++, or Objective-C defun, point at beginning."
1109 (let ((here (point))
1110 ;; there should be a c-point position for 'eod
1111 (eod (save-excursion (end-of-defun) (point)))
1112 (state (c-parse-state))
1115 (setq brace (car state))
1117 (goto-char (cdr brace))
1119 (setq state (cdr state)))
1120 (if (eq (char-after) ?{)
1123 (while (not (or (bobp)
1124 (looking-at "[ \t]*$")))
1127 (skip-chars-forward " \t\n"))
1129 (push-mark eod nil t)))
1132 ;; for progress reporting
1133 (defvar c-progress-info nil)
1135 (defun c-progress-init (start end context)
1136 ;; start the progress update messages. if this emacs doesn't have a
1137 ;; built-in timer, just be dumb about it
1138 (if (not (fboundp 'current-time))
1139 (message "indenting region... (this may take a while)")
1140 ;; if progress has already been initialized, do nothing. otherwise
1141 ;; initialize the counter with a vector of:
1142 ;; [start end lastsec context]
1145 (setq c-progress-info (vector start
1149 (nth 1 (current-time))
1151 (message "indenting region..."))))
1153 (defun c-progress-update ()
1155 (if (not (and c-progress-info c-progress-interval))
1157 (let ((now (nth 1 (current-time)))
1158 (start (aref c-progress-info 0))
1159 (end (aref c-progress-info 1))
1160 (lastsecs (aref c-progress-info 2)))
1161 ;; should we update? currently, update happens every 2 seconds,
1162 ;; what's the right value?
1163 (if (< c-progress-interval (- now lastsecs))
1165 (message "indenting region... (%d%% complete)"
1166 (/ (* 100 (- (point) start)) (- end start)))
1167 (aset c-progress-info 2 now)))
1170 (defun c-progress-fini (context)
1172 (if (or (eq context (aref c-progress-info 3))
1175 (set-marker (aref c-progress-info 1) nil)
1176 (setq c-progress-info nil)
1177 (message "indenting region...done"))))
1181 ;;; This page handles insertion and removal of backslashes for C macros.
1183 (defun c-backslash-region (from to delete-flag)
1184 "Insert, align, or delete end-of-line backslashes on the lines in the region.
1185 With no argument, inserts backslashes and aligns existing backslashes.
1186 With an argument, deletes the backslashes.
1188 This function does not modify blank lines at the start of the region.
1189 If the region ends at the start of a line, it always deletes the
1190 backslash (if any) at the end of the previous line.
1192 You can put the region around an entire macro definition and use this
1193 command to conveniently insert and align the necessary backslashes."
1194 (interactive "r\nP")
1197 (let ((column c-backslash-column)
1198 (endmark (make-marker)))
1199 (move-marker endmark to)
1200 ;; Compute the smallest column number past the ends of all the lines.
1201 (if (not delete-flag)
1202 (while (< (point) to)
1204 (if (eq (char-before) ?\\)
1205 (progn (forward-char -1)
1206 (skip-chars-backward " \t")))
1207 (setq column (max column (1+ (current-column))))
1209 ;; Adjust upward to a tab column, if that doesn't push past the margin.
1210 (if (> (% column tab-width) 0)
1211 (let ((adjusted (* (/ (+ column tab-width -1) tab-width) tab-width)))
1212 (if (< adjusted (window-width))
1213 (setq column adjusted))))
1214 ;; Don't modify blank lines at start of region.
1216 (while (and (< (point) endmark) (eolp))
1218 ;; Add or remove backslashes on all the lines.
1219 (while (< (point) endmark)
1220 (if (and (not delete-flag)
1221 ;; Un-backslashify the last line
1222 ;; if the region ends right at the start of the next line.
1225 (< (point) endmark)))
1226 (c-append-backslash column)
1227 (c-delete-backslash))
1229 (move-marker endmark nil)))
1230 (c-keep-region-active))
1232 (defun c-append-backslash (column)
1234 (if (eq (char-before) ?\\)
1235 (progn (forward-char -1)
1236 (delete-horizontal-space)
1241 (defun c-delete-backslash ()
1246 (if (looking-at "\\\\")
1247 (delete-region (1+ (point))
1248 (progn (skip-chars-backward " \t") (point)))))))
1251 (defun c-fill-paragraph (&optional arg)
1252 "Like \\[fill-paragraph] but handles C and C++ style comments.
1253 If any of the current line is a comment or within a comment,
1254 fill the comment or the paragraph of it that point is in,
1255 preserving the comment indentation or line-starting decorations.
1257 Optional prefix ARG means justify paragraph as well."
1259 (let* (comment-start-place
1261 ;; Check for obvious entry to comment.
1264 (skip-chars-forward " \t\n")
1265 (and (looking-at comment-start-skip)
1266 (setq comment-start-place (point)))))
1267 (re1 "\\|[ \t]*/\\*[ \t]*$\\|[ \t]*\\*/[ \t]*$\\|[ \t/*]*$"))
1270 (looking-at ".*//"))
1271 (let ((fill-prefix fill-prefix)
1272 ;; Lines containing just a comment start or just an end
1273 ;; should not be filled into paragraphs they are next
1275 (paragraph-start (concat paragraph-start re1))
1276 (paragraph-separate (concat paragraph-separate re1)))
1279 ;; Move up to first line of this comment.
1280 (while (and (not (bobp))
1281 (looking-at "[ \t]*//[ \t]*[^ \t\n]"))
1283 (if (not (looking-at ".*//[ \t]*[^ \t\n]"))
1285 ;; Find the comment start in this line.
1286 (re-search-forward "[ \t]*//[ \t]*")
1287 ;; Set the fill-prefix to be what all lines except the first
1288 ;; should start with. But do not alter a user set fill-prefix.
1289 (if (null fill-prefix)
1290 (setq fill-prefix (buffer-substring (match-beginning 0)
1293 ;; Narrow down to just the lines of this comment.
1294 (narrow-to-region (c-point 'bol)
1297 (while (looking-at fill-prefix)
1300 (fill-paragraph arg)
1302 ;; else C style comments
1304 ;; t if we enter a comment between start of function and
1306 (eq (c-in-literal) 'c)
1307 ;; t if this line contains a comment starter.
1312 (re-search-forward comment-start-skip
1313 (save-excursion (end-of-line)
1316 (setq comment-start-place (point))))))
1317 ;; Inside a comment: fill one comment paragraph.
1319 ;; The prefix for each line of this paragraph
1320 ;; is the appropriate part of the start of this line,
1321 ;; up to the column at which text should be indented.
1324 (if (looking-at "[ \t]*/\\*.*\\*/")
1325 (progn (re-search-forward comment-start-skip)
1326 (make-string (current-column) ?\ ))
1327 (if first-line (forward-line 1))
1329 (let ((line-width (progn (end-of-line) (current-column))))
1335 ;; How shall we decide where the end of the
1339 (skip-chars-forward " \t*" (c-point 'eol))
1340 ;; kludge alert, watch out for */, in
1341 ;; which case fill-prefix should *not*
1343 (if (and (eq (char-after) ?/)
1344 (eq (char-before) ?*))
1348 ;; If the comment is only one line followed
1349 ;; by a blank line, calling move-to-column
1350 ;; above may have added some spaces and tabs
1351 ;; to the end of the line; the fill-paragraph
1352 ;; function will then delete it and the
1353 ;; newline following it, so we'll lose a
1354 ;; blank line when we shouldn't. So delete
1355 ;; anything move-to-column added to the end
1356 ;; of the line. We record the line width
1357 ;; instead of the position of the old line
1358 ;; end because move-to-column might break a
1359 ;; tab into spaces, and the new characters
1360 ;; introduced there shouldn't be deleted.
1362 ;; If you can see a better way to do this,
1363 ;; please make the change. This seems very
1365 (delete-region (progn (move-to-column line-width)
1367 (progn (end-of-line) (point))))))))
1369 ;; Lines containing just a comment start or just an end
1370 ;; should not be filled into paragraphs they are next
1372 (paragraph-start (concat paragraph-start re1))
1373 (paragraph-separate (concat paragraph-separate re1))
1377 ;; Don't fill the comment together with the code
1378 ;; following it. So temporarily exclude everything
1379 ;; before the comment start, and everything after the
1380 ;; line where the comment ends. If comment-start-place
1381 ;; is non-nil, the comment starter is there. Otherwise,
1382 ;; point is inside the comment.
1383 (narrow-to-region (save-excursion
1384 (if comment-start-place
1385 (goto-char comment-start-place)
1386 (search-backward "/*"))
1387 (if (and (not c-hanging-comment-starter-p)
1389 (concat c-comment-start-regexp
1392 ;; Protect text before the comment
1393 ;; start by excluding it. Add
1394 ;; spaces to bring back proper
1395 ;; indentation of that point.
1396 (let ((column (current-column)))
1398 (setq chars-to-delete column)
1399 (insert-char ?\ column))))
1401 (if comment-start-place
1402 (goto-char (+ comment-start-place 2)))
1403 (search-forward "*/" nil 'move)
1406 (fill-paragraph arg)
1408 ;; Delete the chars we inserted to avoid clobbering
1409 ;; the stuff before the comment start.
1410 (goto-char (point-min))
1411 (if (> chars-to-delete 0)
1412 (delete-region (point) (+ (point) chars-to-delete)))
1413 ;; Find the comment ender (should be on last line of
1414 ;; buffer, given the narrowing) and don't leave it on
1415 ;; its own line, unless that's the style that's desired.
1416 (goto-char (point-max))
1418 (search-forward "*/" nil 'move)
1420 (if (and c-hanging-comment-ender-p
1421 (looking-at "[ \t]*\\*/"))
1422 ;(delete-indentation)))))
1423 (let ((fill-column (+ fill-column 9999)))
1425 (fill-region-as-paragraph (point) (point-max))))))
1430 ;;; cc-cmds.el ends here