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