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