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