Update autoload checksums.
[bpt/emacs.git] / lisp / progmodes / cc-cmds.el
CommitLineData
0ec8351b 1;;; cc-cmds.el --- user level commands for CC Mode
785eecbb 2
92ab3834 3;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
ae940284 4;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
d7a0267c 5;; Free Software Foundation, Inc.
785eecbb 6
e309f66c
AM
7;; Authors: 2003- Alan Mackenzie
8;; 1998- Martin Stjernholm
d9e94c22 9;; 1992-1999 Barry A. Warsaw
785eecbb
RS
10;; 1987 Dave Detlefs and Stewart Clamen
11;; 1985 Richard M. Stallman
0ec8351b 12;; Maintainer: bug-cc-mode@gnu.org
785eecbb 13;; Created: 22-Apr-1997 (split from cc-mode.el)
a7c7b186 14;; Version: See cc-mode.el
785eecbb
RS
15;; Keywords: c languages oop
16
17;; This file is part of GNU Emacs.
18
b1fc2b50 19;; GNU Emacs is free software: you can redistribute it and/or modify
785eecbb 20;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
21;; the Free Software Foundation, either version 3 of the License, or
22;; (at your option) any later version.
785eecbb
RS
23
24;; GNU Emacs is distributed in the hope that it will be useful,
25;; but WITHOUT ANY WARRANTY; without even the implied warranty of
26;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27;; GNU General Public License for more details.
28
29;; You should have received a copy of the GNU General Public License
b1fc2b50 30;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
785eecbb 31
3afbc435
PJ
32;;; Commentary:
33
34;;; Code:
35
0ec8351b 36(eval-when-compile
51f606de 37 (let ((load-path
130c507e
GM
38 (if (and (boundp 'byte-compile-dest-file)
39 (stringp byte-compile-dest-file))
40 (cons (file-name-directory byte-compile-dest-file) load-path)
51f606de 41 load-path)))
d9e94c22 42 (load "cc-bytecomp" nil t)))
130c507e
GM
43
44(cc-require 'cc-defs)
45(cc-require 'cc-vars)
130c507e
GM
46(cc-require 'cc-engine)
47
48;; Silence the compiler.
0386b551 49(cc-bytecomp-defun delete-forward-p) ; XEmacs
130c507e
GM
50(cc-bytecomp-defvar filladapt-mode) ; c-fill-paragraph contains a kludge
51 ; which looks at this.
0386b551
AM
52(cc-bytecomp-defun c-forward-subword)
53(cc-bytecomp-defun c-backward-subword)
51f606de 54\f
51c9af45 55;; Indentation / Display syntax functions
a66cd3ee
MS
56(defvar c-fix-backslashes t)
57
a66cd3ee
MS
58(defun c-indent-line (&optional syntax quiet ignore-point-pos)
59 "Indent the current line according to the syntactic context,
60if `c-syntactic-indentation' is non-nil. Optional SYNTAX is the
61syntactic information for the current line. Be silent about syntactic
62errors if the optional argument QUIET is non-nil, even if
63`c-report-syntactic-errors' is non-nil. Normally the position of
64point is used to decide where the old indentation is on a lines that
65is otherwise empty \(ignoring any line continuation backslash), but
66that's not done if IGNORE-POINT-POS is non-nil. Returns the amount of
67indentation change \(in columns)."
d9e94c22 68
a66cd3ee
MS
69 (let ((line-cont-backslash (save-excursion
70 (end-of-line)
71 (eq (char-before) ?\\)))
72 (c-fix-backslashes c-fix-backslashes)
73 bs-col
74 shift-amt)
75 (when (and (not ignore-point-pos)
76 (save-excursion
77 (beginning-of-line)
78 (looking-at (if line-cont-backslash
647a3247
AM
79 ;; Don't use "\\s " - ^L doesn't count as WS
80 ;; here
81 "\\([ \t]*\\)\\\\$"
82 "\\([ \t]*\\)$")))
a66cd3ee
MS
83 (<= (point) (match-end 1)))
84 ;; Delete all whitespace after point if there's only whitespace
85 ;; on the line, so that any code that does back-to-indentation
86 ;; or similar gets the current column in this case. If this
87 ;; removes a line continuation backslash it'll be restored
88 ;; at the end.
89 (unless c-auto-align-backslashes
90 ;; Should try to keep the backslash alignment
91 ;; in this case.
92 (save-excursion
93 (goto-char (match-end 0))
94 (setq bs-col (1- (current-column)))))
95 (delete-region (point) (match-end 0))
96 (setq c-fix-backslashes t))
97 (if c-syntactic-indentation
98 (setq c-parsing-error
d9e94c22
MS
99 (or (let ((c-parsing-error nil)
100 (c-syntactic-context
101 (or syntax
102 (and (boundp 'c-syntactic-context)
103 c-syntactic-context))))
104 (c-save-buffer-state (indent)
105 (unless c-syntactic-context
106 (setq c-syntactic-context (c-guess-basic-syntax)))
107 (setq indent (c-get-syntactic-indentation
108 c-syntactic-context))
109 (and (not (c-echo-parsing-error quiet))
110 c-echo-syntactic-information-p
111 (message "syntax: %s, indent: %d"
112 c-syntactic-context indent))
113 (setq shift-amt (- indent (current-indentation))))
a66cd3ee
MS
114 (c-shift-line-indentation shift-amt)
115 (run-hooks 'c-special-indent-hook)
116 c-parsing-error)
117 c-parsing-error))
118 (let ((indent 0))
119 (save-excursion
120 (while (and (= (forward-line -1) 0)
121 (if (looking-at "\\s *\\\\?$")
122 t
123 (setq indent (current-indentation))
124 nil))))
125 (setq shift-amt (- indent (current-indentation)))
126 (c-shift-line-indentation shift-amt)))
127 (when (and c-fix-backslashes line-cont-backslash)
128 (if bs-col
129 (save-excursion
130 (indent-to bs-col)
131 (insert ?\\))
132 (when c-auto-align-backslashes
133 ;; Realign the line continuation backslash.
134 (c-backslash-region (point) (point) nil t))))
135 shift-amt))
136
137(defun c-newline-and-indent (&optional newline-arg)
0386b551 138 "Insert a newline and indent the new line.
a66cd3ee
MS
139This function fixes line continuation backslashes if inside a macro,
140and takes care to set the indentation before calling
141`indent-according-to-mode', so that lineup functions like
142`c-lineup-dont-change' works better."
d9e94c22
MS
143
144 ;; TODO: Backslashes before eol in comments and literals aren't
a66cd3ee
MS
145 ;; kept intact.
146 (let ((c-macro-start (c-query-macro-start))
147 ;; Avoid calling c-backslash-region from c-indent-line if it's
148 ;; called during the newline call, which can happen due to
149 ;; c-electric-continued-statement, for example. We also don't
150 ;; want any backslash alignment from indent-according-to-mode.
151 (c-fix-backslashes nil)
152 has-backslash insert-backslash
153 start col)
154 (save-excursion
155 (beginning-of-line)
156 (setq start (point))
157 (while (and (looking-at "[ \t]*\\\\?$")
158 (= (forward-line -1) 0)))
159 (setq col (current-indentation)))
160 (when c-macro-start
161 (if (and (eolp) (eq (char-before) ?\\))
162 (setq insert-backslash t
163 has-backslash t)
164 (setq has-backslash (eq (char-before (c-point 'eol)) ?\\))))
165 (newline newline-arg)
166 (indent-to col)
167 (when c-macro-start
168 (if insert-backslash
169 (progn
170 ;; The backslash stayed on the previous line. Insert one
171 ;; before calling c-backslash-region, so that
172 ;; bs-col-after-end in it works better. Fixup the
173 ;; backslashes on the newly inserted line.
174 (insert ?\\)
175 (backward-char)
176 (c-backslash-region (point) (point) nil t))
177 ;; The backslash moved to the new line, if there was any. Let
178 ;; c-backslash-region fix a backslash on the previous line,
179 ;; and the one that might be on the new line.
180 ;; c-auto-align-backslashes is intentionally ignored here;
181 ;; maybe the moved backslash should be left alone if it's set,
182 ;; but we fix both lines on the grounds that the old backslash
183 ;; has been moved anyway and is now in a different context.
184 (c-backslash-region start (if has-backslash (point) start) nil t)))
185 (when c-syntactic-indentation
186 ;; Reindent syntactically. The indentation done above is not
187 ;; wasted, since c-indent-line might look at the current
188 ;; indentation.
d9e94c22
MS
189 (let ((c-syntactic-context (c-save-buffer-state nil
190 (c-guess-basic-syntax))))
a66cd3ee
MS
191 ;; We temporarily insert another line break, so that the
192 ;; lineup functions will see the line as empty. That makes
193 ;; e.g. c-lineup-cpp-define more intuitive since it then
194 ;; proceeds to the preceding line in this case.
195 (insert ?\n)
196 (delete-horizontal-space)
197 (setq start (- (point-max) (point)))
198 (unwind-protect
199 (progn
200 (backward-char)
201 (indent-according-to-mode))
202 (goto-char (- (point-max) start))
203 (delete-char -1)))
204 (when has-backslash
205 ;; Must align the backslash again after reindentation. The
206 ;; c-backslash-region call above can't be optimized to ignore
207 ;; this line, since it then won't align correctly with the
208 ;; lines below if the first line in the macro is broken.
209 (c-backslash-region (point) (point) nil t)))))
210
211(defun c-show-syntactic-information (arg)
212 "Show syntactic information for current line.
213With universal argument, inserts the analysis as a comment on that line."
214 (interactive "P")
215 (let* ((c-parsing-error nil)
d9e94c22
MS
216 (syntax (if (boundp 'c-syntactic-context)
217 ;; Use `c-syntactic-context' in the same way as
218 ;; `c-indent-line', to be consistent.
219 c-syntactic-context
220 (c-save-buffer-state nil
221 (c-guess-basic-syntax)))))
a66cd3ee 222 (if (not (consp arg))
0386b551
AM
223 (let (elem pos ols)
224 (message "Syntactic analysis: %s" syntax)
225 (unwind-protect
226 (progn
227 (while syntax
228 (setq elem (pop syntax))
229 (when (setq pos (c-langelem-pos elem))
230 (push (c-put-overlay pos (1+ pos)
231 'face 'highlight)
232 ols))
233 (when (setq pos (c-langelem-2nd-pos elem))
234 (push (c-put-overlay pos (1+ pos)
235 'face 'secondary-selection)
236 ols)))
237 (sit-for 10))
238 (while ols
239 (c-delete-overlay (pop ols)))))
a66cd3ee
MS
240 (indent-for-comment)
241 (insert-and-inherit (format "%s" syntax))
242 ))
243 (c-keep-region-active))
244
245(defun c-syntactic-information-on-region (from to)
0386b551 246 "Insert a comment with the syntactic analysis on every line in the region."
a66cd3ee
MS
247 (interactive "*r")
248 (save-excursion
249 (save-restriction
250 (narrow-to-region from to)
251 (goto-char (point-min))
252 (while (not (eobp))
253 (c-show-syntactic-information '(0))
254 (forward-line)))))
255
256\f
51c9af45 257;; Minor mode functions.
0386b551
AM
258(defun c-update-modeline ()
259 (let ((fmt (format "/%s%s%s%s"
260 (if c-electric-flag "l" "")
261 (if (and c-electric-flag c-auto-newline)
262 "a" "")
263 (if c-hungry-delete-key "h" "")
264 (if (and
265 ;; cc-subword might not be loaded.
266 (boundp 'c-subword-mode)
267 (symbol-value 'c-subword-mode))
268 "w"
cb694ab7
AM
269 "")))
270 (bare-mode-name (if (string-match "\\(^[^/]*\\)/" mode-name)
271 (substring mode-name (match-beginning 1) (match-end 1))
272 mode-name)))
273;; (setq c-submode-indicators
274;; (if (> (length fmt) 1)
275;; fmt))
276 (setq mode-name
0386b551 277 (if (> (length fmt) 1)
17264191 278 (concat bare-mode-name fmt)
cb694ab7 279 bare-mode-name))
0386b551
AM
280 (force-mode-line-update)))
281
a66cd3ee
MS
282(defun c-toggle-syntactic-indentation (&optional arg)
283 "Toggle syntactic indentation.
284Optional numeric ARG, if supplied, turns on syntactic indentation when
285positive, turns it off when negative, and just toggles it when zero or
286left out.
287
288When syntactic indentation is turned on (the default), the indentation
289functions and the electric keys indent according to the syntactic
290context keys, when applicable.
291
0386b551
AM
292When it's turned off, the electric keys don't reindent, the indentation
293functions indents every new line to the same level as the previous
294nonempty line, and \\[c-indent-command] adjusts the indentation in steps
295specified by `c-basic-offset'. The indentation style has no effect in
296this mode, nor any of the indentation associated variables,
297e.g. `c-special-indent-hook'.
a66cd3ee
MS
298
299This command sets the variable `c-syntactic-indentation'."
300 (interactive "P")
301 (setq c-syntactic-indentation
302 (c-calculate-state arg c-syntactic-indentation))
303 (c-keep-region-active))
304
0386b551 305(defun c-toggle-auto-newline (&optional arg)
785eecbb 306 "Toggle auto-newline feature.
130c507e
GM
307Optional numeric ARG, if supplied, turns on auto-newline when
308positive, turns it off when negative, and just toggles it when zero or
309left out.
785eecbb 310
0386b551
AM
311Turning on auto-newline automatically enables electric indentation.
312
313When the auto-newline feature is enabled (indicated by \"/la\" on the
314modeline after the mode name) newlines are automatically inserted
315after special characters such as brace, comma, semi-colon, and colon."
785eecbb 316 (interactive "P")
0386b551
AM
317 (setq c-auto-newline
318 (c-calculate-state arg (and c-auto-newline c-electric-flag)))
319 (if c-auto-newline (setq c-electric-flag t))
785eecbb
RS
320 (c-update-modeline)
321 (c-keep-region-active))
322
0386b551
AM
323(defalias 'c-toggle-auto-state 'c-toggle-auto-newline)
324(make-obsolete 'c-toggle-auto-state 'c-toggle-auto-newline)
325
130c507e 326(defun c-toggle-hungry-state (&optional arg)
785eecbb 327 "Toggle hungry-delete-key feature.
130c507e
GM
328Optional numeric ARG, if supplied, turns on hungry-delete when
329positive, turns it off when negative, and just toggles it when zero or
330left out.
785eecbb 331
0386b551
AM
332When the hungry-delete-key feature is enabled (indicated by \"/h\" on
333the modeline after the mode name) the delete key gobbles all preceding
334whitespace in one fell swoop."
785eecbb
RS
335 (interactive "P")
336 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
337 (c-update-modeline)
338 (c-keep-region-active))
339
130c507e 340(defun c-toggle-auto-hungry-state (&optional arg)
785eecbb 341 "Toggle auto-newline and hungry-delete-key features.
130c507e 342Optional numeric ARG, if supplied, turns on auto-newline and
785eecbb 343hungry-delete when positive, turns them off when negative, and just
130c507e 344toggles them when zero or left out.
785eecbb 345
0386b551 346See `c-toggle-auto-newline' and `c-toggle-hungry-state' for details."
785eecbb
RS
347 (interactive "P")
348 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
349 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
350 (c-update-modeline)
351 (c-keep-region-active))
352
0386b551
AM
353(defun c-toggle-electric-state (&optional arg)
354 "Toggle the electric indentation feature.
355Optional numeric ARG, if supplied, turns on electric indentation when
356positive, turns it off when negative, and just toggles it when zero or
357left out."
358 (interactive "P")
359 (setq c-electric-flag (c-calculate-state arg c-electric-flag))
360 (c-update-modeline)
361 (c-keep-region-active))
362
785eecbb
RS
363\f
364;; Electric keys
365
785eecbb 366(defun c-electric-backspace (arg)
d9e94c22 367 "Delete the preceding character or whitespace.
0386b551
AM
368If `c-hungry-delete-key' is non-nil (indicated by \"/h\" on the mode
369line) then all preceding whitespace is consumed. If however a prefix
370argument is supplied, or `c-hungry-delete-key' is nil, or point is
371inside a literal then the function in the variable
372`c-backspace-function' is called."
28c236de 373 (interactive "*P")
0386b551
AM
374 (if (c-save-buffer-state ()
375 (or (not c-hungry-delete-key)
376 arg
377 (c-in-literal)))
785eecbb 378 (funcall c-backspace-function (prefix-numeric-value arg))
cb694ab7 379 (c-hungry-delete-backwards)))
d9e94c22 380
cb694ab7 381(defun c-hungry-delete-backwards ()
d9e94c22
MS
382 "Delete the preceding character or all preceding whitespace
383back to the previous non-whitespace character.
384See also \\[c-hungry-delete-forward]."
385 (interactive)
386 (let ((here (point)))
387 (c-skip-ws-backward)
388 (if (/= (point) here)
389 (delete-region (point) here)
390 (funcall c-backspace-function 1))))
785eecbb 391
cb694ab7
AM
392(defalias 'c-hungry-backspace 'c-hungry-delete-backwards)
393
fdea67e7 394(defun c-electric-delete-forward (arg)
d9e94c22 395 "Delete the following character or whitespace.
0386b551
AM
396If `c-hungry-delete-key' is non-nil (indicated by \"/h\" on the mode
397line) then all following whitespace is consumed. If however a prefix
398argument is supplied, or `c-hungry-delete-key' is nil, or point is
399inside a literal then the function in the variable `c-delete-function'
400is called."
fdea67e7 401 (interactive "*P")
0386b551
AM
402 (if (c-save-buffer-state ()
403 (or (not c-hungry-delete-key)
404 arg
405 (c-in-literal)))
fdea67e7 406 (funcall c-delete-function (prefix-numeric-value arg))
d9e94c22
MS
407 (c-hungry-delete-forward)))
408
409(defun c-hungry-delete-forward ()
410 "Delete the following character or all following whitespace
411up to the next non-whitespace character.
cb694ab7 412See also \\[c-hungry-delete-backwards]."
d9e94c22
MS
413 (interactive)
414 (let ((here (point)))
415 (c-skip-ws-forward)
416 (if (/= (point) here)
417 (delete-region (point) here)
418 (funcall c-delete-function 1))))
fdea67e7 419
d9e94c22 420;; This function is only used in XEmacs.
785eecbb
RS
421(defun c-electric-delete (arg)
422 "Deletes preceding or following character or whitespace.
fdea67e7 423This function either deletes forward as `c-electric-delete-forward' or
0386b551
AM
424backward as `c-electric-backspace', depending on the configuration: If
425the function `delete-forward-p' is defined and returns non-nil, it
426deletes forward. Otherwise it deletes backward.
427
428Note: This is the way in XEmacs to choose the correct action for the
429\[delete] key, whichever key that means. Other flavors don't use this
430function to control that."
28c236de 431 (interactive "*P")
0386b551
AM
432 (if (and (fboundp 'delete-forward-p)
433 (delete-forward-p))
fdea67e7 434 (c-electric-delete-forward arg)
785eecbb
RS
435 (c-electric-backspace arg)))
436
0386b551
AM
437;; This function is only used in XEmacs.
438(defun c-hungry-delete ()
439 "Delete a non-whitespace char, or all whitespace up to the next non-whitespace char.
440The direction of deletion depends on the configuration: If the
441function `delete-forward-p' is defined and returns non-nil, it deletes
442forward using `c-hungry-delete-forward'. Otherwise it deletes
443backward using `c-hungry-backspace'.
444
445Note: This is the way in XEmacs to choose the correct action for the
446\[delete] key, whichever key that means. Other flavors don't use this
447function to control that."
448 (interactive)
449 (if (and (fboundp 'delete-forward-p)
450 (delete-forward-p))
451 (c-hungry-delete-forward)
cb694ab7 452 (c-hungry-delete-backwards)))
0386b551 453
785eecbb 454(defun c-electric-pound (arg)
0386b551
AM
455 "Insert a \"#\".
456If `c-electric-flag' is set, handle it specially according to the variable
457`c-electric-pound-behavior'. If a numeric ARG is supplied, or if point is
458inside a literal or a macro, nothing special happens."
28c236de 459 (interactive "*P")
0386b551
AM
460 (if (c-save-buffer-state ()
461 (or arg
462 (not c-electric-flag)
463 (not (memq 'alignleft c-electric-pound-behavior))
464 (save-excursion
465 (skip-chars-backward " \t")
466 (not (bolp)))
467 (save-excursion
468 (and (= (forward-line -1) 0)
469 (progn (end-of-line)
470 (eq (char-before) ?\\))))
471 (c-in-literal)))
785eecbb
RS
472 ;; do nothing special
473 (self-insert-command (prefix-numeric-value arg))
474 ;; place the pound character at the left edge
475 (let ((pos (- (point-max) (point)))
476 (bolp (bolp)))
477 (beginning-of-line)
478 (delete-horizontal-space)
a66cd3ee 479 (insert last-command-char)
785eecbb
RS
480 (and (not bolp)
481 (goto-char (- (point-max) pos)))
482 )))
483
0386b551
AM
484(defun c-point-syntax ()
485 ;; Return the syntactic context of the construct at point. (This is NOT
486 ;; nec. the same as the s.c. of the line point is on). N.B. This won't work
487 ;; between the `#' of a cpp thing and what follows (see c-opt-cpp-prefix).
488 (c-save-buffer-state (;; shut this up too
489 (c-echo-syntactic-information-p nil)
490 syntax)
491 (c-tentative-buffer-changes
492 ;; insert a newline to isolate the construct at point for syntactic
493 ;; analysis.
494 (insert-char ?\n 1)
495 ;; In AWK (etc.) or in a macro, make sure this CR hasn't changed
496 ;; the syntax. (There might already be an escaped NL there.)
497 (when (or (c-at-vsemi-p (1- (point)))
498 (let ((pt (point)))
499 (save-excursion
500 (backward-char)
501 (and (c-beginning-of-macro)
502 (progn (c-end-of-macro)
503 (< (point) pt))))))
504 (backward-char)
505 (insert-char ?\\ 1)
506 (forward-char))
507 (let ((c-syntactic-indentation-in-macros t)
508 (c-auto-newline-analysis t))
509 ;; Turn on syntactic macro analysis to help with auto
510 ;; newlines only.
511 (setq syntax (c-guess-basic-syntax))
512 nil))
513 syntax))
514
515(defun c-brace-newlines (syntax)
516 ;; A brace stands at point. SYNTAX is the syntactic context of this brace
517 ;; (not necessarily the same as the S.C. of the line it is on). Return
518 ;; NEWLINES, the list containing some combination of the symbols `before'
519 ;; and `after' saying where newlines should be inserted.
520 (c-save-buffer-state
521 ((syms
522 ;; This is the list of brace syntactic symbols that can hang.
523 ;; If any new ones are added to c-offsets-alist, they should be
524 ;; added here as well.
3f71582d 525 ;;
4fae8922
AM
526 ;; The order of this list is important; if SYNTAX has several
527 ;; elements, the element that "wins" is the earliest in SYMS.
528 '(arglist-cont-nonempty ; e.g. an array literal.
529 class-open class-close defun-open defun-close
0386b551
AM
530 inline-open inline-close
531 brace-list-open brace-list-close
532 brace-list-intro brace-entry-open
533 block-open block-close
534 substatement-open statement-case-open
535 extern-lang-open extern-lang-close
536 namespace-open namespace-close
537 module-open module-close
538 composition-open composition-close
539 inexpr-class-open inexpr-class-close
540 ;; `statement-cont' is here for the case with a brace
541 ;; list opener inside a statement. C.f. CASE B.2 in
542 ;; `c-guess-continued-construct'.
543 statement-cont))
544 ;; shut this up too
545 (c-echo-syntactic-information-p nil)
546 symb-newlines) ; e.g. (substatement-open . (after))
17264191 547
0386b551
AM
548 (setq symb-newlines
549 ;; Do not try to insert newlines around a special
550 ;; (Pike-style) brace list.
551 (if (and c-special-brace-lists
552 (save-excursion
553 (c-safe (if (= (char-before) ?{)
554 (forward-char -1)
555 (c-forward-sexp -1))
556 (c-looking-at-special-brace-list))))
557 nil
558 ;; Seek the matching entry in c-hanging-braces-alist.
559 (or (c-lookup-lists
560 syms
561 ;; Substitute inexpr-class and class-open or
562 ;; class-close with inexpr-class-open or
563 ;; inexpr-class-close.
564 (if (assq 'inexpr-class syntax)
565 (cond ((assq 'class-open syntax)
566 '((inexpr-class-open)))
567 ((assq 'class-close syntax)
568 '((inexpr-class-close)))
569 (t syntax))
570 syntax)
571 c-hanging-braces-alist)
572 '(ignore before after)))) ; Default, when not in c-h-b-l.
573
574 ;; If syntax is a function symbol, then call it using the
575 ;; defined semantics.
576 (if (and (not (consp (cdr symb-newlines)))
577 (functionp (cdr symb-newlines)))
578 (let ((c-syntactic-context syntax))
579 (funcall (cdr symb-newlines)
580 (car symb-newlines)
581 (point)))
582 (cdr symb-newlines))))
583
584(defun c-try-one-liner ()
585 ;; Point is just after a newly inserted }. If the non-whitespace
586 ;; content of the braces is a single line of code, compact the whole
587 ;; construct to a single line, if this line isn't too long. The Right
588 ;; Thing is done with comments.
589 ;;
590 ;; Point will be left after the }, regardless of whether the clean-up is
591 ;; done. Return NON-NIL if the clean-up happened, NIL if it didn't.
592
593 (let ((here (point))
594 (pos (- (point-max) (point)))
595 mbeg1 mend1 mbeg4 mend4
596 eol-col cmnt-pos cmnt-col cmnt-gap)
597
598 (when
599 (save-excursion
600 (save-restriction
601 ;; Avoid backtracking over a very large block. The one we
602 ;; deal with here can never be more than three lines.
603 (narrow-to-region (save-excursion
604 (forward-line -2)
605 (point))
606 (point))
607 (and (c-safe (c-backward-sexp))
608 (progn
609 (forward-char)
610 (narrow-to-region (point) (1- here)) ; innards of {.}
611 (looking-at
612 (cc-eval-when-compile
613 (concat
614 "\\(" ; (match-beginning 1)
615 "[ \t]*\\([\r\n][ \t]*\\)?" ; WS with opt. NL
616 "\\)" ; (match-end 1)
617 "[^ \t\r\n]+\\([ \t]+[^ \t\r\n]+\\)*" ; non-WS
618 "\\(" ; (match-beginning 4)
619 "[ \t]*\\([\r\n][ \t]*\\)?" ; WS with opt. NL
620 "\\)\\'"))))))) ; (match-end 4) at EOB.
621
622 (if (c-tentative-buffer-changes
623 (setq mbeg1 (match-beginning 1) mend1 (match-end 1)
624 mbeg4 (match-beginning 4) mend4 (match-end 4))
625 (backward-char) ; back over the `}'
626 (save-excursion
627 (setq cmnt-pos (and (c-backward-single-comment)
628 (- (point) (- mend1 mbeg1)))))
629 (delete-region mbeg4 mend4)
630 (delete-region mbeg1 mend1)
631 (setq eol-col (save-excursion (end-of-line) (current-column)))
632
633 ;; Necessary to put the closing brace before any line
634 ;; oriented comment to keep it syntactically significant.
635 ;; This isn't necessary for block comments, but the result
636 ;; looks nicer anyway.
637 (when cmnt-pos
638 (delete-char 1) ; the `}' has blundered into a comment
639 (goto-char cmnt-pos)
640 (setq cmnt-col (1+ (current-column)))
641 (setq cmnt-pos (1+ cmnt-pos)) ; we're inserting a `}'
642 (c-skip-ws-backward)
643 (insert-char ?\} 1) ; reinsert the `}' before the comment.
644 (setq cmnt-gap (- cmnt-col (current-column)))
645 (when (zerop cmnt-gap)
646 (insert-char ?\ 1) ; Put a space before a bare comment.
647 (setq cmnt-gap 1)))
648
649 (or (null c-max-one-liner-length)
650 (zerop c-max-one-liner-length)
651 (<= eol-col c-max-one-liner-length)
652 ;; Can we trim space before comment to make the line fit?
653 (and cmnt-gap
654 (< (- eol-col cmnt-gap) c-max-one-liner-length)
655 (progn (goto-char cmnt-pos)
656 (backward-delete-char-untabify
657 (- eol-col c-max-one-liner-length))
658 t))))
659 (goto-char (- (point-max) pos))))))
660
785eecbb
RS
661(defun c-electric-brace (arg)
662 "Insert a brace.
663
0386b551
AM
664If `c-electric-flag' is non-nil, the brace is not inside a literal and a
665numeric ARG hasn't been supplied, the command performs several electric
666actions:
785eecbb 667
cb694ab7 668\(a) If the auto-newline feature is turned on (indicated by \"/la\" on
0386b551
AM
669the mode line) newlines are inserted before and after the brace as
670directed by the settings in `c-hanging-braces-alist'.
671
672\(b) Any auto-newlines are indented. The original line is also
673reindented unless `c-syntactic-indentation' is nil.
674
675\(c) If auto-newline is turned on, various newline cleanups based on the
676settings of `c-cleanup-list' are done."
0ec8351b 677
28c236de 678 (interactive "*P")
0386b551
AM
679 (let (safepos literal
680 ;; We want to inhibit blinking the paren since this would be
681 ;; most disruptive. We'll blink it ourselves later on.
682 (old-blink-paren blink-paren-function)
683 blink-paren-function)
684
685 (c-save-buffer-state ()
686 (setq safepos (c-safe-position (point) (c-parse-state))
687 literal (c-in-literal safepos)))
688
689 ;; Insert the brace. Note that expand-abbrev might reindent
690 ;; the line here if there's a preceding "else" or something.
691 (self-insert-command (prefix-numeric-value arg))
692
693 (when (and c-electric-flag (not literal) (not arg))
694 (if (not (looking-at "[ \t]*\\\\?$"))
695 (if c-syntactic-indentation
696 (indent-according-to-mode))
697
698 (let ( ;; shut this up too
699 (c-echo-syntactic-information-p nil)
700 newlines
701 ln-syntax br-syntax syntax) ; Syntactic context of the original line,
702 ; of the brace itself, of the line the brace ends up on.
703 (c-save-buffer-state ((c-syntactic-indentation-in-macros t)
704 (c-auto-newline-analysis t))
705 (setq ln-syntax (c-guess-basic-syntax)))
706 (if c-syntactic-indentation
707 (c-indent-line ln-syntax))
708
709 (when c-auto-newline
710 (backward-char)
711 (setq br-syntax (c-point-syntax)
712 newlines (c-brace-newlines br-syntax))
713
714 ;; Insert the BEFORE newline, if wanted, and reindent the newline.
715 (if (and (memq 'before newlines)
716 (> (current-column) (current-indentation)))
717 (if c-syntactic-indentation
718 ;; Only a plain newline for now - it's indented
719 ;; after the cleanups when the line has its final
720 ;; appearance.
721 (newline)
722 (c-newline-and-indent)))
723 (forward-char)
724
725 ;; `syntax' is the syntactic context of the line which ends up
726 ;; with the brace on it.
727 (setq syntax (if (memq 'before newlines) br-syntax ln-syntax))
728
729 ;; Do all appropriate clean ups
730 (let ((here (point))
731 (pos (- (point-max) (point)))
732 mbeg mend
733 )
734
735 ;; `}': clean up empty defun braces
736 (when (c-save-buffer-state ()
737 (and (memq 'empty-defun-braces c-cleanup-list)
738 (eq last-command-char ?\})
739 (c-intersect-lists '(defun-close class-close inline-close)
740 syntax)
741 (progn
742 (forward-char -1)
743 (c-skip-ws-backward)
744 (eq (char-before) ?\{))
745 ;; make sure matching open brace isn't in a comment
746 (not (c-in-literal))))
747 (delete-region (point) (1- here))
748 (setq here (- (point-max) pos)))
749 (goto-char here)
750
751 ;; `}': compact to a one-liner defun?
752 (save-match-data
753 (when
754 (and (eq last-command-char ?\})
755 (memq 'one-liner-defun c-cleanup-list)
756 (c-intersect-lists '(defun-close) syntax)
757 (c-try-one-liner))
758 (setq here (- (point-max) pos))))
759
760 ;; `{': clean up brace-else-brace and brace-elseif-brace
761 (when (eq last-command-char ?\{)
762 (cond
763 ((and (memq 'brace-else-brace c-cleanup-list)
764 (re-search-backward
765 (concat "}"
766 "\\([ \t\n]\\|\\\\\n\\)*"
767 "else"
768 "\\([ \t\n]\\|\\\\\n\\)*"
769 "{"
770 "\\=")
771 nil t))
cb694ab7 772 (delete-region (match-beginning 0) (match-end 0))
0386b551
AM
773 (insert-and-inherit "} else {"))
774 ((and (memq 'brace-elseif-brace c-cleanup-list)
775 (progn
776 (goto-char (1- here))
777 (setq mend (point))
778 (c-skip-ws-backward)
779 (setq mbeg (point))
780 (eq (char-before) ?\)))
781 (zerop (c-save-buffer-state nil (c-backward-token-2 1 t)))
782 (eq (char-after) ?\()
783 ; (progn
784 ; (setq tmp (point))
785 (re-search-backward
786 (concat "}"
787 "\\([ \t\n]\\|\\\\\n\\)*"
788 "else"
789 "\\([ \t\n]\\|\\\\\n\\)+"
790 "if"
791 "\\([ \t\n]\\|\\\\\n\\)*"
792 "\\=")
793 nil t);)
794 ;(eq (match-end 0) tmp);
795 )
796 (delete-region mbeg mend)
797 (goto-char mbeg)
798 (insert ?\ ))))
799
800 (goto-char (- (point-max) pos))
801
802 ;; Indent the line after the cleanups since it might
803 ;; very well indent differently due to them, e.g. if
804 ;; c-indent-one-line-block is used together with the
805 ;; one-liner-defun cleanup.
806 (when c-syntactic-indentation
807 (c-indent-line)))
808
809 ;; does a newline go after the brace?
810 (if (memq 'after newlines)
811 (c-newline-and-indent))
812 ))))
813
a66cd3ee
MS
814 ;; blink the paren
815 (and (eq last-command-char ?\})
816 (not executing-kbd-macro)
817 old-blink-paren
818 (save-excursion
d9e94c22
MS
819 (c-save-buffer-state nil
820 (c-backward-syntactic-ws safepos))
a66cd3ee 821 (funcall old-blink-paren)))))
0ec8351b 822
785eecbb
RS
823(defun c-electric-slash (arg)
824 "Insert a slash character.
0fc3821e 825
0386b551
AM
826If the slash is inserted immediately after the comment prefix in a c-style
827comment, the comment might get closed by removing whitespace and possibly
828inserting a \"*\". See the variable `c-cleanup-list'.
829
0fc3821e
RS
830Indent the line as a comment, if:
831
0386b551 832 1. The slash is second of a \"//\" line oriented comment introducing
0fc3821e
RS
833 token and we are on a comment-only-line, or
834
0386b551 835 2. The slash is part of a \"*/\" token that closes a block oriented
0fc3821e
RS
836 comment.
837
b8ded794 838If a numeric ARG is supplied, point is inside a literal, or
0386b551
AM
839`c-syntactic-indentation' is nil or `c-electric-flag' is nil, indentation
840is inhibited."
28c236de 841 (interactive "*P")
0386b551
AM
842 (let ((literal (c-save-buffer-state () (c-in-literal)))
843 indentp
844 ;; shut this up
845 (c-echo-syntactic-information-p nil))
846
847 ;; comment-close-slash cleanup? This DOESN'T need `c-electric-flag' or
848 ;; `c-syntactic-indentation' set.
849 (when (and (not arg)
850 (eq literal 'c)
851 (memq 'comment-close-slash c-cleanup-list)
852 (eq last-command-char ?/)
51c9af45
AM
853 (looking-at (concat "[ \t]*\\("
854 (regexp-quote comment-end) "\\)?$"))
0386b551
AM
855 ; (eq c-block-comment-ender "*/") ; C-style comments ALWAYS end in */
856 (save-excursion
51c9af45
AM
857 (save-restriction
858 (narrow-to-region (point-min) (point))
859 (back-to-indentation)
860 (looking-at (concat c-current-comment-prefix "[ \t]*$")))))
0abe900b 861 (delete-region (progn (forward-line 0) (point))
c05ddcf7 862 (progn (end-of-line) (point)))
51c9af45 863 (insert-char ?* 1)) ; the / comes later. ; Do I need a t (retain sticky properties) here?
0386b551
AM
864
865 (setq indentp (and (not arg)
866 c-syntactic-indentation
867 c-electric-flag
0fc3821e 868 (eq last-command-char ?/)
0386b551 869 (eq (char-before) (if literal ?* ?/))))
785eecbb
RS
870 (self-insert-command (prefix-numeric-value arg))
871 (if indentp
130c507e 872 (indent-according-to-mode))))
785eecbb
RS
873
874(defun c-electric-star (arg)
875 "Insert a star character.
0386b551
AM
876If `c-electric-flag' and `c-syntactic-indentation' are both non-nil, and
877the star is the second character of a C style comment starter on a
878comment-only-line, indent the line as a comment. If a numeric ARG is
879supplied, point is inside a literal, or `c-syntactic-indentation' is nil,
880this indentation is inhibited."
881
28c236de 882 (interactive "*P")
785eecbb 883 (self-insert-command (prefix-numeric-value arg))
0386b551 884 ;; if we are in a literal, or if arg is given do not reindent the
785eecbb 885 ;; current line, unless this star introduces a comment-only line.
0386b551
AM
886 (if (c-save-buffer-state ()
887 (and c-syntactic-indentation
888 c-electric-flag
889 (not arg)
890 (eq (c-in-literal) 'c)
891 (eq (char-before) ?*)
892 (save-excursion
893 (forward-char -1)
894 (skip-chars-backward "*")
895 (if (eq (char-before) ?/)
896 (forward-char -1))
897 (skip-chars-backward " \t")
898 (bolp))))
130c507e
GM
899 (let (c-echo-syntactic-information-p) ; shut this up
900 (indent-according-to-mode))
785eecbb
RS
901 ))
902
903(defun c-electric-semi&comma (arg)
904 "Insert a comma or semicolon.
785eecbb 905
0386b551
AM
906If `c-electric-flag' is non-nil, point isn't inside a literal and a
907numeric ARG hasn't been supplied, the command performs several electric
908actions:
909
cb694ab7 910\(a) When the auto-newline feature is turned on (indicated by \"/la\" on
0386b551
AM
911the mode line) a newline might be inserted. See the variable
912`c-hanging-semi&comma-criteria' for how newline insertion is determined.
0ec8351b 913
0386b551
AM
914\(b) Any auto-newlines are indented. The original line is also
915reindented unless `c-syntactic-indentation' is nil.
916
917\(c) If auto-newline is turned on, a comma following a brace list or a
918semicolon following a defun might be cleaned up, depending on the
919settings of `c-cleanup-list'."
28c236de 920 (interactive "*P")
0386b551 921 (let* (lim literal c-syntactic-context
785eecbb
RS
922 (here (point))
923 ;; shut this up
924 (c-echo-syntactic-information-p nil))
0386b551
AM
925
926 (c-save-buffer-state ()
927 (setq lim (c-most-enclosing-brace (c-parse-state))
928 literal (c-in-literal lim)))
929
930 (self-insert-command (prefix-numeric-value arg))
931
932 (if (and c-electric-flag (not literal) (not arg))
933 ;; do all cleanups and newline insertions if c-auto-newline is on.
934 (if (or (not c-auto-newline)
935 (not (looking-at "[ \t]*\\\\?$")))
936 (if c-syntactic-indentation
937 (c-indent-line))
938 ;; clean ups: list-close-comma or defun-close-semi
939 (let ((pos (- (point-max) (point))))
940 (if (c-save-buffer-state ()
941 (and (or (and
942 (eq last-command-char ?,)
943 (memq 'list-close-comma c-cleanup-list))
944 (and
945 (eq last-command-char ?\;)
946 (memq 'defun-close-semi c-cleanup-list)))
947 (progn
948 (forward-char -1)
949 (c-skip-ws-backward)
950 (eq (char-before) ?}))
951 ;; make sure matching open brace isn't in a comment
952 (not (c-in-literal lim))))
953 (delete-region (point) here))
954 (goto-char (- (point-max) pos)))
955 ;; reindent line
956 (when c-syntactic-indentation
957 (setq c-syntactic-context (c-guess-basic-syntax))
958 (c-indent-line c-syntactic-context))
959 ;; check to see if a newline should be added
960 (let ((criteria c-hanging-semi&comma-criteria)
961 answer add-newline-p)
962 (while criteria
963 (setq answer (funcall (car criteria)))
964 ;; only nil value means continue checking
965 (if (not answer)
966 (setq criteria (cdr criteria))
967 (setq criteria nil)
968 ;; only 'stop specifically says do not add a newline
969 (setq add-newline-p (not (eq answer 'stop)))
970 ))
971 (if add-newline-p
972 (c-newline-and-indent))
973 )))))
785eecbb
RS
974
975(defun c-electric-colon (arg)
976 "Insert a colon.
977
0386b551
AM
978If `c-electric-flag' is non-nil, the colon is not inside a literal and a
979numeric ARG hasn't been supplied, the command performs several electric
980actions:
981
cb694ab7 982\(a) If the auto-newline feature is turned on (indicated by \"/la\" on
0386b551
AM
983the mode line) newlines are inserted before and after the colon based on
984the settings in `c-hanging-colons-alist'.
785eecbb 985
0386b551
AM
986\(b) Any auto-newlines are indented. The original line is also
987reindented unless `c-syntactic-indentation' is nil.
988
989\(c) If auto-newline is turned on, whitespace between two colons will be
990\"cleaned up\" leaving a scope operator, if this action is set in
991`c-cleanup-list'."
785eecbb 992
28c236de 993 (interactive "*P")
785eecbb 994 (let* ((bod (c-point 'bod))
0386b551 995 (literal (c-save-buffer-state () (c-in-literal bod)))
a66cd3ee 996 newlines is-scope-op
785eecbb
RS
997 ;; shut this up
998 (c-echo-syntactic-information-p nil))
0386b551
AM
999 (self-insert-command (prefix-numeric-value arg))
1000 ;; Any electric action?
1001 (if (and c-electric-flag (not literal) (not arg))
1002 ;; Unless we're at EOL, only re-indentation happens.
1003 (if (not (looking-at "[ \t]*\\\\?$"))
1004 (if c-syntactic-indentation
1005 (indent-according-to-mode))
1006
1007 ;; scope-operator clean-up?
1008 (let ((pos (- (point-max) (point)))
1009 (here (point)))
1010 (if (c-save-buffer-state () ; Why do we need this? [ACM, 2003-03-12]
1011 (and c-auto-newline
1012 (memq 'scope-operator c-cleanup-list)
1013 (eq (char-before) ?:)
1014 (progn
1015 (forward-char -1)
1016 (c-skip-ws-backward)
1017 (eq (char-before) ?:))
1018 (not (c-in-literal))
1019 (not (eq (char-after (- (point) 2)) ?:))))
1020 (progn
1021 (delete-region (point) (1- here))
1022 (setq is-scope-op t)))
1023 (goto-char (- (point-max) pos)))
1024
1025 ;; indent the current line if it's done syntactically.
1026 (if c-syntactic-indentation
1027 ;; Cannot use the same syntax analysis as we find below,
1028 ;; since that's made with c-syntactic-indentation-in-macros
1029 ;; always set to t.
1030 (indent-according-to-mode))
1031
1032 ;; Calculate where, if anywhere, we want newlines.
1033 (c-save-buffer-state
1034 ((c-syntactic-indentation-in-macros t)
1035 (c-auto-newline-analysis t)
1036 ;; Turn on syntactic macro analysis to help with auto newlines
1037 ;; only.
1038 (syntax (c-guess-basic-syntax))
1039 (elem syntax))
1040 ;; Translate substatement-label to label for this operation.
1041 (while elem
1042 (if (eq (car (car elem)) 'substatement-label)
1043 (setcar (car elem) 'label))
1044 (setq elem (cdr elem)))
1045 ;; some language elements can only be determined by checking
1046 ;; the following line. Lets first look for ones that can be
1047 ;; found when looking on the line with the colon
1048 (setq newlines
1049 (and c-auto-newline
1050 (or (c-lookup-lists '(case-label label access-label)
1051 syntax c-hanging-colons-alist)
1052 (c-lookup-lists '(member-init-intro inher-intro)
1053 (progn
1054 (insert ?\n)
1055 (unwind-protect
1056 (c-guess-basic-syntax)
1057 (delete-char -1)))
1058 c-hanging-colons-alist)))))
1059 ;; does a newline go before the colon? Watch out for already
1060 ;; non-hung colons. However, we don't unhang them because that
1061 ;; would be a cleanup (and anti-social).
1062 (if (and (memq 'before newlines)
1063 (not is-scope-op)
1064 (save-excursion
1065 (skip-chars-backward ": \t")
1066 (not (bolp))))
1067 (let ((pos (- (point-max) (point))))
1068 (forward-char -1)
1069 (c-newline-and-indent)
1070 (goto-char (- (point-max) pos))))
1071 ;; does a newline go after the colon?
1072 (if (and (memq 'after (cdr-safe newlines))
1073 (not is-scope-op))
1074 (c-newline-and-indent))
1075 ))))
785eecbb
RS
1076
1077(defun c-electric-lt-gt (arg)
0386b551
AM
1078 "Insert a \"<\" or \">\" character.
1079If the current language uses angle bracket parens (e.g. template
1080arguments in C++), try to find out if the inserted character is a
1081paren and give it paren syntax if appropriate.
1082
1083If `c-electric-flag' and `c-syntactic-indentation' are both non-nil, the
1084line will be reindented if the inserted character is a paren or if it
1085finishes a C++ style stream operator in C++ mode. Exceptions are when a
1086numeric argument is supplied, or the point is inside a literal."
1087
28c236de 1088 (interactive "*P")
0386b551
AM
1089 (let ((c-echo-syntactic-information-p nil)
1090 final-pos close-paren-inserted)
1091
785eecbb 1092 (self-insert-command (prefix-numeric-value arg))
0386b551
AM
1093 (setq final-pos (point))
1094
1095 (c-save-buffer-state (c-parse-and-markup-<>-arglists
1096 c-restricted-<>-arglists
1097 <-pos)
1098
1099 (when c-recognize-<>-arglists
1100 (if (eq last-command-char ?<)
1101 (when (and (progn
1102 (backward-char)
1103 (= (point)
1104 (progn
1105 (c-beginning-of-current-token)
1106 (point))))
1107 (progn
1108 (c-backward-token-2)
1109 (looking-at c-opt-<>-sexp-key)))
1110 (c-mark-<-as-paren (1- final-pos)))
1111
1112 ;; It's a ">". Check if there's an earlier "<" which either has
1113 ;; open paren syntax already or that can be recognized as an arglist
1114 ;; together with this ">". Note that this won't work in cases like
1115 ;; "template <x, a < b, y>" but they ought to be rare.
1116
1117 (save-restriction
1118 ;; Narrow to avoid that `c-forward-<>-arglist' below searches past
1119 ;; our position.
1120 (narrow-to-region (point-min) final-pos)
1121
1122 (while (and
1123 (progn
1124 (goto-char final-pos)
1125 (c-syntactic-skip-backward "^<;}" nil t)
1126 (eq (char-before) ?<))
1127 (progn
1128 (backward-char)
1129 ;; If the "<" already got open paren syntax we know we
1130 ;; have the matching closer. Handle it and exit the
1131 ;; loop.
1132 (if (looking-at "\\s\(")
1133 (progn
1134 (c-mark->-as-paren (1- final-pos))
1135 (setq close-paren-inserted t)
1136 nil)
1137 t))
1138
1139 (progn
1140 (setq <-pos (point))
1141 (c-backward-syntactic-ws)
1142 (c-simple-skip-symbol-backward))
1143 (or (looking-at c-opt-<>-sexp-key)
1144 (not (looking-at c-keywords-regexp)))
1145
1146 (let ((c-parse-and-markup-<>-arglists t)
1147 c-restricted-<>-arglists
1148 (containing-sexp
1149 (c-most-enclosing-brace (c-parse-state))))
1150 (when (and containing-sexp
1151 (progn (goto-char containing-sexp)
1152 (eq (char-after) ?\())
1153 (not (eq (get-text-property (point) 'c-type)
1154 'c-decl-arg-start)))
1155 (setq c-restricted-<>-arglists t))
1156 (goto-char <-pos)
1157 (c-forward-<>-arglist nil))
1158
1159 ;; Loop here if the "<" we found above belongs to a nested
1160 ;; angle bracket sexp. When we start over we'll find the
1161 ;; previous or surrounding sexp.
1162 (if (< (point) final-pos)
1163 t
1164 (setq close-paren-inserted t)
1165 nil)))))))
1166 (goto-char final-pos)
1167
1168 ;; Indent the line if appropriate.
1169 (when (and c-electric-flag c-syntactic-indentation)
1170 (backward-char)
1171 (when (prog1 (or (looking-at "\\s\(\\|\\s\)")
1172 (and (c-major-mode-is 'c++-mode)
1173 (progn
1174 (c-beginning-of-current-token)
1175 (looking-at "<<\\|>>"))
1176 (= (match-end 0) final-pos)))
1177 (goto-char final-pos))
1178 (indent-according-to-mode)))
1179
1180 (when (and close-paren-inserted
1181 (not executing-kbd-macro)
1182 blink-paren-function)
1183 ;; Note: Most paren blink functions, such as the standard
1184 ;; `blink-matching-open', currently doesn't handle paren chars
1185 ;; marked with text properties very well. Maybe we should avoid
1186 ;; this call for the time being?
1187 (funcall blink-paren-function))))
785eecbb 1188
0ec8351b
BW
1189(defun c-electric-paren (arg)
1190 "Insert a parenthesis.
1191
0386b551
AM
1192If `c-syntactic-indentation' and `c-electric-flag' are both non-nil, the
1193line is reindented unless a numeric ARG is supplied, or the parenthesis
1194is inserted inside a literal.
0ec8351b 1195
0386b551
AM
1196Whitespace between a function name and the parenthesis may get added or
1197removed; see the variable `c-cleanup-list'.
1198
1199Also, if `c-electric-flag' and `c-auto-newline' are both non-nil, some
1200newline cleanups are done if appropriate; see the variable `c-cleanup-list'."
0ec8351b 1201 (interactive "*P")
0386b551 1202 (let ((literal (c-save-buffer-state () (c-in-literal)))
a66cd3ee 1203 ;; shut this up
0ec8351b 1204 (c-echo-syntactic-information-p nil))
0386b551
AM
1205 (self-insert-command (prefix-numeric-value arg))
1206
1207 (if (and (not arg) (not literal))
1208 (let* ( ;; We want to inhibit blinking the paren since this will
1209 ;; be most disruptive. We'll blink it ourselves
1210 ;; afterwards.
1211 (old-blink-paren blink-paren-function)
1212 blink-paren-function)
1213 (if (and c-syntactic-indentation c-electric-flag)
1214 (indent-according-to-mode))
1215
1216 ;; If we're at EOL, check for new-line clean-ups.
1217 (when (and c-electric-flag c-auto-newline
1218 (looking-at "[ \t]*\\\\?$"))
1219
1220 ;; clean up brace-elseif-brace
1221 (when
1222 (and (memq 'brace-elseif-brace c-cleanup-list)
1223 (eq last-command-char ?\()
1224 (re-search-backward
1225 (concat "}"
1226 "\\([ \t\n]\\|\\\\\n\\)*"
1227 "else"
1228 "\\([ \t\n]\\|\\\\\n\\)+"
1229 "if"
1230 "\\([ \t\n]\\|\\\\\n\\)*"
1231 "("
1232 "\\=")
1233 nil t)
1234 (not (c-save-buffer-state () (c-in-literal))))
1235 (delete-region (match-beginning 0) (match-end 0))
1236 (insert-and-inherit "} else if ("))
1237
1238 ;; clean up brace-catch-brace
1239 (when
1240 (and (memq 'brace-catch-brace c-cleanup-list)
1241 (eq last-command-char ?\()
1242 (re-search-backward
1243 (concat "}"
1244 "\\([ \t\n]\\|\\\\\n\\)*"
1245 "catch"
1246 "\\([ \t\n]\\|\\\\\n\\)*"
1247 "("
1248 "\\=")
1249 nil t)
1250 (not (c-save-buffer-state () (c-in-literal))))
1251 (delete-region (match-beginning 0) (match-end 0))
1252 (insert-and-inherit "} catch (")))
1253
1254 ;; Check for clean-ups at function calls. These two DON'T need
1255 ;; `c-electric-flag' or `c-syntactic-indentation' set.
1256 ;; Point is currently just after the inserted paren.
1257 (let (beg (end (1- (point))))
1258 (cond
1259
1260 ;; space-before-funcall clean-up?
1261 ((and (memq 'space-before-funcall c-cleanup-list)
1262 (eq last-command-char ?\()
1263 (save-excursion
1264 (backward-char)
1265 (skip-chars-backward " \t")
1266 (setq beg (point))
8ccf9f7a
AM
1267 (and (c-save-buffer-state () (c-on-identifier))
1268 ;; Don't add a space into #define FOO()....
1269 (not (and (c-beginning-of-macro)
1270 (c-forward-over-cpp-define-id)
1271 (eq (point) beg))))))
0386b551
AM
1272 (save-excursion
1273 (delete-region beg end)
1274 (goto-char beg)
1275 (insert ?\ )))
1276
1277 ;; compact-empty-funcall clean-up?
1278 ((c-save-buffer-state ()
1279 (and (memq 'compact-empty-funcall c-cleanup-list)
1280 (eq last-command-char ?\))
1281 (save-excursion
1282 (c-safe (backward-char 2))
1283 (when (looking-at "()")
1284 (setq end (point))
1285 (skip-chars-backward " \t")
1286 (setq beg (point))
1287 (c-on-identifier)))))
1288 (delete-region beg end))))
1289 (and (eq last-input-event ?\))
1290 (not executing-kbd-macro)
1291 old-blink-paren
1292 (funcall old-blink-paren))))))
0ec8351b 1293
130c507e
GM
1294(defun c-electric-continued-statement ()
1295 "Reindent the current line if appropriate.
1296
1297This function is used to reindent the line after a keyword which
1298continues an earlier statement is typed, e.g. an \"else\" or the
1299\"while\" in a do-while block.
1300
1301The line is reindented if there is nothing but whitespace before the
1302keyword on the line, the keyword is not inserted inside a literal, and
0386b551 1303`c-electric-flag' and `c-syntactic-indentation' are both non-nil."
130c507e
GM
1304 (let (;; shut this up
1305 (c-echo-syntactic-information-p nil))
0386b551
AM
1306 (when (c-save-buffer-state ()
1307 (and c-electric-flag
1308 c-syntactic-indentation
1309 (not (eq last-command-char ?_))
1310 (= (save-excursion
1311 (skip-syntax-backward "w")
1312 (point))
1313 (c-point 'boi))
1314 (not (c-in-literal (c-point 'bod)))))
a66cd3ee
MS
1315 ;; Have to temporarily insert a space so that
1316 ;; c-guess-basic-syntax recognizes the keyword. Follow the
1317 ;; space with a nonspace to avoid messing up any whitespace
1318 ;; sensitive meddling that might be done, e.g. by
1319 ;; `c-backslash-region'.
1320 (insert-and-inherit " x")
1321 (unwind-protect
1322 (indent-according-to-mode)
1323 (delete-char -2)))))
785eecbb
RS
1324
1325\f
51c9af45 1326;; "nomenclature" functions + c-scope-operator.
785eecbb 1327(defun c-forward-into-nomenclature (&optional arg)
0386b551 1328 "Compatibility alias for `c-forward-subword'."
785eecbb 1329 (interactive "p")
0386b551
AM
1330 (require 'cc-subword)
1331 (c-forward-subword arg))
1332(make-obsolete 'c-forward-into-nomenclature 'c-forward-subword)
785eecbb
RS
1333
1334(defun c-backward-into-nomenclature (&optional arg)
0386b551 1335 "Compatibility alias for `c-backward-subword'."
785eecbb 1336 (interactive "p")
0386b551
AM
1337 (require 'cc-subword)
1338 (c-backward-subword arg))
1339(make-obsolete 'c-backward-into-nomenclature 'c-backward-subword)
785eecbb
RS
1340
1341(defun c-scope-operator ()
1342 "Insert a double colon scope operator at point.
1343No indentation or other \"electric\" behavior is performed."
28c236de 1344 (interactive "*")
a66cd3ee 1345 (insert-and-inherit "::"))
785eecbb 1346
51c9af45
AM
1347\f
1348;; Movement (etc.) by defuns.
1349(defun c-in-function-trailer-p (&optional lim)
1350 ;; Return non-nil if point is between the closing brace and the semicolon of
1351 ;; a brace construct which needs a semicolon, e.g. within the "variables"
1352 ;; portion of a declaration like "struct foo {...} bar ;".
1353 ;;
1354 ;; Return the position of the main declaration. Otherwise, return nil.
1355 ;; Point is assumed to be at the top level and outside of any macro or
1356 ;; literal.
1357 ;;
1358 ;; If LIM is non-nil, it is the bound on a the backward search for the
1359 ;; beginning of the declaration.
1360 ;;
1361 ;; This function might do hidden buffer changes.
1362 (and c-opt-block-decls-with-vars-key
1363 (save-excursion
1364 (c-syntactic-skip-backward "^;}" lim)
8007b73c
AM
1365 (let ((eo-block (point))
1366 bod)
1367 (and (eq (char-before) ?\})
1368 (eq (car (c-beginning-of-decl-1 lim)) 'previous)
1369 (setq bod (point))
1370 ;; Look for struct or union or ... If we find one, it might
1371 ;; be the return type of a function, or the like. Exclude
1372 ;; this case.
1373 (c-syntactic-re-search-forward
1374 (concat "[;=\(\[{]\\|\\("
1375 c-opt-block-decls-with-vars-key
1376 "\\)")
1377 eo-block t t t)
1378 (match-beginning 1) ; Is there a "struct" etc., somewhere?
1379 (not (eq (char-before) ?_))
1380 (c-syntactic-re-search-forward "[;=\(\[{]" eo-block t t t)
1381 (eq (char-before) ?\{)
1382 bod)))))
51c9af45
AM
1383
1384(defun c-where-wrt-brace-construct ()
1385 ;; Determine where we are with respect to functions (or other brace
1386 ;; constructs, included in the term "function" in the rest of this comment).
1387 ;; Point is assumed to be outside any macro or literal.
1388 ;; This is used by c-\(begining\|end\)-of-defun.
1389 ;;
1390 ;; Return one of these symbols:
1391 ;; at-header : we're at the start of a function's header.
1392 ;; in-header : we're inside a function's header, this extending right
1393 ;; up to the brace. This bit includes any k&r declarations.
1394 ;; in-block : we're inside a function's brace block.
1395 ;; in-trailer : we're in the area between the "}" and ";" of something
1396 ;; like "struct foo {...} bar, baz;".
1397 ;; at-function-end : we're just after the closing brace (or semicolon) that
1398 ;; terminates the function.
1399 ;; outwith-function: we're not at or in any function. Being inside a
1400 ;; non-brace construct also counts as 'outwith-function'.
1401 ;;
1402 ;; This function might do hidden buffer changes.
1403 (save-excursion
f325b570 1404 (let* (kluge-start
51c9af45
AM
1405 decl-result brace-decl-p
1406 (start (point))
1407 (paren-state (c-parse-state))
1408 (least-enclosing (c-least-enclosing-brace paren-state)))
1409
1410 (cond
1411 ((and least-enclosing
1412 (eq (char-after least-enclosing) ?\{))
1413 'in-block)
1414 ((c-in-function-trailer-p)
1415 'in-trailer)
1416 ((and (not least-enclosing)
1417 (consp paren-state)
1418 (consp (car paren-state))
1419 (eq start (cdar paren-state)))
1420 'at-function-end)
1421 (t
1422 ;; Find the start of the current declaration. NOTE: If we're in the
1423 ;; variables after a "struct/eval" type block, we don't get to the
1424 ;; real declaration here - we detect and correct for this later.
1425
1426 ;;If we're in the parameters' parens, move back out of them.
1427 (if least-enclosing (goto-char least-enclosing))
1428 ;; Kluge so that c-beginning-of-decl-1 won't go back if we're already
1429 ;; at a declaration.
1430 (if (or (and (eolp) (not (eobp))) ; EOL is matched by "\\s>"
1431 (not (looking-at
1432"\\([;#]\\|\\'\\|\\s(\\|\\s)\\|\\s\"\\|\\s\\\\|\\s$\\|\\s<\\|\\s>\\|\\s!\\)")))
1433 (forward-char))
1434 (setq kluge-start (point))
1435 (setq decl-result
1436 (car (c-beginning-of-decl-1
f325b570
AM
1437 ;; NOTE: If we're in a K&R region, this might be the start
1438 ;; of a parameter declaration, not the actual function.
51c9af45
AM
1439 (and least-enclosing ; LIMIT for c-b-of-decl-1
1440 (c-safe-position least-enclosing paren-state)))))
1441
1442 ;; Has the declaration we've gone back to got braces?
51c9af45
AM
1443 (setq brace-decl-p
1444 (save-excursion
1445 (and (c-syntactic-re-search-forward "[;{]" nil t t)
1446 (or (eq (char-before) ?\{)
1447 (and c-recognize-knr-p
1448 ;; Might have stopped on the
1449 ;; ';' in a K&R argdecl. In
1450 ;; that case the declaration
1451 ;; should contain a block.
f325b570 1452 (c-in-knr-argdecl))))))
51c9af45
AM
1453
1454 (cond
1455 ((= (point) kluge-start) ; might be BOB or unbalanced parens.
1456 'outwith-function)
1457 ((eq decl-result 'same)
1458 (if brace-decl-p
1459 (if (eq (point) start)
1460 'at-header
1461 'in-header)
1462 'outwith-function))
1463 ((eq decl-result 'previous)
1464 (if (and (not brace-decl-p)
1465 (c-in-function-trailer-p))
1466 'at-function-end
1467 'outwith-function))
1468 (t (error
1469 "c-where-wrt-brace-construct: c-beginning-of-decl-1 returned %s"
1470 decl-result))))))))
1471
1472(defun c-backward-to-nth-BOF-{ (n where)
1473 ;; Skip to the opening brace of the Nth function before point. If
1474 ;; point is inside a function, this counts as the first. Point must be
1475 ;; outside any comment/string or macro.
1476 ;;
1477 ;; N must be strictly positive.
1478 ;; WHERE describes the position of point, one of the symbols `at-header',
1479 ;; `in-header', `in-block', `in-trailer', `at-function-end',
1480 ;; `outwith-function' as returned by c-where-wrt-brace-construct.
1481 ;;
1482 ;; If we run out of functions, leave point at BOB. Return zero on success,
1483 ;; otherwise the number of {s still to go.
1484 ;;
1485 ;; This function may do hidden buffer changes
1486 (cond
1487 ;; What we do to go back the first defun depends on where we start.
1488 ((bobp))
1489 ((eq where 'in-block)
1490 (goto-char (c-least-enclosing-brace (c-parse-state)))
1491 (setq n (1- n)))
1492 ((eq where 'in-header)
1493 (c-syntactic-re-search-forward "{")
1494 (backward-char)
1495 (setq n (1- n)))
15279e74 1496 ((memq where '(at-header outwith-function at-function-end in-trailer))
51c9af45
AM
1497 (c-syntactic-skip-backward "^}")
1498 (when (eq (char-before) ?\})
1499 (backward-sexp)
1500 (setq n (1- n))))
1501 (t (error "Unknown `where' %s in c-backward-to-nth-EOF-{" where)))
1502
1503 ;; Each time round the loop, go back to a "{" at the outermost level.
1504 (while (and (> n 0) (not (bobp)))
1505 (c-parse-state) ; This call speeds up the following one
1506 ; by a factor of ~6. Hmmm. 2006/4/5.
1507 (c-syntactic-skip-backward "^}")
1508 (when (eq (char-before) ?\})
1509 (backward-sexp)
1510 (setq n (1- n))))
1511 n)
1512
28c236de
RS
1513(defun c-beginning-of-defun (&optional arg)
1514 "Move backward to the beginning of a defun.
a66cd3ee
MS
1515Every top level declaration that contains a brace paren block is
1516considered to be a defun.
1517
1518With a positive argument, move backward that many defuns. A negative
1519argument -N means move forward to the Nth following beginning. Return
1520t unless search stops due to beginning or end of buffer.
28c236de
RS
1521
1522Unlike the built-in `beginning-of-defun' this tries to be smarter
1523about finding the char with open-parenthesis syntax that starts the
1524defun."
a66cd3ee 1525
28c236de 1526 (interactive "p")
a66cd3ee
MS
1527 (or arg (setq arg 1))
1528
51c9af45 1529 (c-save-buffer-state
28abe5e2
AM
1530 (beginning-of-defun-function end-of-defun-function
1531 (start (point))
51c9af45 1532 where paren-state pos)
a66cd3ee 1533
51c9af45
AM
1534 ;; Move back out of any macro/comment/string we happen to be in.
1535 (c-beginning-of-macro)
1536 (setq pos (c-literal-limits))
1537 (if pos (goto-char (car pos)))
1538
1539 (setq where (c-where-wrt-brace-construct))
1540
1541 (if (< arg 0)
1542 ;; Move forward to the closing brace of a function.
1543 (progn
15279e74 1544 (if (memq where '(at-function-end outwith-function))
51c9af45
AM
1545 (setq arg (1+ arg)))
1546 (if (< arg 0)
1547 (setq arg (c-forward-to-nth-EOF-} (- arg) where)))
1548 ;; Move forward to the next opening brace....
1549 (when (and (= arg 0)
f7510c40 1550 (c-syntactic-re-search-forward "{" nil 'eob))
51c9af45
AM
1551 (backward-char)
1552 ;; ... and backward to the function header.
1553 (c-beginning-of-decl-1)
1554 t))
1555
1556 ;; Move backward to the opening brace of a function.
1557 (when (and (> arg 0)
1558 (eq (setq arg (c-backward-to-nth-BOF-{ arg where)) 0))
1559
1560 ;; Go backward to this function's header.
1561 (c-beginning-of-decl-1)
1562
1563 (setq pos (point))
1564 ;; We're now there, modulo comments and whitespace.
1565 ;; Try to be line oriented; position point at the closest
1566 ;; preceding boi that isn't inside a comment, but if we hit
1567 ;; the previous declaration then we use the current point
1568 ;; instead.
1569 (while (and (/= (point) (c-point 'boi))
1570 (c-backward-single-comment)))
1571 (if (/= (point) (c-point 'boi))
1572 (goto-char pos)))
1573
1574 (c-keep-region-active)
1575 (= arg 0))))
1576
1577(defun c-forward-to-nth-EOF-} (n where)
1578 ;; Skip to the closing brace of the Nth function after point. If
1579 ;; point is inside a function, this counts as the first. Point must be
1580 ;; outside any comment/string or macro.
1581 ;;
1582 ;; N must be strictly positive.
1583 ;; WHERE describes the position of point, one of the symbols `at-header',
1584 ;; `in-header', `in-block', `in-trailer', `at-function-end',
1585 ;; `outwith-function' as returned by c-where-wrt-brace-construct.
1586 ;;
1587 ;; If we run out of functions, leave point at EOB. Return zero on success,
1588 ;; otherwise the number of }s still to go.
1589 ;;
1590 ;; This function may do hidden buffer changes.
1591
1592 (cond
1593 ;; What we do to go forward over the first defun depends on where we
1594 ;; start. We go to the closing brace of that defun, even when we go
1595 ;; backwards to it (in a "struct foo {...} bar ;").
1596 ((eobp))
1597 ((eq where 'in-block)
1598 (goto-char (c-least-enclosing-brace (c-parse-state)))
1599 (forward-sexp)
1600 (setq n (1- n)))
1601 ((eq where 'in-trailer)
1602 (c-syntactic-skip-backward "^}")
1603 (setq n (1- n)))
15279e74
AM
1604 ((memq where '(at-function-end outwith-function at-header in-header))
1605 (when (c-syntactic-re-search-forward "{" nil 'eob)
1606 (backward-char)
1607 (forward-sexp)
1608 (setq n (1- n))))
51c9af45
AM
1609 (t (error "c-forward-to-nth-EOF-}: `where' is %s" where)))
1610
1611 ;; Each time round the loop, go forward to a "}" at the outermost level.
1612 (while (and (> n 0) (not (eobp)))
1613 ;(c-parse-state) ; This call speeds up the following one by a factor
1614 ; of ~6. Hmmm. 2006/4/5.
1615 (when (c-syntactic-re-search-forward "{" nil 'eob)
1616 (backward-char)
1617 (forward-sexp))
1618 (setq n (1- n)))
1619 n)
28c236de
RS
1620
1621(defun c-end-of-defun (&optional arg)
a66cd3ee
MS
1622 "Move forward to the end of a top level declaration.
1623With argument, do it that many times. Negative argument -N means move
1624back to Nth preceding end. Returns t unless search stops due to
1625beginning or end of buffer.
28c236de
RS
1626
1627An end of a defun occurs right after the close-parenthesis that matches
1628the open-parenthesis that starts a defun; see `beginning-of-defun'."
1629 (interactive "p")
a66cd3ee
MS
1630 (or arg (setq arg 1))
1631
51c9af45 1632 (c-save-buffer-state
28abe5e2
AM
1633 (beginning-of-defun-function end-of-defun-function
1634 (start (point))
51c9af45
AM
1635 where paren-state pos)
1636
1637 ;; Move back out of any macro/comment/string we happen to be in.
1638 (c-beginning-of-macro)
1639 (setq pos (c-literal-limits))
1640 (if pos (goto-char (car pos)))
1641
1642 (setq where (c-where-wrt-brace-construct))
1643
1644 (if (< arg 0)
1645 ;; Move backwards to the } of a function
1646 (progn
15279e74 1647 (if (memq where '(at-header outwith-function))
51c9af45
AM
1648 (setq arg (1+ arg)))
1649 (if (< arg 0)
1650 (setq arg (c-backward-to-nth-BOF-{ (- arg) where)))
de5c0bc1
AM
1651 (if (= arg 0)
1652 (c-syntactic-skip-backward "^}")))
51c9af45
AM
1653
1654 ;; Move forward to the } of a function
1655 (if (> arg 0)
1656 (setq arg (c-forward-to-nth-EOF-} arg where))))
1657
1658 ;; Do we need to move forward from the brace to the semicolon?
1659 (when (eq arg 0)
1660 (if (c-in-function-trailer-p) ; after "}" of struct/enum, etc.
1661 (c-syntactic-re-search-forward ";"))
1662
1663 (setq pos (point))
1664 ;; We're there now, modulo comments and whitespace.
1665 ;; Try to be line oriented; position point after the next
1666 ;; newline that isn't inside a comment, but if we hit the
1667 ;; next declaration then we use the current point instead.
1668 (while (and (not (bolp))
1669 (not (looking-at "\\s *$"))
1670 (c-forward-single-comment)))
1671 (cond ((bolp))
1672 ((looking-at "\\s *$")
1673 (forward-line 1))
1674 (t
1675 (goto-char pos))))
a66cd3ee 1676
51f606de
GM
1677 (c-keep-region-active)
1678 (= arg 0)))
28c236de 1679
fa7056bc
AM
1680(defun c-defun-name ()
1681 "Return the name of the current defun, or NIL if there isn't one.
1682\"Defun\" here means a function, or other top level construct
1683with a brace block."
1684 (interactive)
1685 (c-save-buffer-state
1686 (beginning-of-defun-function end-of-defun-function
1687 where pos name-end)
3f71582d 1688
fa7056bc
AM
1689 (save-excursion
1690 ;; Move back out of any macro/comment/string we happen to be in.
1691 (c-beginning-of-macro)
1692 (setq pos (c-literal-limits))
1693 (if pos (goto-char (car pos)))
1694
1695 (setq where (c-where-wrt-brace-construct))
1696
1697 ;; Move to the beginning of the current defun, if any, if we're not
1698 ;; already there.
1699 (if (eq where 'outwith-function)
1700 nil
1701 (unless (eq where 'at-header)
1702 (c-backward-to-nth-BOF-{ 1 where)
1703 (c-beginning-of-decl-1))
1704
1705 ;; Pick out the defun name, according to the type of defun.
1706 (cond
4588b317 1707 ;; struct, union, enum, or similar:
fa7056bc
AM
1708 ((and (looking-at c-type-prefix-key)
1709 (progn (c-forward-token-2 2) ; over "struct foo "
4588b317
AM
1710 (or (eq (char-after) ?\{)
1711 (looking-at c-symbol-key)))) ; "struct foo bar ..."
1712 (save-match-data (c-forward-token-2))
1713 (when (eq (char-after) ?\{)
1714 (c-backward-token-2)
1715 (looking-at c-symbol-key))
1716 (match-string-no-properties 0))
fa7056bc
AM
1717
1718 ((looking-at "DEFUN\\_>")
1719 ;; DEFUN ("file-name-directory", Ffile_name_directory, Sfile_name_directory, ...) ==> Ffile_name_directory
3f71582d 1720 ;; DEFUN(POSIX::STREAM-LOCK, stream lockp &key BLOCK SHARED START LENGTH) ==> POSIX::STREAM-LOCK
fa7056bc
AM
1721 (down-list 1)
1722 (c-forward-syntactic-ws)
1723 (when (eq (char-after) ?\")
1724 (forward-sexp 1)
1725 (c-forward-token-2)) ; over the comma and following WS.
1726 (buffer-substring-no-properties
1727 (point)
1728 (progn
1729 (c-forward-token-2)
3f71582d
SS
1730 (when (looking-at ":") ; CLISP: DEFUN(PACKAGE:LISP-SYMBOL,...)
1731 (skip-chars-forward "^,"))
fa7056bc
AM
1732 (c-backward-syntactic-ws)
1733 (point))))
3f71582d 1734
55d150f3
SS
1735 ((looking-at "DEF[a-zA-Z0-9_]* *( *\\([^, ]*\\) *,")
1736 ;; DEFCHECKER(sysconf_arg,prefix=_SC,default=, ...) ==> sysconf_arg
1737 ;; DEFFLAGSET(syslog_opt_flags,LOG_PID ...) ==> syslog_opt_flags
1738 (match-string-no-properties 1))
1739
fa7056bc
AM
1740 (t
1741 ;; Normal function or initializer.
1742 (when (c-syntactic-re-search-forward "[{(]" nil t)
1743 (backward-char)
1744 (c-backward-syntactic-ws)
1745 (when (eq (char-before) ?\=) ; struct foo bar = {0, 0} ;
1746 (c-backward-token-2)
1747 (c-backward-syntactic-ws))
1748 (setq name-end (point))
1749 (c-backward-token-2)
1750 (buffer-substring-no-properties (point) name-end))))))))
1751
a66cd3ee
MS
1752(defun c-declaration-limits (near)
1753 ;; Return a cons of the beginning and end positions of the current
1754 ;; top level declaration or macro. If point is not inside any then
1755 ;; nil is returned, unless NEAR is non-nil in which case the closest
1756 ;; following one is chosen instead (if there is any). The end
1757 ;; position is at the next line, providing there is one before the
1758 ;; declaration.
0386b551
AM
1759 ;;
1760 ;; This function might do hidden buffer changes.
a66cd3ee
MS
1761 (save-excursion
1762
1763 ;; Note: Some code duplication in `c-beginning-of-defun' and
1764 ;; `c-end-of-defun'.
1765 (catch 'exit
1766 (let ((start (point))
1767 (paren-state (c-parse-state))
1768 lim pos end-pos)
1769 (unless (c-safe
1770 (goto-char (c-least-enclosing-brace paren-state))
1771 ;; If we moved to the outermost enclosing paren then we
1772 ;; can use c-safe-position to set the limit. Can't do
1773 ;; that otherwise since the earlier paren pair on
1774 ;; paren-state might very well be part of the
1775 ;; declaration we should go to.
1776 (setq lim (c-safe-position (point) paren-state))
1777 t)
1778 ;; At top level. Make sure we aren't inside a literal.
1779 (setq pos (c-literal-limits
1780 (c-safe-position (point) paren-state)))
1781 (if pos (goto-char (car pos))))
1782
1783 (when (c-beginning-of-macro)
1784 (throw 'exit
1785 (cons (point)
1786 (save-excursion
1787 (c-end-of-macro)
1788 (forward-line 1)
1789 (point)))))
1790
1791 (setq pos (point))
1792 (when (or (eq (car (c-beginning-of-decl-1 lim)) 'previous)
1793 (= pos (point)))
1794 ;; We moved back over the previous defun. Skip to the next
1795 ;; one. Not using c-forward-syntactic-ws here since we
1796 ;; should not skip a macro. We can also be directly after
1797 ;; the block in a `c-opt-block-decls-with-vars-key'
1798 ;; declaration, but then we won't move significantly far
1799 ;; here.
1800 (goto-char pos)
d9e94c22 1801 (c-forward-comments)
a66cd3ee
MS
1802
1803 (when (and near (c-beginning-of-macro))
1804 (throw 'exit
1805 (cons (point)
1806 (save-excursion
1807 (c-end-of-macro)
1808 (forward-line 1)
1809 (point))))))
1810
1811 (if (eobp) (throw 'exit nil))
1812
1813 ;; Check if `c-beginning-of-decl-1' put us after the block in a
1814 ;; declaration that doesn't end there. We're searching back and
1815 ;; forth over the block here, which can be expensive.
1816 (setq pos (point))
1817 (if (and c-opt-block-decls-with-vars-key
1818 (progn
1819 (c-backward-syntactic-ws)
1820 (eq (char-before) ?}))
1821 (eq (car (c-beginning-of-decl-1))
1822 'previous)
1823 (save-excursion
1824 (c-end-of-decl-1)
1825 (and (> (point) pos)
1826 (setq end-pos (point)))))
1827 nil
1828 (goto-char pos))
1829
1830 (if (and (not near) (> (point) start))
1831 nil
1832
1833 ;; Try to be line oriented; position the limits at the
1834 ;; closest preceding boi, and after the next newline, that
1835 ;; isn't inside a comment, but if we hit a neighboring
1836 ;; declaration then we instead use the exact declaration
1837 ;; limit in that direction.
1838 (cons (progn
1839 (setq pos (point))
1840 (while (and (/= (point) (c-point 'boi))
d9e94c22 1841 (c-backward-single-comment)))
a66cd3ee
MS
1842 (if (/= (point) (c-point 'boi))
1843 pos
1844 (point)))
1845 (progn
1846 (if end-pos
1847 (goto-char end-pos)
1848 (c-end-of-decl-1))
1849 (setq pos (point))
1850 (while (and (not (bolp))
1851 (not (looking-at "\\s *$"))
d9e94c22 1852 (c-forward-single-comment)))
a66cd3ee
MS
1853 (cond ((bolp)
1854 (point))
1855 ((looking-at "\\s *$")
1856 (forward-line 1)
1857 (point))
1858 (t
1859 pos)))))
1860 ))))
1861
1862(defun c-mark-function ()
1863 "Put mark at end of the current top-level declaration or macro, point at beginning.
1864If point is not inside any then the closest following one is chosen.
1865
1866As opposed to \\[c-beginning-of-defun] and \\[c-end-of-defun], this
1867function does not require the declaration to contain a brace block."
1868 (interactive)
1869
d9e94c22
MS
1870 (let (decl-limits)
1871 (c-save-buffer-state nil
1872 ;; We try to be line oriented, unless there are several
1873 ;; declarations on the same line.
1874 (if (looking-at c-syntactic-eol)
1875 (c-backward-token-2 1 nil (c-point 'bol)))
1876 (setq decl-limits (c-declaration-limits t)))
a66cd3ee 1877
a66cd3ee
MS
1878 (if (not decl-limits)
1879 (error "Cannot find any declaration")
1880 (goto-char (car decl-limits))
1881 (push-mark (cdr decl-limits) nil t))))
1882
fa7056bc
AM
1883(defun c-cpp-define-name ()
1884 "Return the name of the current CPP macro, or NIL if we're not in one."
1885 (interactive)
1886 (save-excursion
1887 (and c-opt-cpp-macro-define-start
1888 (c-beginning-of-macro)
1889 (looking-at c-opt-cpp-macro-define-start)
1890 (match-string-no-properties 1))))
1891
785eecbb 1892\f
51c9af45 1893;; Movement by statements.
0386b551
AM
1894(defun c-in-comment-line-prefix-p ()
1895 ;; Point is within a comment. Is it also within a comment-prefix?
1896 ;; Space at BOL which precedes a comment-prefix counts as part of it.
1897 ;;
1898 ;; This function might do hidden buffer changes.
1899 (let ((here (point)))
1900 (save-excursion
1901 (beginning-of-line)
1902 (skip-chars-forward " \t")
1903 (and (looking-at c-current-comment-prefix)
1904 (/= (match-beginning 0) (match-end 0))
1905 (< here (match-end 0))))))
1906
1907(defun c-narrow-to-comment-innards (range)
1908 ;; Narrow to the "inside" of the comment (block) defined by range, as
1909 ;; follows:
17264191 1910 ;;
0386b551
AM
1911 ;; A c-style block comment has its opening "/*" and its closing "*/" (if
1912 ;; present) removed. A c++-style line comment retains its opening "//" but
1913 ;; has any final NL removed. If POINT is currently outwith these innards,
1914 ;; move it to the appropriate boundary.
17264191 1915 ;;
0386b551
AM
1916 ;; This narrowing simplifies the sentence movement functions, since it
1917 ;; eliminates awkward things at the boundaries of the comment (block).
1918 ;;
1919 ;; This function might do hidden buffer changes.
1920 (let* ((lit-type (c-literal-type range))
1921 (beg (if (eq lit-type 'c) (+ (car range) 2) (car range)))
1922 (end (if (eq lit-type 'c)
1923 (if (and (eq (char-before (cdr range)) ?/)
1924 (eq (char-before (1- (cdr range))) ?*))
1925 (- (cdr range) 2)
1926 (point-max))
1927 (if (eq (cdr range) (point-max))
1928 (point-max)
1929 (- (cdr range) 1)))))
1930 (if (> (point) end)
1931 (goto-char end)) ; This would be done automatically by ...
1932 (if (< (point) beg)
1933 (goto-char beg)) ; ... narrow-to-region but is not documented.
1934 (narrow-to-region beg end)))
1935
1936(defun c-beginning-of-sentence-in-comment (range)
1937 ;; Move backwards to the "beginning of a sentence" within the comment
1938 ;; defined by RANGE, a cons of its starting and ending positions. If we
1939 ;; find a BOS, return NIL. Otherwise, move point to just before the start
1940 ;; of the comment and return T.
1941 ;;
1942 ;; The BOS is either text which follows a regexp match of sentence-end,
17264191 1943 ;; or text which is a beginning of "paragraph".
0386b551
AM
1944 ;; Comment-prefixes are treated like WS when calculating BOSes or BOPs.
1945 ;;
1946 ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
1947 ;; It is not a general function, but is intended only for calling from
1948 ;; c-move-over-sentence. Not all preconditions have been explicitly stated.
1949 ;;
1950 ;; This function might do hidden buffer changes.
1951 (save-match-data
1952 (let ((start-point (point)))
1953 (save-restriction
1954 (c-narrow-to-comment-innards range) ; This may move point back.
1955 (let* ((here (point))
1956 last
1957 (here-filler ; matches WS and comment-prefices at point.
1958 (concat "\\=\\(^[ \t]*\\(" c-current-comment-prefix "\\)"
1959 "\\|[ \t\n\r\f]\\)*"))
1960 (prefix-at-bol-here ; matches WS and prefix at BOL, just before point
1961 (concat "^[ \t]*\\(" c-current-comment-prefix "\\)[ \t\n\r\f]*\\="))
1962 ;; First, find the previous paragraph start, if any.
1963 (par-beg ; point where non-WS/non-prefix text of paragraph starts.
1964 (save-excursion
1965 (forward-paragraph -1) ; uses cc-mode values of
1966 ; paragraph-\(start\|separate\)
1967 (if (> (re-search-forward here-filler nil t) here)
1968 (goto-char here))
1969 (when (>= (point) here)
1970 (forward-paragraph -2)
1971 (if (> (re-search-forward here-filler nil t) here)
1972 (goto-char here)))
1973 (point))))
1974
1975 ;; Now seek successively earlier sentence ends between PAR-BEG and
1976 ;; HERE, until the "start of sentence" following it is earlier than
1977 ;; HERE, or we hit PAR-BEG. Beware of comment prefices!
1978 (while (and (re-search-backward (c-sentence-end) par-beg 'limit)
1979 (setq last (point))
1980 (goto-char (match-end 0)) ; tentative beginning of sentence
1981 (or (>= (point) here)
1982 (and (not (bolp)) ; Found a non-blank comment-prefix?
1983 (save-excursion
1984 (if (re-search-backward prefix-at-bol-here nil t)
1985 (/= (match-beginning 1) (match-end 1)))))
1986 (progn ; Skip the crud to find a real b-o-s.
1987 (if (c-in-comment-line-prefix-p)
1988 (beginning-of-line))
1989 (re-search-forward here-filler) ; always succeeds.
1990 (>= (point) here))))
1991 (goto-char last))
1992 (re-search-forward here-filler)))
1993
1994 (if (< (point) start-point)
1995 nil
1996 (goto-char (car range))
1997 t))))
1998
1999(defun c-end-of-sentence-in-comment (range)
2000 ;; Move forward to the "end of a sentence" within the comment defined by
2001 ;; RANGE, a cons of its starting and ending positions (enclosing the opening
2002 ;; comment delimiter and the terminating */ or newline). If we find an EOS,
2003 ;; return NIL. Otherwise, move point to just after the end of the comment
2004 ;; and return T.
2005 ;;
2006 ;; The EOS is just after the non-WS part of the next match of the regexp
2007 ;; sentence-end. Typically, this is just after one of [.!?]. If there is
2008 ;; no sentence-end match following point, any WS before the end of the
2009 ;; comment will count as EOS, providing we're not already in it.
2010 ;;
2011 ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
2012 ;; It is not a general function, but is intended only for calling from
2013 ;; c-move-over-sentence.
2014 ;;
2015 ;; This function might do hidden buffer changes.
2016 (save-match-data
2017 (let ((start-point (point))
2018 ;; (lit-type (c-literal-type range)) ; Commented out, 2005/11/23, ACM
2019 )
2020 (save-restriction
2021 (c-narrow-to-comment-innards range) ; This might move point forwards.
2022 (let* ((here (point))
2023 (par-end ; EOL position of last text in current/next paragraph.
2024 (save-excursion
2025 ;; The cc-mode values of paragraph-\(start\|separate\), set
2026 ;; in c-setup-paragraph-variables, are used in the
2027 ;; following.
2028 (forward-paragraph 1)
2029 (if (eq (preceding-char) ?\n) (forward-char -1))
2030 (when (<= (point) here) ; can happen, e.g., when HERE is at EOL.
2031 (goto-char here)
2032 (forward-paragraph 2)
2033 (if (eq (preceding-char) ?\n) (forward-char -1)))
2034 (point)))
2035
2036 last
2037 (prefix-at-bol-here
2038 (concat "^[ \t]*\\(" c-current-comment-prefix "\\)\\=")))
2039 ;; Go forward one "comment-prefix which looks like sentence-end"
2040 ;; each time round the following:
2041 (while (and (re-search-forward (c-sentence-end) par-end 'limit)
2042 (progn
2043 (setq last (point))
2044 (skip-chars-backward " \t\n")
2045 (or (and (not (bolp))
2046 (re-search-backward prefix-at-bol-here nil t)
2047 (/= (match-beginning 1) (match-end 1)))
2048 (<= (point) here))))
2049 (goto-char last))
2050
2051 ;; Take special action if we're up against the end of a comment (of
2052 ;; either sort): Leave point just after the last non-ws text.
2053 (if (eq (point) (point-max))
2054 (while (or (/= (skip-chars-backward " \t\n") 0)
2055 (and (re-search-backward prefix-at-bol-here nil t)
2056 (/= (match-beginning 1) (match-end 1))))))))
2057
2058 (if (> (point) start-point)
2059 nil
2060 (goto-char (cdr range))
2061 t))))
2062
2063(defun c-beginning-of-sentence-in-string (range)
2064 ;; Move backwards to the "beginning of a sentence" within the string defined
2065 ;; by RANGE, a cons of its starting and ending positions (enclosing the
2066 ;; string quotes). If we find a BOS, return NIL. Otherwise, move point to
2067 ;; just before the start of the string and return T.
2068 ;;
2069 ;; The BOS is either the text which follows a regexp match of sentence-end
2070 ;; or text which is a beginning of "paragraph". For the purposes of
2071 ;; determining paragraph boundaries, escaped newlines are treated as
2072 ;; ordinary newlines.
2073 ;;
2074 ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
2075 ;; It is not a general function, but is intended only for calling from
2076 ;; c-move-over-sentence.
2077 ;;
2078 ;; This function might do hidden buffer changes.
2079 (save-match-data
2080 (let* ((here (point)) last
2081 (end (1- (cdr range)))
2082 (here-filler ; matches WS and escaped newlines at point.
2083 "\\=\\([ \t\n\r\f]\\|\\\\[\n\r]\\)*")
2084 ;; Enhance paragraph-start and paragraph-separate also to recognise
2085 ;; blank lines terminated by escaped EOLs. IT MAY WELL BE that
2086 ;; these values should be customizable user options, or something.
2087 (paragraph-start c-string-par-start)
2088 (paragraph-separate c-string-par-separate)
2089
2090 (par-beg ; beginning of current (or previous) paragraph.
2091 (save-excursion
2092 (save-restriction
2093 (narrow-to-region (1+ (car range)) end)
2094 (forward-paragraph -1) ; uses above values of
2095 ; paragraph-\(start\|separate\)
2096 (if (> (re-search-forward here-filler nil t) here)
2097 (goto-char here))
2098 (when (>= (point) here)
2099 (forward-paragraph -2)
2100 (if (> (re-search-forward here-filler nil t) here)
2101 (goto-char here)))
2102 (point)))))
2103 ;; Now see if we can find a sentence end after PAR-BEG.
2104 (while (and (re-search-backward c-sentence-end-with-esc-eol par-beg 'limit)
2105 (setq last (point))
2106 (goto-char (match-end 0))
2107 (or (> (point) end)
2108 (progn
2109 (re-search-forward
2110 here-filler end t) ; always succeeds. Use end rather
2111 ; than here, in case point starts
2112 ; beyond the closing quote.
2113 (>= (point) here))))
2114 (goto-char last))
2115 (re-search-forward here-filler here t)
2116 (if (< (point) here)
2117 nil
2118 (goto-char (car range))
2119 t))))
2120
2121(defun c-end-of-sentence-in-string (range)
2122 ;; Move forward to the "end of a sentence" within the string defined by
2123 ;; RANGE, a cons of its starting and ending positions. If we find an EOS,
2124 ;; return NIL. Otherwise, move point to just after the end of the string
2125 ;; and return T.
2126 ;;
2127 ;; The EOS is just after the non-WS part of the next match of the regexp
2128 ;; sentence-end. Typically, this is just after one of [.!?]. If there is
2129 ;; no sentence-end match following point, any WS before the end of the
2130 ;; string will count as EOS, providing we're not already in it.
2131 ;;
2132 ;; This code was adapted from GNU Emacs's forward-sentence in paragraphs.el.
2133 ;; It is not a general function, but is intended only for calling from
2134 ;; c-move-over-sentence.
2135 ;;
2136 ;; This function might do hidden buffer changes.
2137 (save-match-data
2138 (let* ((here (point))
2139 last
2140 ;; Enhance paragraph-start and paragraph-separate to recognise
2141 ;; blank lines terminated by escaped EOLs.
2142 (paragraph-start c-string-par-start)
2143 (paragraph-separate c-string-par-separate)
2144
2145 (par-end ; EOL position of last text in current/next paragraph.
2146 (save-excursion
2147 (save-restriction
2148 (narrow-to-region (car range) (1- (cdr range)))
2149 ;; The above values of paragraph-\(start\|separate\) are used
2150 ;; in the following.
2151 (forward-paragraph 1)
2152 (setq last (point))
2153 ;; (re-search-backward filler-here nil t) would find an empty
2154 ;; string. Therefore we simulate it by the following:
2155 (while (or (/= (skip-chars-backward " \t\n\r\f") 0)
2156 (re-search-backward "\\\\\\($\\)\\=" nil t)))
2157 (unless (> (point) here)
2158 (goto-char last)
2159 (forward-paragraph 1)
2160 (while (or (/= (skip-chars-backward " \t\n\r\f") 0)
2161 (re-search-backward "\\\\\\($\\)\\=" nil t))))
2162 (point)))))
2163 ;; Try to go forward a sentence.
2164 (when (re-search-forward c-sentence-end-with-esc-eol par-end 'limit)
2165 (setq last (point))
2166 (while (or (/= (skip-chars-backward " \t\n") 0)
2167 (re-search-backward "\\\\\\($\\)\\=" nil t))))
2168 ;; Did we move a sentence, or did we hit the end of the string?
2169 (if (> (point) here)
2170 nil
2171 (goto-char (cdr range))
2172 t))))
2173
2174(defun c-ascertain-preceding-literal ()
2175 ;; Point is not in a literal (i.e. comment or string (include AWK regexp)).
2176 ;; If a literal is the next thing (aside from whitespace) to be found before
2177 ;; point, return a cons of its start.end positions (enclosing the
2178 ;; delimiters). Otherwise return NIL.
2179 ;;
2180 ;; This function might do hidden buffer changes.
2181 (save-excursion
2182 (c-collect-line-comments
2183 (let ((here (point))
2184 pos)
2185 (if (c-backward-single-comment)
2186 (cons (point) (progn (c-forward-single-comment) (point)))
2187 (save-restriction
2188 ;; to prevent `looking-at' seeing a " at point.
2189 (narrow-to-region (point-min) here)
2190 (when
2191 (or
2192 ;; An EOL can act as an "open string" terminator in AWK.
2193 (looking-at c-ws*-string-limit-regexp)
2194 (and (not (bobp))
2195 (progn (backward-char)
2196 (looking-at c-string-limit-regexp))))
2197 (goto-char (match-end 0)) ; just after the string terminator.
2198 (setq pos (point))
2199 (c-safe (c-backward-sexp 1) ; move back over the string.
2200 (cons (point) pos)))))))))
2201
2202(defun c-ascertain-following-literal ()
2203 ;; Point is not in a literal (i.e. comment or string (include AWK regexp)).
2204 ;; If a literal is the next thing (aside from whitespace) following point,
2205 ;; return a cons of its start.end positions (enclosing the delimiters).
2206 ;; Otherwise return NIL.
2207 ;;
2208 ;; This function might do hidden buffer changes.
2209 (save-excursion
2210 (c-collect-line-comments
2211 (let (pos)
2212 (c-skip-ws-forward)
2213 (if (looking-at c-string-limit-regexp) ; string-delimiter.
2214 (cons (point) (or (c-safe (progn (c-forward-sexp 1) (point)))
2215 (point-max)))
2216 (setq pos (point))
2217 (if (c-forward-single-comment)
2218 (cons pos (point))))))))
2219
2220(defun c-after-statement-terminator-p () ; Should we pass in LIM here?
2221 ;; Does point immediately follow a statement "terminator"? A virtual
2222 ;; semicolon is regarded here as such. So is a an opening brace ;-)
2223 ;;
2224 ;; This function might do hidden buffer changes.
2225 (or (save-excursion
2226 (backward-char)
2227 (and (looking-at "[;{}]")
2228 (not (and c-special-brace-lists ; Pike special brace lists.
2229 (eq (char-after) ?{)
2230 (c-looking-at-special-brace-list)))))
2231 (c-at-vsemi-p)
2232 ;; The following (for macros) is not strict about exactly where we are
2233 ;; wrt white space at the end of the macro. Doesn't seem to matter too
2234 ;; much. ACM 2004/3/29.
2235 (let (eom)
2236 (save-excursion
2237 (if (c-beginning-of-macro)
2238 (setq eom (progn (c-end-of-macro)
2239 (point)))))
2240 (when eom
2241 (save-excursion
2242 (c-forward-comments)
2243 (>= (point) eom))))))
2244
2245(defun c-back-over-illiterals (macro-start)
2246 ;; Move backwards over code which isn't a literal (i.e. comment or string),
2247 ;; stopping before reaching BOB or a literal or the boundary of a
2248 ;; preprocessor statement or the "beginning of a statement". MACRO-START is
2249 ;; the position of the '#' beginning the current preprocessor directive, or
2250 ;; NIL if we're not in such.
2251 ;;
2252 ;; Return a cons (A.B), where
2253 ;; A is NIL if we moved back to a BOS (and know it), T otherwise (we
2254 ;; didn't move, or we hit a literal, or we're not sure about BOS).
2255 ;; B is MACRO-BOUNDARY if we are about to cross the boundary out of or
2256 ;; into a macro, otherwise LITERAL if we've hit a literal, otherwise NIL
2257 ;;
2258 ;; The total collection of returned values is as follows:
2259 ;; (nil . nil): Found a BOS whilst remaining inside the illiterals.
2260 ;; (t . literal): No BOS found: only a comment/string. We _might_ be at
2261 ;; a BOS - the caller must check this.
2262 ;; (nil . macro-boundary): only happens with non-nil macro-start. We've
2263 ;; moved and reached the opening # of the macro.
2264 ;; (t . macro-boundary): Every other circumstance in which we're at a
2265 ;; macro-boundary. We might be at a BOS.
2266 ;;
2267 ;; Point is left either at the beginning-of-statement, or at the last non-ws
2268 ;; code before encountering the literal/BOB or macro-boundary.
2269 ;;
2270 ;; Note that this function moves within either preprocessor commands
2271 ;; (macros) or normal code, but will not cross a boundary between the two,
2272 ;; or between two distinct preprocessor commands.
2273 ;;
2274 ;; Stop before `{' and after `;', `{', `}' and `};' when not followed by `}'
2275 ;; or `)', but on the other side of the syntactic ws. Move by sexps and
2276 ;; move into parens. Also stop before `#' when it's at boi on a line.
2277 ;;
2278 ;; This function might do hidden buffer changes.
2279 (save-match-data
2280 (let ((here (point))
2281 last) ; marks the position of non-ws code, what'll be BOS if, say, a
2282 ; semicolon precedes it.
2283 (catch 'done
2284 (while t ;; We go back one "token" each iteration of the loop.
2285 (setq last (point))
2286 (cond
2287 ;; Stop at the token after a comment.
2288 ((c-backward-single-comment) ; Also functions as backwards-ws.
2289 (goto-char last)
2290 (throw 'done '(t . literal)))
2291
2292 ;; If we've gone back over a LF, we might have moved into or out of
2293 ;; a preprocessor line.
2294 ((and (save-excursion
2295 (beginning-of-line)
2296 (re-search-forward "\\(^\\|[^\\]\\)[\n\r]" last t))
2297 (if macro-start
2298 (< (point) macro-start)
2299 (c-beginning-of-macro)))
2300 (goto-char last)
2301 ;; Return a car of NIL ONLY if we've hit the opening # of a macro.
2302 (throw 'done (cons (or (eq (point) here)
2303 (not macro-start))
2304 'macro-boundary)))
2305
2306 ;; Have we found a virtual semicolon? If so, stop, unless the next
2307 ;; statement is where we started from.
2308 ((and (c-at-vsemi-p)
2309 (< last here)
2310 (not (memq (char-after last) '(?\) ?})))) ; we've moved back from ) or }
2311 (goto-char last)
2312 (throw 'done '(nil . nil)))
2313
2314 ;; Hit the beginning of the buffer/region?
2315 ((bobp)
2316 (if (/= here last)
2317 (goto-char last))
2318 (throw 'done '(nil . nil)))
2319
2320 ;; Move back a character.
2321 ((progn (backward-char) nil))
2322
2323 ;; Stop at "{" (unless it's a PIKE special brace list.)
2324 ((eq (char-after) ?\{)
2325 (if (and c-special-brace-lists
2326 (c-looking-at-special-brace-list))
2327 (skip-syntax-backward "w_") ; Speedup only.
2328 (if (/= here last)
2329 (goto-char last))
2330 (throw 'done '(nil . nil))))
2331
2332 ;; Have we reached the start of a macro? This always counts as
2333 ;; BOS. (N.B. I don't think (eq (point) here) can ever be true
2334 ;; here. FIXME!!! ACM 2004/3/29)
2335 ((and macro-start (eq (point) macro-start))
2336 (throw 'done (cons (eq (point) here) 'macro-boundary)))
2337
2338 ;; Stop at token just after "}" or ";".
2339 ((looking-at "[;}]")
2340 ;; If we've gone back over ;, {, or }, we're done.
2341 (if (or (= here last)
2342 (memq (char-after last) '(?\) ?}))) ; we've moved back from ) or }
2343 (if (and (eq (char-before) ?}) ; If };, treat them as a unit.
2344 (eq (char-after) ?\;))
2345 (backward-char))
2346 (goto-char last) ; To the statement starting after the ; or }.
2347 (throw 'done '(nil . nil))))
2348
2349 ;; Stop at the token after a string.
2350 ((looking-at c-string-limit-regexp) ; Just gone back over a string terminator?
2351 (goto-char last)
2352 (throw 'done '(t . literal)))
17264191 2353
0386b551
AM
2354 ;; Nothing special: go back word characters.
2355 (t (skip-syntax-backward "w_")) ; Speedup only.
2356 ))))))
2357
2358(defun c-forward-over-illiterals (macro-end allow-early-stop)
2359 ;; Move forwards over code, stopping before reaching EOB or a literal
2360 ;; (i.e. a comment/string) or the boundary of a preprocessor statement or
2361 ;; the "end of a statement". MACRO-END is the position of the EOL/EOB which
2362 ;; terminates the current preprocessor directive, or NIL if we're not in
2363 ;; such.
2364 ;;
2365 ;; ALLOW-EARLY-STOP is non-nil if it is permissible to return without moving
2366 ;; forward at all, should we encounter a `{'. This is an ugly kludge, but
2367 ;; seems unavoidable. Depending on the context this function is called
2368 ;; from, we _sometimes_ need to stop there. Currently (2004/4/3),
2369 ;; ALLOW-EARLY-STOP is applied only to open braces, not to virtual
2370 ;; semicolons, or anything else.
2371 ;;
2372 ;; Return a cons (A.B), where
2373 ;; A is NIL if we moved forward to an EOS, or stay at one (when
2374 ;; ALLOW-EARLY-STOP is set), T otherwise (we hit a literal).
2375 ;; B is 'MACRO-BOUNDARY if we are about to cross the boundary out of or
2376 ;; into a macro, otherwise 'LITERAL if we've hit a literal, otherwise NIL
2377 ;;
2378 ;; Point is left either after the end-of-statement, or at the last non-ws
2379 ;; code before encountering the literal, or the # of the preprocessor
2380 ;; statement, or at EOB [or just after last non-WS stuff??].
2381 ;;
2382 ;; As a clarification of "after the end-of-statement", if a comment or
2383 ;; whitespace follows a completed AWK statement, that statement is treated
2384 ;; as ending just after the last non-ws character before the comment.
17264191 2385 ;;
0386b551
AM
2386 ;; Note that this function moves within either preprocessor commands
2387 ;; (macros) or normal code, but not both within the same invocation.
2388 ;;
2389 ;; Stop before `{', `}', and `#' when it's at boi on a line, but on the
2390 ;; other side of the syntactic ws, and after `;', `}' and `};'. Only
2391 ;; stop before `{' if at top level or inside braces, though. Move by
2392 ;; sexps and move into parens. Also stop at eol of lines with `#' at
2393 ;; the boi.
2394 ;;
2395 ;; This function might do hidden buffer changes.
2396 (let ((here (point))
2397 last)
2398 (catch 'done
2399 (while t ;; We go one "token" forward each time round this loop.
2400 (setq last (point))
2401
2402 ;; If we've moved forward to a virtual semicolon, we're done.
2403 (if (and (> last here) ; Should we check ALLOW-EARLY-STOP, here? 2004/4/3
2404 (c-at-vsemi-p))
2405 (throw 'done '(nil . nil)))
2406
2407 (c-skip-ws-forward)
2408 (cond
2409 ;; Gone past the end of a macro?
2410 ((and macro-end (> (point) macro-end))
2411 (goto-char last)
2412 (throw 'done (cons (eq (point) here) 'macro-boundary)))
2413
2414 ;; About to hit a comment?
2415 ((save-excursion (c-forward-single-comment))
2416 (goto-char last)
2417 (throw 'done '(t . literal)))
2418
2419 ;; End of buffer?
2420 ((eobp)
2421 (if (/= here last)
2422 (goto-char last))
2423 (throw 'done '(nil . nil)))
2424
2425 ;; If we encounter a '{', stop just after the previous token.
2426 ((and (eq (char-after) ?{)
2427 (not (and c-special-brace-lists
2428 (c-looking-at-special-brace-list)))
2429 (or allow-early-stop (/= here last))
2430 (save-excursion ; Is this a check that we're NOT at top level?
2431;;;; NO! This seems to check that (i) EITHER we're at the top level; OR (ii) The next enclosing
2432;;;; level of bracketing is a '{'. HMM. Doesn't seem to make sense.
2433;;;; 2003/8/8 This might have something to do with the GCC extension "Statement Expressions", e.g.
2434;;;; while ({stmt1 ; stmt2 ; exp ;}). This form excludes such Statement Expressions.
2435 (or (not (c-safe (up-list -1) t))
2436 (= (char-after) ?{))))
2437 (goto-char last)
2438 (throw 'done '(nil . nil)))
2439
2440 ;; End of a PIKE special brace list? If so, step over it and continue.
2441 ((and c-special-brace-lists
2442 (eq (char-after) ?})
2443 (save-excursion
2444 (and (c-safe (up-list -1) t)
2445 (c-looking-at-special-brace-list))))
2446 (forward-char)
2447 (skip-syntax-forward "w_")) ; Speedup only.
2448
2449 ;; Have we got a '}' after having moved? If so, stop after the
2450 ;; previous token.
2451 ((and (eq (char-after) ?})
2452 (/= here last))
2453 (goto-char last)
2454 (throw 'done '(nil . nil)))
2455
2456 ;; Stop if we encounter a preprocessor line.
2457 ((and (not macro-end)
2458 (eq (char-after) ?#)
2459 (= (point) (c-point 'boi)))
2460 (goto-char last)
2461 ;(throw 'done (cons (eq (point) here) 'macro-boundary))) ; Changed 2003/3/26
2462 (throw 'done '(t . macro-boundary)))
2463
2464 ;; Stop after a ';', '}', or "};"
2465 ((looking-at ";\\|};?")
2466 (goto-char (match-end 0))
2467 (throw 'done '(nil . nil)))
2468
2469 ;; Found a string (this subsumes AWK regexps)?
2470 ((looking-at c-string-limit-regexp)
2471 (goto-char last)
2472 (throw 'done '(t . literal)))
2473
2474 (t
2475 (forward-char) ; Can't fail - we checked (eobp) earlier on.
2476 (skip-syntax-forward "w_") ; Speedup only.
2477 (when (and macro-end (> (point) macro-end))
2478 (goto-char last)
2479 (throw 'done (cons (eq (point) here) 'macro-boundary))))
2480 )))))
2481
2482(defun c-one-line-string-p (range)
2483 ;; Is the literal defined by RANGE a string contained in a single line?
2484 ;;
2485 ;; This function might do hidden buffer changes.
2486 (save-excursion
2487 (goto-char (car range))
2488 (and (looking-at c-string-limit-regexp)
2489 (progn (skip-chars-forward "^\n" (cdr range))
2490 (eq (point) (cdr range))))))
2491
785eecbb
RS
2492(defun c-beginning-of-statement (&optional count lim sentence-flag)
2493 "Go to the beginning of the innermost C statement.
2494With prefix arg, go back N - 1 statements. If already at the
28c236de
RS
2495beginning of a statement then go to the beginning of the closest
2496preceding one, moving into nested blocks if necessary (use
130c507e
GM
2497\\[backward-sexp] to skip over a block). If within or next to a
2498comment or multiline string, move by sentences instead of statements.
785eecbb
RS
2499
2500When called from a program, this function takes 3 optional args: the
2501repetition count, a buffer position limit which is the farthest back
130c507e 2502to search for the syntactic context, and a flag saying whether to do
a66cd3ee
MS
2503sentence motion in or near comments and multiline strings.
2504
0386b551
AM
2505Note that for use in programs, `c-beginning-of-statement-1' is
2506usually better. It has much better defined semantics than this one,
2507which is intended for interactive use, and might therefore change to
2508be more \"DWIM:ey\"."
785eecbb
RS
2509 (interactive (list (prefix-numeric-value current-prefix-arg)
2510 nil t))
0386b551
AM
2511 (if (< count 0)
2512 (c-end-of-statement (- count) lim sentence-flag)
2513 (c-save-buffer-state
2514 ((count (or count 1))
2515 last ; start point for going back ONE chunk. Updated each chunk movement.
2516 (macro-fence
2517 (save-excursion (and (not (bobp)) (c-beginning-of-macro) (point))))
2518 res ; result from sub-function call
2519 not-bos ; "not beginning-of-statement"
2520 (range (c-collect-line-comments (c-literal-limits lim)))) ; (start.end) of current literal or NIL
2521
2522 ;; Go back one statement at each iteration of the following loop.
2523 (while (and (/= count 0)
2524 (or (not lim) (> (point) lim)))
2525 ;; Go back one "chunk" each time round the following loop, stopping
2526 ;; when we reach a statement boundary, etc.
2527 (setq last (point))
2528 (while
2529 (cond ; Each arm of this cond returns NIL on reaching a desired
2530 ; statement boundary, non-NIL otherwise.
2531 ((bobp)
2532 (setq count 0)
2533 nil)
2534
2535 (range ; point is within or approaching a literal.
2536 (cond
2537 ;; Single line string or sentence-flag is null => skip the
2538 ;; entire literal.
2539 ((or (null sentence-flag)
2540 (c-one-line-string-p range))
2541 (goto-char (car range))
2542 (setq range (c-ascertain-preceding-literal))
2543 ;; N.B. The following is essentially testing for an AWK regexp
2544 ;; at BOS:
2545 ;; Was the previous non-ws thing an end of statement?
2546 (save-excursion
2547 (if macro-fence
2548 (c-backward-comments)
2549 (c-backward-syntactic-ws))
2550 (not (or (bobp) (c-after-statement-terminator-p)))))
2551
2552 ;; Comment inside a statement or a multi-line string.
2553 (t (when (setq res ; returns non-nil when we go out of the literal
2554 (if (eq (c-literal-type range) 'string)
2555 (c-beginning-of-sentence-in-string range)
2556 (c-beginning-of-sentence-in-comment range)))
2557 (setq range (c-ascertain-preceding-literal)))
2558 res)))
2559
2560 ;; Non-literal code.
2561 (t (setq res (c-back-over-illiterals macro-fence))
2562 (setq not-bos ; "not reached beginning-of-statement".
2563 (or (= (point) last)
2564 (memq (char-after) '(?\) ?\}))
2565 (and
2566 (car res)
2567 ;; We're at a tentative BOS. The next form goes
2568 ;; back over WS looking for an end of previous
2569 ;; statement.
2570 (not (save-excursion
2571 (if macro-fence
2572 (c-backward-comments)
2573 (c-backward-syntactic-ws))
2574 (or (bobp) (c-after-statement-terminator-p)))))))
2575 ;; Are we about to move backwards into or out of a
2576 ;; preprocessor command? If so, locate it's beginning.
2577 (when (eq (cdr res) 'macro-boundary)
2578 (save-excursion
2579 (beginning-of-line)
2580 (setq macro-fence
2581 (and (not (bobp))
2582 (progn (c-skip-ws-backward) (c-beginning-of-macro))
2583 (point)))))
2584 ;; Are we about to move backwards into a literal?
2585 (when (memq (cdr res) '(macro-boundary literal))
2586 (setq range (c-ascertain-preceding-literal)))
2587 not-bos))
2588 (setq last (point)))
2589
2590 (if (/= count 0) (setq count (1- count))))
2591 (c-keep-region-active))))
785eecbb
RS
2592
2593(defun c-end-of-statement (&optional count lim sentence-flag)
2594 "Go to the end of the innermost C statement.
28c236de
RS
2595With prefix arg, go forward N - 1 statements. Move forward to the end
2596of the next statement if already at end, and move into nested blocks
130c507e
GM
2597\(use \\[forward-sexp] to skip over a block). If within or next to a
2598comment or multiline string, move by sentences instead of statements.
785eecbb
RS
2599
2600When called from a program, this function takes 3 optional args: the
2601repetition count, a buffer position limit which is the farthest back
130c507e
GM
2602to search for the syntactic context, and a flag saying whether to do
2603sentence motion in or near comments and multiline strings."
785eecbb
RS
2604 (interactive (list (prefix-numeric-value current-prefix-arg)
2605 nil t))
0386b551
AM
2606 (setq count (or count 1))
2607 (if (< count 0) (c-beginning-of-statement (- count) lim sentence-flag)
2608
2609 (c-save-buffer-state
2610 (here ; start point for going forward ONE statement. Updated each statement.
2611 (macro-fence
2612 (save-excursion
2613 (and (not (eobp)) (c-beginning-of-macro)
2614 (progn (c-end-of-macro) (point)))))
2615 res
2616 (range (c-collect-line-comments (c-literal-limits lim)))) ; (start.end) of current literal or NIL
2617
2618 ;; Go back/forward one statement at each iteration of the following loop.
2619 (while (and (/= count 0)
2620 (or (not lim) (< (point) lim)))
2621 (setq here (point)) ; ONLY HERE is HERE updated
2622
2623 ;; Go forward one "chunk" each time round the following loop, stopping
2624 ;; when we reach a statement boundary, etc.
2625 (while
2626 (cond ; Each arm of this cond returns NIL on reaching a desired
2627 ; statement boundary, non-NIL otherwise.
2628 ((eobp)
2629 (setq count 0)
2630 nil)
2631
2632 (range ; point is within a literal.
2633 (cond
2634 ;; sentence-flag is null => skip the entire literal.
2635 ;; or a Single line string.
2636 ((or (null sentence-flag)
2637 (c-one-line-string-p range))
2638 (goto-char (cdr range))
2639 (setq range (c-ascertain-following-literal))
2640 ;; Is there a virtual semicolon here (e.g. for AWK)?
2641 (not (c-at-vsemi-p)))
2642
2643 ;; Comment or multi-line string.
2644 (t (when (setq res ; gets non-nil when we go out of the literal
2645 (if (eq (c-literal-type range) 'string)
2646 (c-end-of-sentence-in-string range)
2647 (c-end-of-sentence-in-comment range)))
2648 (setq range (c-ascertain-following-literal)))
2649 ;; If we've just come forward out of a literal, check for
2650 ;; vsemi. (N.B. AWK can't have a vsemi after a comment, but
2651 ;; some other language may do in the future)
2652 (and res
2653 (not (c-at-vsemi-p))))))
2654
2655 ;; Non-literal code.
2656 (t (setq res (c-forward-over-illiterals macro-fence
2657 (> (point) here)))
2658 ;; Are we about to move forward into or out of a
2659 ;; preprocessor command?
2660 (when (eq (cdr res) 'macro-boundary)
2661 (save-excursion
2662 (end-of-line)
2663 (setq macro-fence
2664 (and (not (eobp))
2665 (progn (c-skip-ws-forward)
2666 (c-beginning-of-macro))
2667 (progn (c-end-of-macro)
2668 (point))))))
2669 ;; Are we about to move forward into a literal?
2670 (when (memq (cdr res) '(macro-boundary literal))
2671 (setq range (c-ascertain-following-literal)))
2672 (car res))))
2673
2674 (if (/= count 0) (setq count (1- count))))
2675 (c-keep-region-active))))
17264191 2676
785eecbb
RS
2677\f
2678;; set up electric character functions to work with pending-del,
2679;; (a.k.a. delsel) mode. All symbols get the t value except
c93a62d8 2680;; the functions which delete, which gets 'supersede.
6b7513e3 2681(mapc
785eecbb
RS
2682 (function
2683 (lambda (sym)
2684 (put sym 'delete-selection t) ; for delsel (Emacs)
2685 (put sym 'pending-delete t))) ; for pending-del (XEmacs)
2686 '(c-electric-pound
2687 c-electric-brace
2688 c-electric-slash
2689 c-electric-star
2690 c-electric-semi&comma
2691 c-electric-lt-gt
0ec8351b
BW
2692 c-electric-colon
2693 c-electric-paren))
c93a62d8
RS
2694(put 'c-electric-delete 'delete-selection 'supersede) ; delsel
2695(put 'c-electric-delete 'pending-delete 'supersede) ; pending-del
2696(put 'c-electric-backspace 'delete-selection 'supersede) ; delsel
2697(put 'c-electric-backspace 'pending-delete 'supersede) ; pending-del
7443aaa6
SM
2698(put 'c-electric-delete-forward 'delete-selection 'supersede) ; delsel
2699(put 'c-electric-delete-forward 'pending-delete 'supersede) ; pending-del
785eecbb
RS
2700
2701\f
51c9af45 2702;; Inserting/indenting comments
a66cd3ee 2703(defun c-calc-comment-indent (entry)
0386b551 2704 ;; This function might do hidden buffer changes.
a66cd3ee
MS
2705 (if (symbolp entry)
2706 (setq entry (or (assq entry c-indent-comment-alist)
2707 (assq 'other c-indent-comment-alist)
2708 '(default . (column . nil)))))
2709 (let ((action (car (cdr entry)))
2710 (value (cdr (cdr entry)))
2711 (col (current-column)))
2712 (cond ((eq action 'space)
2713 (+ col value))
2714 ((eq action 'column)
2715 (unless value (setq value comment-column))
2716 (if (bolp)
2717 ;; Do not pad with one space if we're at bol.
2718 value
2719 (max (1+ col) value)))
2720 ((eq action 'align)
2721 (or (save-excursion
2722 (beginning-of-line)
2723 (unless (bobp)
2724 (backward-char)
2725 (let ((lim (c-literal-limits (c-point 'bol) t)))
2726 (when (consp lim)
2727 (goto-char (car lim))
0386b551 2728 (when (looking-at "/[/*]") ; FIXME!!! Adapt for AWK! (ACM, 2005/11/18)
a66cd3ee
MS
2729 ;; Found comment to align with.
2730 (if (bolp)
2731 ;; Do not pad with one space if we're at bol.
2732 0
2733 (max (1+ col) (current-column))))))))
2734 ;; Recurse to handle value as a new spec.
2735 (c-calc-comment-indent (cdr entry)))))))
2736
785eecbb 2737(defun c-comment-indent ()
a66cd3ee
MS
2738 "Used by `indent-for-comment' to create and indent comments.
2739See `c-indent-comment-alist' for a description."
2740 (save-excursion
2741 (end-of-line)
d9e94c22
MS
2742 (c-save-buffer-state
2743 ((eot (let ((lim (c-literal-limits (c-point 'bol) t)))
a66cd3ee
MS
2744 (or (when (consp lim)
2745 (goto-char (car lim))
2746 (when (looking-at "/[/*]")
2747 (skip-chars-backward " \t")
2748 (point)))
2749 (progn
2750 (skip-chars-backward " \t")
2751 (point)))))
2752 (line-type
2753 (cond ((looking-at "^/[/*]")
2754 'anchored-comment)
2755 ((progn (beginning-of-line)
2756 (eq (point) eot))
2757 'empty-line)
2758 ((progn (back-to-indentation)
2759 (and (eq (char-after) ?})
2760 (eq (point) (1- eot))))
2761 'end-block)
2762 ((and (looking-at "#[ \t]*\\(endif\\|else\\)")
2763 (eq (match-end 0) eot))
2764 'cpp-end-block)
2765 (t
2766 'other))))
2767 (if (and (memq line-type '(anchored-comment empty-line))
2768 c-indent-comments-syntactically-p)
d9e94c22 2769 (let ((c-syntactic-context (c-guess-basic-syntax)))
785eecbb
RS
2770 ;; BOGOSITY ALERT: if we're looking at the eol, its
2771 ;; because indent-for-comment hasn't put the comment-start
2772 ;; in the buffer yet. this will screw up the syntactic
2773 ;; analysis so we kludge in the necessary info. Another
2774 ;; kludge is that if we're at the bol, then we really want
2775 ;; to ignore any anchoring as specified by
2776 ;; c-comment-only-line-offset since it doesn't apply here.
a66cd3ee 2777 (if (eolp)
785eecbb
RS
2778 (c-add-syntax 'comment-intro))
2779 (let ((c-comment-only-line-offset
2780 (if (consp c-comment-only-line-offset)
2781 c-comment-only-line-offset
2782 (cons c-comment-only-line-offset
2783 c-comment-only-line-offset))))
d9e94c22 2784 (c-get-syntactic-indentation c-syntactic-context)))
a66cd3ee
MS
2785 (goto-char eot)
2786 (c-calc-comment-indent line-type)))))
785eecbb 2787
fd3b1ef6 2788\f
785eecbb
RS
2789;; used by outline-minor-mode
2790(defun c-outline-level ()
a66cd3ee
MS
2791 (let (buffer-invisibility-spec);; This so that `current-column' DTRT
2792 ;; in otherwise-hidden text.
de28797f
SM
2793 (save-excursion
2794 (skip-chars-forward "\t ")
2795 (current-column))))
785eecbb
RS
2796
2797\f
51c9af45 2798;; Movement by CPP conditionals.
785eecbb
RS
2799(defun c-up-conditional (count)
2800 "Move back to the containing preprocessor conditional, leaving mark behind.
2801A prefix argument acts as a repeat count. With a negative argument,
2802move forward to the end of the containing preprocessor conditional.
51f606de 2803
0386b551
AM
2804\"#elif\" is treated like \"#else\" followed by \"#if\", so the
2805function stops at them when going backward, but not when going
2806forward."
51f606de
GM
2807 (interactive "p")
2808 (c-forward-conditional (- count) -1)
2809 (c-keep-region-active))
17264191 2810
51f606de 2811(defun c-up-conditional-with-else (count)
0386b551
AM
2812 "Move back to the containing preprocessor conditional, including \"#else\".
2813Just like `c-up-conditional', except it also stops at \"#else\"
51f606de
GM
2814directives."
2815 (interactive "p")
2816 (c-forward-conditional (- count) -1 t)
2817 (c-keep-region-active))
2818
2819(defun c-down-conditional (count)
2820 "Move forward into the next preprocessor conditional, leaving mark behind.
2821A prefix argument acts as a repeat count. With a negative argument,
2822move backward into the previous preprocessor conditional.
2823
0386b551
AM
2824\"#elif\" is treated like \"#else\" followed by \"#if\", so the
2825function stops at them when going forward, but not when going
2826backward."
785eecbb 2827 (interactive "p")
51f606de 2828 (c-forward-conditional count 1)
785eecbb
RS
2829 (c-keep-region-active))
2830
51f606de 2831(defun c-down-conditional-with-else (count)
0386b551
AM
2832 "Move forward into the next preprocessor conditional, including \"#else\".
2833Just like `c-down-conditional', except it also stops at \"#else\"
51f606de
GM
2834directives."
2835 (interactive "p")
2836 (c-forward-conditional count 1 t)
2837 (c-keep-region-active))
2838
2839(defun c-backward-conditional (count &optional target-depth with-else)
785eecbb
RS
2840 "Move back across a preprocessor conditional, leaving mark behind.
2841A prefix argument acts as a repeat count. With a negative argument,
2842move forward across a preprocessor conditional."
2843 (interactive "p")
51f606de 2844 (c-forward-conditional (- count) target-depth with-else)
785eecbb
RS
2845 (c-keep-region-active))
2846
51f606de 2847(defun c-forward-conditional (count &optional target-depth with-else)
785eecbb
RS
2848 "Move forward across a preprocessor conditional, leaving mark behind.
2849A prefix argument acts as a repeat count. With a negative argument,
51f606de
GM
2850move backward across a preprocessor conditional.
2851
0386b551
AM
2852\"#elif\" is treated like \"#else\" followed by \"#if\", except that
2853the nesting level isn't changed when tracking subconditionals.
51f606de
GM
2854
2855The optional argument TARGET-DEPTH specifies the wanted nesting depth
2856after each scan. I.e. if TARGET-DEPTH is -1, the function will move
2857out of the enclosing conditional. A non-integer non-nil TARGET-DEPTH
2858counts as -1.
2859
0386b551
AM
2860If the optional argument WITH-ELSE is non-nil, \"#else\" directives
2861are treated as conditional clause limits. Normally they are ignored."
785eecbb
RS
2862 (interactive "p")
2863 (let* ((forward (> count 0))
2864 (increment (if forward -1 1))
2865 (search-function (if forward 're-search-forward 're-search-backward))
2866 (new))
51f606de
GM
2867 (unless (integerp target-depth)
2868 (setq target-depth (if target-depth -1 0)))
785eecbb
RS
2869 (save-excursion
2870 (while (/= count 0)
51f606de
GM
2871 (let ((depth 0)
2872 ;; subdepth is the depth in "uninteresting" subtrees,
2873 ;; i.e. those that takes us farther from the target
2874 ;; depth instead of closer.
2875 (subdepth 0)
2876 found)
785eecbb
RS
2877 (save-excursion
2878 ;; Find the "next" significant line in the proper direction.
2879 (while (and (not found)
2880 ;; Rather than searching for a # sign that
2881 ;; comes at the beginning of a line aside from
2882 ;; whitespace, search first for a string
2883 ;; starting with # sign. Then verify what
2884 ;; precedes it. This is faster on account of
2885 ;; the fastmap feature of the regexp matcher.
2886 (funcall search-function
51f606de 2887 "#[ \t]*\\(if\\|elif\\|endif\\|else\\)"
785eecbb
RS
2888 nil t))
2889 (beginning-of-line)
2890 ;; Now verify it is really a preproc line.
51f606de
GM
2891 (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\|else\\)")
2892 (let (dchange (directive (match-string 1)))
2893 (cond ((string= directive "if")
2894 (setq dchange (- increment)))
2895 ((string= directive "endif")
2896 (setq dchange increment))
2897 ((= subdepth 0)
2898 ;; When we're not in an "uninteresting"
2899 ;; subtree, we might want to act on "elif"
2900 ;; and "else" too.
2901 (if (cond (with-else
2902 ;; Always move toward the target depth.
2903 (setq dchange
2904 (if (> target-depth 0) 1 -1)))
2905 ((string= directive "elif")
2906 (setq dchange (- increment))))
2907 ;; Ignore the change if it'd take us
2908 ;; into an "uninteresting" subtree.
2909 (if (eq (> dchange 0) (<= target-depth 0))
2910 (setq dchange nil)))))
2911 (when dchange
2912 (when (or (/= subdepth 0)
2913 (eq (> dchange 0) (<= target-depth 0)))
2914 (setq subdepth (+ subdepth dchange)))
2915 (setq depth (+ depth dchange))
2916 ;; If we are trying to move across, and we find an
2917 ;; end before we find a beginning, get an error.
2918 (if (and (< depth target-depth) (< dchange 0))
2919 (error (if forward
2920 "No following conditional at this level"
2921 "No previous conditional at this level"))))
785eecbb
RS
2922 ;; When searching forward, start from next line so
2923 ;; that we don't find the same line again.
2924 (if forward (forward-line 1))
51f606de
GM
2925 ;; We found something if we've arrived at the
2926 ;; target depth.
2927 (if (and dchange (= depth target-depth))
785eecbb
RS
2928 (setq found (point))))
2929 ;; else
51f606de 2930 (if forward (forward-line 1)))))
785eecbb
RS
2931 (or found
2932 (error "No containing preprocessor conditional"))
2933 (goto-char (setq new found)))
2934 (setq count (+ count increment))))
2935 (push-mark)
2936 (goto-char new))
2937 (c-keep-region-active))
2938
2939\f
2940;; commands to indent lines, regions, defuns, and expressions
b8ded794 2941(defun c-indent-command (&optional arg)
785eecbb
RS
2942 "Indent current line as C code, and/or insert some whitespace.
2943
2944If `c-tab-always-indent' is t, always just indent the current line.
2945If nil, indent the current line only if point is at the left margin or
2946in the line's indentation; otherwise insert some whitespace[*]. If
2947other than nil or t, then some whitespace[*] is inserted only within
2a15eb73 2948literals (comments and strings), but the line is always reindented.
785eecbb 2949
b8ded794 2950If `c-syntactic-indentation' is t, indentation is done according to
a66cd3ee
MS
2951the syntactic context. A numeric argument, regardless of its value,
2952means indent rigidly all the lines of the expression starting after
2953point so that this line becomes properly indented. The relative
2954indentation among the lines of the expression is preserved.
2955
2956If `c-syntactic-indentation' is nil, the line is just indented one
b8ded794
GM
2957step according to `c-basic-offset'. In this mode, a numeric argument
2958indents a number of such steps, positive or negative, and an empty
2959prefix argument is equivalent to -1.
2960
785eecbb
RS
2961 [*] The amount and kind of whitespace inserted is controlled by the
2962 variable `c-insert-tab-function', which is called to do the actual
2963 insertion of whitespace. Normally the function in this variable
2964 just inserts a tab character, or the equivalent number of spaces,
2965 depending on the variable `indent-tabs-mode'."
2966
0386b551 2967 (interactive "P")
a66cd3ee 2968 (let ((indent-function
b8ded794 2969 (if c-syntactic-indentation
130c507e 2970 (symbol-function 'indent-according-to-mode)
b8ded794 2971 (lambda ()
a66cd3ee 2972 (let ((c-macro-start c-macro-start)
0386b551
AM
2973 (steps (if (equal arg '(4))
2974 -1
2975 (prefix-numeric-value arg))))
a66cd3ee
MS
2976 (c-shift-line-indentation (* steps c-basic-offset))
2977 (when (and c-auto-align-backslashes
2978 (save-excursion
2979 (end-of-line)
2980 (eq (char-before) ?\\))
2981 (c-query-and-set-macro-start))
2982 ;; Realign the line continuation backslash if inside a macro.
2983 (c-backslash-region (point) (point) nil t)))
b8ded794 2984 ))))
0386b551 2985 (if (and c-syntactic-indentation arg)
b8ded794
GM
2986 ;; If c-syntactic-indentation and got arg, always indent this
2987 ;; line as C and shift remaining lines of expression the same
2988 ;; amount.
130c507e
GM
2989 (let ((shift-amt (save-excursion
2990 (back-to-indentation)
2991 (current-column)))
785eecbb 2992 beg end)
130c507e
GM
2993 (c-indent-line)
2994 (setq shift-amt (- (save-excursion
2995 (back-to-indentation)
2996 (current-column))
2997 shift-amt))
785eecbb
RS
2998 (save-excursion
2999 (if (eq c-tab-always-indent t)
0386b551 3000 (beginning-of-line)) ; FIXME!!! What is this here for? ACM 2005/10/31
785eecbb 3001 (setq beg (point))
0ec8351b 3002 (c-forward-sexp 1)
785eecbb
RS
3003 (setq end (point))
3004 (goto-char beg)
3005 (forward-line 1)
3006 (setq beg (point)))
3007 (if (> end beg)
130c507e 3008 (indent-code-rigidly beg end shift-amt "#")))
b8ded794 3009 ;; Else use c-tab-always-indent to determine behavior.
785eecbb 3010 (cond
0386b551 3011 ;; CASE 1: indent when at column zero or in line's indentation,
785eecbb
RS
3012 ;; otherwise insert a tab
3013 ((not c-tab-always-indent)
3014 (if (save-excursion
3015 (skip-chars-backward " \t")
3016 (not (bolp)))
3017 (funcall c-insert-tab-function)
b8ded794 3018 (funcall indent-function)))
785eecbb
RS
3019 ;; CASE 2: just indent the line
3020 ((eq c-tab-always-indent t)
b8ded794 3021 (funcall indent-function))
785eecbb
RS
3022 ;; CASE 3: if in a literal, insert a tab, but always indent the
3023 ;; line
3024 (t
0386b551 3025 (if (c-save-buffer-state () (c-in-literal))
785eecbb 3026 (funcall c-insert-tab-function))
b8ded794 3027 (funcall indent-function)
785eecbb
RS
3028 )))))
3029
3030(defun c-indent-exp (&optional shutup-p)
130c507e 3031 "Indent each line in the balanced expression following point syntactically.
17264191 3032If optional SHUTUP-P is non-nil, no errors are signaled if no
130c507e 3033balanced expression is found."
28c236de 3034 (interactive "*P")
51f606de 3035 (let ((here (point-marker))
130c507e 3036 end)
51f606de 3037 (set-marker-insertion-type here t)
785eecbb 3038 (unwind-protect
a66cd3ee
MS
3039 (let ((start (save-restriction
3040 ;; Find the closest following open paren that
3041 ;; ends on another line.
3042 (narrow-to-region (point-min) (c-point 'eol))
3043 (let (beg (end (point)))
3044 (while (and (setq beg (c-down-list-forward end))
3045 (setq end (c-up-list-forward beg))))
3046 (and beg
3047 (eq (char-syntax (char-before beg)) ?\()
3048 (1- beg))))))
785eecbb 3049 ;; sanity check
130c507e
GM
3050 (if (not start)
3051 (unless shutup-p
3052 (error "Cannot find start of balanced expression to indent"))
19da29f9 3053 (goto-char start)
a66cd3ee 3054 (setq end (c-safe (scan-sexps (point) 1)))
130c507e
GM
3055 (if (not end)
3056 (unless shutup-p
3057 (error "Cannot find end of balanced expression to indent"))
a66cd3ee
MS
3058 (forward-line)
3059 (if (< (point) end)
3060 (c-indent-region (point) end)))))
51f606de
GM
3061 (goto-char here)
3062 (set-marker here nil))))
785eecbb
RS
3063
3064(defun c-indent-defun ()
a66cd3ee
MS
3065 "Indent the current top-level declaration or macro syntactically.
3066In the macro case this also has the effect of realigning any line
3067continuation backslashes, unless `c-auto-align-backslashes' is nil."
28c236de 3068 (interactive "*")
a66cd3ee 3069 (let ((here (point-marker)) decl-limits)
785eecbb 3070 (unwind-protect
d9e94c22
MS
3071 (progn
3072 (c-save-buffer-state nil
3073 ;; We try to be line oriented, unless there are several
3074 ;; declarations on the same line.
3075 (if (looking-at c-syntactic-eol)
3076 (c-backward-token-2 1 nil (c-point 'bol))
3077 (c-forward-token-2 0 nil (c-point 'eol)))
3078 (setq decl-limits (c-declaration-limits nil)))
3079 (if decl-limits
3080 (c-indent-region (car decl-limits)
3081 (cdr decl-limits))))
785eecbb
RS
3082 (goto-char here)
3083 (set-marker here nil))))
3084
130c507e 3085(defun c-indent-region (start end &optional quiet)
a66cd3ee
MS
3086 "Indent syntactically every line whose first char is between START
3087and END inclusive. If the optional argument QUIET is non-nil then no
3088syntactic errors are reported, even if `c-report-syntactic-errors' is
3089non-nil."
785eecbb 3090 (save-excursion
a66cd3ee 3091 (goto-char end)
d9e94c22 3092 (skip-chars-backward " \t\n\r\f\v")
a66cd3ee 3093 (setq end (point))
785eecbb
RS
3094 (goto-char start)
3095 ;; Advance to first nonblank line.
a66cd3ee 3096 (beginning-of-line)
d9e94c22 3097 (skip-chars-forward " \t\n\r\f\v")
a66cd3ee 3098 (setq start (point))
785eecbb 3099 (beginning-of-line)
130c507e
GM
3100 (setq c-parsing-error
3101 (or (let ((endmark (copy-marker end))
3102 (c-parsing-error nil)
3103 ;; shut up any echo msgs on indiv lines
a66cd3ee 3104 (c-echo-syntactic-information-p nil)
9644a7da 3105 (ml-macro-start ; Start pos of multi-line macro.
24f15006
AM
3106 (and (c-save-buffer-state ()
3107 (save-excursion (c-beginning-of-macro)))
9644a7da 3108 (eq (char-before (c-point 'eol)) ?\\)
24f15006 3109 start))
a66cd3ee
MS
3110 (c-fix-backslashes nil)
3111 syntax)
130c507e
GM
3112 (unwind-protect
3113 (progn
3114 (c-progress-init start end 'c-indent-region)
24f15006
AM
3115
3116 (while (and (bolp) ;; One line each time round the loop.
130c507e
GM
3117 (not (eobp))
3118 (< (point) endmark))
3119 ;; update progress
3120 (c-progress-update)
a66cd3ee 3121 ;; skip empty lines
24f15006 3122 (unless (or (looking-at "\\s *$")
9644a7da 3123 (and ml-macro-start (looking-at "\\s *\\\\$")))
24f15006
AM
3124 ;; Get syntax and indent.
3125 (c-save-buffer-state nil
3126 (setq syntax (c-guess-basic-syntax)))
3127 (c-indent-line syntax t t))
3128
9644a7da
AM
3129 (if ml-macro-start
3130 ;; End of current multi-line macro?
3131 (when (and c-auto-align-backslashes
3132 (not (eq (char-before (c-point 'eol)) ?\\)))
3133 ;; Fixup macro backslashes.
3134 (c-backslash-region ml-macro-start (c-point 'bonl) nil)
3135 (setq ml-macro-start nil))
3136 ;; New multi-line macro?
3137 (if (and (assq 'cpp-macro syntax)
3138 (eq (char-before (c-point 'eol)) ?\\))
3139 (setq ml-macro-start (point))))
3140
24f15006
AM
3141 (forward-line))
3142
9644a7da
AM
3143 (if (and ml-macro-start c-auto-align-backslashes)
3144 (c-backslash-region ml-macro-start (c-point 'bopl) nil t)))
130c507e
GM
3145 (set-marker endmark nil)
3146 (c-progress-fini 'c-indent-region))
3147 (c-echo-parsing-error quiet))
3148 c-parsing-error))))
785eecbb 3149
130c507e
GM
3150(defun c-fn-region-is-active-p ()
3151 ;; Function version of the macro for use in places that aren't
3152 ;; compiled, e.g. in the menus.
3153 (c-region-is-active-p))
3154
c02a1ee9
RS
3155(defun c-indent-line-or-region (&optional arg region)
3156 "Indent active region, current line, or block starting on this line.
3157In Transient Mark mode, when the region is active, reindent the region.
3158Othewise, with a prefix argument, rigidly reindent the expression
3159starting on the current line.
3160Otherwise reindent just the current line."
3161 (interactive
3162 (list current-prefix-arg (use-region-p)))
3163 (if region
0ec8351b 3164 (c-indent-region (region-beginning) (region-end))
c02a1ee9 3165 (c-indent-command arg)))
785eecbb
RS
3166\f
3167;; for progress reporting
3168(defvar c-progress-info nil)
3169
3170(defun c-progress-init (start end context)
a7c7b186
KH
3171 (cond
3172 ;; Be silent
3173 ((not c-progress-interval))
3174 ;; Start the progress update messages. If this Emacs doesn't have
3175 ;; a built-in timer, just be dumb about it.
3176 ((not (fboundp 'current-time))
130c507e 3177 (message "Indenting region... (this may take a while)"))
a7c7b186
KH
3178 ;; If progress has already been initialized, do nothing. otherwise
3179 ;; initialize the counter with a vector of:
3180 ;; [start end lastsec context]
3181 (c-progress-info)
3182 (t (setq c-progress-info (vector start
785eecbb
RS
3183 (save-excursion
3184 (goto-char end)
3185 (point-marker))
3186 (nth 1 (current-time))
3187 context))
130c507e 3188 (message "Indenting region..."))
a7c7b186 3189 ))
785eecbb
RS
3190
3191(defun c-progress-update ()
785eecbb
RS
3192 (if (not (and c-progress-info c-progress-interval))
3193 nil
3194 (let ((now (nth 1 (current-time)))
3195 (start (aref c-progress-info 0))
3196 (end (aref c-progress-info 1))
3197 (lastsecs (aref c-progress-info 2)))
3198 ;; should we update? currently, update happens every 2 seconds,
3199 ;; what's the right value?
3200 (if (< c-progress-interval (- now lastsecs))
3201 (progn
130c507e 3202 (message "Indenting region... (%d%% complete)"
785eecbb
RS
3203 (/ (* 100 (- (point) start)) (- end start)))
3204 (aset c-progress-info 2 now)))
3205 )))
3206
3207(defun c-progress-fini (context)
a7c7b186
KH
3208 (if (not c-progress-interval)
3209 nil
3210 (if (or (eq context (aref c-progress-info 3))
3211 (eq context t))
3212 (progn
3213 (set-marker (aref c-progress-info 1) nil)
3214 (setq c-progress-info nil)
130c507e 3215 (message "Indenting region... done")))))
785eecbb
RS
3216
3217
3218\f
3219;;; This page handles insertion and removal of backslashes for C macros.
3220
a66cd3ee 3221(defun c-backslash-region (from to delete-flag &optional line-mode)
785eecbb
RS
3222 "Insert, align, or delete end-of-line backslashes on the lines in the region.
3223With no argument, inserts backslashes and aligns existing backslashes.
a66cd3ee
MS
3224With an argument, deletes the backslashes. The backslash alignment is
3225done according to the settings in `c-backslash-column',
3226`c-backslash-max-column' and `c-auto-align-backslashes'.
785eecbb
RS
3227
3228This function does not modify blank lines at the start of the region.
a66cd3ee
MS
3229If the region ends at the start of a line and the macro doesn't
3230continue below it, the backslash (if any) at the end of the previous
3231line is deleted.
0ec8351b 3232
785eecbb
RS
3233You can put the region around an entire macro definition and use this
3234command to conveniently insert and align the necessary backslashes."
28c236de 3235 (interactive "*r\nP")
a66cd3ee
MS
3236 (let ((endmark (make-marker))
3237 ;; Keep the backslash trimming functions from changing the
3238 ;; whitespace around point, since in this case it's only the
3239 ;; position of point that tells the indentation of the line.
3240 (point-pos (if (save-excursion
3241 (skip-chars-backward " \t")
3242 (and (bolp) (looking-at "[ \t]*\\\\?$")))
3243 (point-marker)
3244 (point-min)))
3245 column longest-line-col bs-col-after-end)
3246 (save-excursion
3247 (goto-char to)
3248 (if (and (not line-mode) (bobp))
3249 ;; Nothing to do if to is at bob, since we should back up
3250 ;; and there's no line to back up to.
3251 nil
3252 (when (and (not line-mode) (bolp))
3253 ;; Do not back up the to line if line-mode is set, to make
3254 ;; e.g. c-newline-and-indent consistent regardless whether
3255 ;; the (newline) call leaves point at bol or not.
3256 (backward-char)
3257 (setq to (point)))
3258 (if delete-flag
3259 (progn
3260 (set-marker endmark (point))
3261 (goto-char from)
3262 (c-delete-backslashes-forward endmark point-pos))
3263 ;; Set bs-col-after-end to the column of any backslash
3264 ;; following the region, or nil if there is none.
3265 (setq bs-col-after-end
3266 (and (progn (end-of-line)
3267 (eq (char-before) ?\\))
3268 (= (forward-line 1) 0)
3269 (progn (end-of-line)
3270 (eq (char-before) ?\\))
3271 (1- (current-column))))
3272 (when line-mode
3273 ;; Back up the to line if line-mode is set, since the line
3274 ;; after the newly inserted line break should not be
3275 ;; touched in c-newline-and-indent.
3276 (setq to (max from (or (c-safe (c-point 'eopl)) from)))
3277 (unless bs-col-after-end
3278 ;; Set bs-col-after-end to non-nil in any case, since we
3279 ;; do not want to delete the backslash at the last line.
3280 (setq bs-col-after-end t)))
3281 (if (and line-mode
3282 (not c-auto-align-backslashes))
3283 (goto-char from)
3284 ;; Compute the smallest column number past the ends of all
3285 ;; the lines.
3286 (setq longest-line-col 0)
3287 (goto-char to)
3288 (if bs-col-after-end
3289 ;; Include one more line in the max column
3290 ;; calculation, since the to line will be backslashed
3291 ;; too.
3292 (forward-line 1))
3293 (end-of-line)
3294 (while (and (>= (point) from)
3295 (progn
3296 (if (eq (char-before) ?\\)
3297 (forward-char -1))
3298 (skip-chars-backward " \t")
3299 (setq longest-line-col (max longest-line-col
3300 (1+ (current-column))))
3301 (beginning-of-line)
3302 (not (bobp))))
3303 (backward-char))
3304 ;; Try to align with surrounding backslashes.
3305 (goto-char from)
3306 (beginning-of-line)
3307 (if (and (not (bobp))
3308 (progn (backward-char)
3309 (eq (char-before) ?\\)))
3310 (progn
3311 (setq column (1- (current-column)))
3312 (if (numberp bs-col-after-end)
3313 ;; Both a preceding and a following backslash.
3314 ;; Choose the greatest of them.
3315 (setq column (max column bs-col-after-end)))
3316 (goto-char from))
3317 ;; No preceding backslash. Try to align with one
3318 ;; following the region. Disregard the backslash at the
3319 ;; to line since it's likely to be bogus (e.g. when
3320 ;; called from c-newline-and-indent).
3321 (if (numberp bs-col-after-end)
3322 (setq column bs-col-after-end))
3323 ;; Don't modify blank lines at start of region.
3324 (goto-char from)
3325 (while (and (< (point) to) (bolp) (eolp))
3326 (forward-line 1)))
3327 (if (and column (< column longest-line-col))
3328 ;; Don't try to align with surrounding backslashes if
3329 ;; any line is too long.
3330 (setq column nil))
3331 (unless column
3332 ;; Impose minimum limit and tab width alignment only if
3333 ;; we can't align with surrounding backslashes.
3334 (if (> (% longest-line-col tab-width) 0)
3335 (setq longest-line-col
3336 (* (/ (+ longest-line-col tab-width -1)
3337 tab-width)
3338 tab-width)))
3339 (setq column (max c-backslash-column
3340 longest-line-col)))
3341 ;; Always impose maximum limit.
3342 (setq column (min column c-backslash-max-column)))
3343 (if bs-col-after-end
3344 ;; Add backslashes on all lines if the macro continues
3345 ;; after the to line.
3346 (progn
3347 (set-marker endmark to)
3348 (c-append-backslashes-forward endmark column point-pos))
3349 ;; Add backslashes on all lines except the last, and
3350 ;; remove any on the last line.
3351 (if (save-excursion
3352 (goto-char to)
3353 (beginning-of-line)
3354 (if (not (bobp))
3355 (set-marker endmark (1- (point)))))
3356 (progn
3357 (c-append-backslashes-forward endmark column point-pos)
3358 ;; The function above leaves point on the line
3359 ;; following endmark.
3360 (set-marker endmark (point)))
3361 (set-marker endmark to))
3362 (c-delete-backslashes-forward endmark point-pos)))))
3363 (set-marker endmark nil)
3364 (if (markerp point-pos)
3365 (set-marker point-pos nil))))
3366
3367(defun c-append-backslashes-forward (to-mark column point-pos)
3368 (let ((state (parse-partial-sexp (c-point 'bol) (point))))
3369 (if column
3370 (while
3371 (and
3372 (<= (point) to-mark)
3373
3374 (let ((start (point)) (inserted nil) end col)
3375 (end-of-line)
3376 (unless (eq (char-before) ?\\)
3377 (insert ?\\)
3378 (setq inserted t))
3379 (setq state (parse-partial-sexp
3380 start (point) nil nil state))
3381 (backward-char)
3382 (setq col (current-column))
3383
3384 ;; Avoid unnecessary changes of the buffer.
3385 (cond ((and (not inserted) (nth 3 state))
3386 ;; Don't realign backslashes in string literals
3387 ;; since that would change them.
3388 )
3389
3390 ((< col column)
3391 (delete-region
3392 (point)
3393 (progn
3394 (skip-chars-backward
3395 " \t" (if (>= (point) point-pos) point-pos))
3396 (point)))
3397 (indent-to column))
3398
3399 ((and (= col column)
3400 (memq (char-before) '(?\ ?\t))))
3401
3402 ((progn
3403 (setq end (point))
3404 (or (/= (skip-chars-backward
3405 " \t" (if (>= (point) point-pos) point-pos))
3406 -1)
3407 (/= (char-after) ?\ )))
3408 (delete-region (point) end)
3409 (indent-to column 1)))
3410
3efc2cd7
MS
3411 (zerop (forward-line 1)))
3412 (bolp))) ; forward-line has funny behavior at eob.
a66cd3ee
MS
3413
3414 ;; Make sure there are backslashes with at least one space in
3415 ;; front of them.
3416 (while
3417 (and
3418 (<= (point) to-mark)
3419
3420 (let ((start (point)))
3421 (end-of-line)
3422 (setq state (parse-partial-sexp
3423 start (point) nil nil state))
3424
3425 (if (eq (char-before) ?\\)
3426 (unless (nth 3 state)
3427 (backward-char)
3428 (unless (and (memq (char-before) '(?\ ?\t))
3429 (/= (point) point-pos))
3430 (insert ?\ )))
3431
3432 (if (and (memq (char-before) '(?\ ?\t))
3433 (/= (point) point-pos))
3434 (insert ?\\)
3435 (insert ?\ ?\\)))
3436
3efc2cd7
MS
3437 (zerop (forward-line 1)))
3438 (bolp)))))) ; forward-line has funny behavior at eob.
a66cd3ee
MS
3439
3440(defun c-delete-backslashes-forward (to-mark point-pos)
3441 (while
3442 (and (<= (point) to-mark)
3443 (progn
3444 (end-of-line)
3445 (if (eq (char-before) ?\\)
3446 (delete-region
3447 (point)
3448 (progn (backward-char)
3449 (skip-chars-backward " \t" (if (>= (point) point-pos)
3450 point-pos))
3451 (point))))
3efc2cd7
MS
3452 (zerop (forward-line 1)))
3453 (bolp)))) ; forward-line has funny behavior at eob.
785eecbb 3454
51f606de 3455
785eecbb 3456\f
51f606de
GM
3457;;; Line breaking and paragraph filling.
3458
130c507e
GM
3459(defvar c-auto-fill-prefix t)
3460(defvar c-lit-limits nil)
3461(defvar c-lit-type nil)
3462
51f606de
GM
3463;; The filling code is based on a simple theory; leave the intricacies
3464;; of the text handling to the currently active mode for that
3465;; (e.g. adaptive-fill-mode or filladapt-mode) and do as little as
3466;; possible to make them work correctly wrt the comment and string
3467;; separators, one-line paragraphs etc. Unfortunately, when it comes
3468;; to it, there's quite a lot of special cases to handle which makes
3469;; the code anything but simple. The intention is that it will work
3470;; with any well-written text filling package that preserves a fill
3471;; prefix.
3472;;
3473;; We temporarily mask comment starters and enders as necessary for
3474;; the filling code to do its job on a seemingly normal text block.
3475;; We do _not_ mask the fill prefix, so it's up to the filling code to
3476;; preserve it correctly (especially important when filling C++ style
3477;; line comments). By default, we set up and use adaptive-fill-mode,
3478;; which is standard in all supported Emacs flavors.
3479
3480(defun c-guess-fill-prefix (lit-limits lit-type)
3481 ;; Determine the appropriate comment fill prefix for a block or line
3482 ;; comment. Return a cons of the prefix string and the column where
3483 ;; it ends. If fill-prefix is set, it'll override. Note that this
3484 ;; function also uses the value of point in some heuristics.
0386b551
AM
3485 ;;
3486 ;; This function might do hidden buffer changes.
d9e94c22 3487
51f606de
GM
3488 (let* ((here (point))
3489 (prefix-regexp (concat "[ \t]*\\("
130c507e 3490 c-current-comment-prefix
51f606de
GM
3491 "\\)[ \t]*"))
3492 (comment-start-regexp (if (eq lit-type 'c++)
3493 prefix-regexp
3494 comment-start-skip))
130c507e 3495 prefix-line comment-prefix res comment-text-end)
d9e94c22 3496
51f606de
GM
3497 (cond
3498 (fill-prefix
3499 (setq res (cons fill-prefix
3500 ;; Ugly way of getting the column after the fill
3501 ;; prefix; it'd be nice with a current-column
3502 ;; that works on strings..
d9e94c22 3503 (let ((start (point)))
51f606de
GM
3504 (unwind-protect
3505 (progn
a66cd3ee 3506 (insert-and-inherit "\n" fill-prefix)
51f606de 3507 (current-column))
d9e94c22
MS
3508 (delete-region start (point)))))))
3509
51f606de
GM
3510 ((eq lit-type 'c++)
3511 (save-excursion
3512 ;; Set fallback for comment-prefix if none is found.
130c507e
GM
3513 (setq comment-prefix "// "
3514 comment-text-end (cdr lit-limits))
d9e94c22 3515
51f606de
GM
3516 (beginning-of-line)
3517 (if (> (point) (car lit-limits))
3518 ;; The current line is not the comment starter, so the
3519 ;; comment has more than one line, and it can therefore be
3520 ;; used to find the comment fill prefix.
3521 (setq prefix-line (point))
d9e94c22 3522
51f606de
GM
3523 (goto-char (car lit-limits))
3524 (if (and (= (forward-line 1) 0)
3525 (< (point) (cdr lit-limits)))
3526 ;; The line after the comment starter is inside the
3527 ;; comment, so we can use it.
3528 (setq prefix-line (point))
d9e94c22 3529
51f606de
GM
3530 ;; The comment is only one line. Take the comment prefix
3531 ;; from it and keep the indentation.
3532 (goto-char (car lit-limits))
3533 (if (looking-at prefix-regexp)
3534 (goto-char (match-end 0))
3535 (forward-char 2)
3536 (skip-chars-forward " \t"))
d9e94c22 3537
a66cd3ee
MS
3538 (let (str col)
3539 (if (eq (c-point 'boi) (car lit-limits))
3540 ;; There is only whitespace before the comment
3541 ;; starter; take the prefix straight from this line.
3542 (setq str (buffer-substring-no-properties
51f606de 3543 (c-point 'bol) (point))
a66cd3ee 3544 col (current-column))
d9e94c22 3545
a66cd3ee
MS
3546 ;; There is code before the comment starter, so we
3547 ;; have to temporarily insert and indent a new line to
3548 ;; get the right space/tab mix in the indentation.
d9e94c22 3549 (let ((prefix-len (- (point) (car lit-limits)))
a66cd3ee
MS
3550 tmp)
3551 (unwind-protect
3552 (progn
3553 (goto-char (car lit-limits))
3554 (indent-to (prog1 (current-column)
3555 (insert ?\n)))
3556 (setq tmp (point))
3557 (forward-char prefix-len)
3558 (setq str (buffer-substring-no-properties
51f606de 3559 (c-point 'bol) (point))
a66cd3ee 3560 col (current-column)))
d9e94c22
MS
3561 (delete-region (car lit-limits) tmp))))
3562
a66cd3ee
MS
3563 (setq res
3564 (if (or (string-match "\\s \\'" str) (not (eolp)))
3565 (cons str col)
3566 ;; The prefix ends the line with no whitespace
3567 ;; after it. Default to a single space.
3568 (cons (concat str " ") (1+ col))))
3569 )))))
d9e94c22 3570
51f606de 3571 (t
a66cd3ee
MS
3572 (setq comment-text-end
3573 (save-excursion
3574 (goto-char (- (cdr lit-limits) 2))
3575 (if (looking-at "\\*/") (point) (cdr lit-limits))))
d9e94c22 3576
51f606de
GM
3577 (save-excursion
3578 (beginning-of-line)
3579 (if (and (> (point) (car lit-limits))
3580 (not (and (looking-at "[ \t]*\\*/")
3581 (eq (cdr lit-limits) (match-end 0)))))
3582 ;; The current line is not the comment starter and
3583 ;; contains more than just the ender, so it's good enough
3584 ;; to be used for the comment fill prefix.
3585 (setq prefix-line (point))
3586 (goto-char (car lit-limits))
d9e94c22
MS
3587
3588 (cond ((or (/= (forward-line 1) 0)
3589 (>= (point) (cdr lit-limits))
3590 (and (looking-at "[ \t]*\\*/")
3591 (eq (cdr lit-limits) (match-end 0)))
3592 (and (looking-at prefix-regexp)
3593 (<= (1- (cdr lit-limits)) (match-end 0))))
3594 ;; The comment is either one line or the next line contains
3595 ;; just the comment ender. In this case we have no
3596 ;; information about a suitable comment prefix, so we resort
3597 ;; to c-block-comment-prefix.
3598 (setq comment-prefix (or c-block-comment-prefix "")))
3599
3600 ((< here (point))
3601 ;; The point was on the comment opener line, so we might want
3602 ;; to treat this as a not yet closed comment.
3603
3604 (if (and (match-beginning 1)
3605 (/= (match-beginning 1) (match-end 1)))
3606 ;; Above `prefix-regexp' matched a nonempty prefix on the
3607 ;; second line, so let's use it. Normally it should do
3608 ;; to set `prefix-line' and let the code below pick up
3609 ;; the whole prefix, but if there's no text after the
3610 ;; match then it will probably fall back to no prefix at
3611 ;; all if the comment isn't closed yet, so in that case
3612 ;; it's better to force use of the prefix matched now.
3613 (if (= (match-end 0) (c-point 'eol))
3614 (setq comment-prefix (match-string 1))
3615 (setq prefix-line (point)))
3616
3617 ;; There's no nonempty prefix on the line after the
3618 ;; comment opener. If the line is empty, or if the
d858963e 3619 ;; text on it has less or equal indentation than the
d9e94c22
MS
3620 ;; comment starter we assume it's an unclosed
3621 ;; comment starter, i.e. that
3622 ;; `c-block-comment-prefix' should be used.
3623 ;; Otherwise we assume it's a closed comment where
3624 ;; the prefix really is the empty string.
3625 ;; E.g. this is an unclosed comment:
3626 ;;
3627 ;; /*
3628 ;; foo
3629 ;;
3630 ;; But this is not:
3631 ;;
3632 ;; /*
3633 ;; foo
3634 ;; */
3635 ;;
3636 ;; (Looking for the presence of the comment closer
3637 ;; rarely works since it's probably the closer of
3638 ;; some comment further down when the comment
3639 ;; really is unclosed.)
3640 (if (<= (save-excursion (back-to-indentation)
3641 (current-column))
3642 (save-excursion (goto-char (car lit-limits))
3643 (current-column)))
3644 (setq comment-prefix (or c-block-comment-prefix ""))
3645 (setq prefix-line (point)))))
3646
3647 (t
3648 ;; Otherwise the line after the comment starter is good
3649 ;; enough to find the prefix in.
3650 (setq prefix-line (point))))
3651
3652 (when comment-prefix
3653 ;; Haven't got the comment prefix on any real line that we
3654 ;; can take it from, so we have to temporarily insert
3655 ;; `comment-prefix' on a line and indent it to find the
3656 ;; correct column and the correct mix of tabs and spaces.
3657 (setq res
3658 (let (tmp-pre tmp-post)
3659 (unwind-protect
3660 (progn
3661
3662 (goto-char (car lit-limits))
3663 (if (looking-at comment-start-regexp)
3664 (goto-char (min (match-end 0)
3665 comment-text-end))
3666 (forward-char 2)
3667 (skip-chars-forward " \t"))
3668
3669 (when (eq (char-syntax (char-before)) ?\ )
3670 ;; If there's ws on the current line, we'll use it
3671 ;; instead of what's ending comment-prefix.
3672 (setq comment-prefix
3673 (concat (substring comment-prefix
3674 0 (string-match
3675 "\\s *\\'"
3676 comment-prefix))
3677 (buffer-substring-no-properties
3678 (save-excursion
3679 (skip-chars-backward " \t")
3680 (point))
3681 (point)))))
3682
3683 (setq tmp-pre (point-marker))
3684
3685 ;; We insert an extra non-whitespace character
3686 ;; before the line break and after comment-prefix in
3687 ;; case it's "" or ends with whitespace.
3688 (insert-and-inherit "x\n" comment-prefix "x")
3689 (setq tmp-post (point-marker))
3690
3691 (indent-according-to-mode)
3692
3693 (goto-char (1- tmp-post))
3694 (cons (buffer-substring-no-properties
3695 (c-point 'bol) (point))
3696 (current-column)))
3697
3698 (when tmp-post
3699 (delete-region tmp-pre tmp-post)
3700 (set-marker tmp-pre nil)
3701 (set-marker tmp-post nil))))))))))
3702
3703 (or res ; Found a good prefix above.
3704
51f606de
GM
3705 (save-excursion
3706 ;; prefix-line is the bol of a line on which we should try
3707 ;; to find the prefix.
3708 (let* (fb-string fb-endpos ; Contains any fallback prefix found.
3709 (test-line
3710 (lambda ()
3711 (when (and (looking-at prefix-regexp)
130c507e
GM
3712 (<= (match-end 0) comment-text-end))
3713 (unless (eq (match-end 0) (c-point 'eol))
3714 ;; The match is fine if there's text after it.
3715 (throw 'found (cons (buffer-substring-no-properties
3716 (match-beginning 0) (match-end 0))
3717 (progn (goto-char (match-end 0))
3718 (current-column)))))
51f606de 3719 (unless fb-string
130c507e
GM
3720 ;; This match is better than nothing, so let's
3721 ;; remember it in case nothing better is found
3722 ;; on another line.
51f606de
GM
3723 (setq fb-string (buffer-substring-no-properties
3724 (match-beginning 0) (match-end 0))
3725 fb-endpos (match-end 0)))
51f606de 3726 t))))
d9e94c22 3727
130c507e 3728 (or (catch 'found
51f606de
GM
3729 ;; Search for a line which has text after the prefix
3730 ;; so that we get the proper amount of whitespace
3731 ;; after it. We start with the current line, then
3732 ;; search backwards, then forwards.
d9e94c22 3733
51f606de
GM
3734 (goto-char prefix-line)
3735 (when (and (funcall test-line)
130c507e
GM
3736 (or (/= (match-end 1) (match-end 0))
3737 ;; The whitespace is sucked up by the
3738 ;; first [ \t]* glob if the prefix is empty.
3739 (and (= (match-beginning 1) (match-end 1))
3740 (/= (match-beginning 0) (match-end 0)))))
51f606de
GM
3741 ;; If the current line doesn't have text but do
3742 ;; have whitespace after the prefix, we'll use it.
130c507e
GM
3743 (throw 'found (cons fb-string
3744 (progn (goto-char fb-endpos)
3745 (current-column)))))
d9e94c22 3746
130c507e
GM
3747 (if (eq lit-type 'c++)
3748 ;; For line comments we can search up to and
3749 ;; including the first line.
3750 (while (and (zerop (forward-line -1))
3751 (>= (point) (car lit-limits)))
3752 (funcall test-line))
3753 ;; For block comments we must stop before the
3754 ;; block starter.
3755 (while (and (zerop (forward-line -1))
3756 (> (point) (car lit-limits)))
3757 (funcall test-line)))
d9e94c22 3758
51f606de
GM
3759 (goto-char prefix-line)
3760 (while (and (zerop (forward-line 1))
3761 (< (point) (cdr lit-limits)))
3762 (funcall test-line))
d9e94c22 3763
130c507e 3764 (goto-char prefix-line)
51f606de 3765 nil)
d9e94c22 3766
130c507e 3767 (when fb-string
51f606de
GM
3768 ;; A good line wasn't found, but at least we have a
3769 ;; fallback that matches the comment prefix regexp.
a66cd3ee
MS
3770 (cond ((or (string-match "\\s \\'" fb-string)
3771 (progn
3772 (goto-char fb-endpos)
3773 (not (eolp))))
3774 ;; There are ws or text after the prefix, so
3775 ;; let's use it.
3776 (cons fb-string (current-column)))
d9e94c22 3777
51f606de
GM
3778 ((progn
3779 ;; Check if there's any whitespace padding
3780 ;; on the comment start line that we can
3781 ;; use after the prefix.
3782 (goto-char (car lit-limits))
3783 (if (looking-at comment-start-regexp)
3784 (goto-char (match-end 0))
3785 (forward-char 2)
3786 (skip-chars-forward " \t"))
a66cd3ee
MS
3787 (or (not (eolp))
3788 (eq (char-syntax (char-before)) ?\ )))
d9e94c22 3789
51f606de
GM
3790 (setq fb-string (buffer-substring-no-properties
3791 (save-excursion
3792 (skip-chars-backward " \t")
3793 (point))
3794 (point)))
3795 (goto-char fb-endpos)
3796 (skip-chars-backward " \t")
d9e94c22
MS
3797
3798 (let ((tmp (point)))
51f606de
GM
3799 ;; Got to mess in the buffer once again to
3800 ;; ensure the column gets correct. :P
3801 (unwind-protect
3802 (progn
a66cd3ee 3803 (insert-and-inherit fb-string)
51f606de
GM
3804 (cons (buffer-substring-no-properties
3805 (c-point 'bol)
3806 (point))
3807 (current-column)))
d9e94c22
MS
3808 (delete-region tmp (point)))))
3809
51f606de
GM
3810 (t
3811 ;; Last resort: Just add a single space after
3812 ;; the prefix.
3813 (cons (concat fb-string " ")
3814 (progn (goto-char fb-endpos)
130c507e 3815 (1+ (current-column)))))))
d9e94c22 3816
51f606de
GM
3817 ;; The line doesn't match the comment prefix regexp.
3818 (if comment-prefix
3819 ;; We have a fallback for line comments that we must use.
3820 (cons (concat (buffer-substring-no-properties
3821 prefix-line (c-point 'boi))
3822 comment-prefix)
3823 (progn (back-to-indentation)
3824 (+ (current-column) (length comment-prefix))))
d9e94c22 3825
51f606de
GM
3826 ;; Assume we are dealing with a "free text" block
3827 ;; comment where the lines doesn't have any comment
3828 ;; prefix at all and we should just fill it as
3829 ;; normal text.
130c507e 3830 '("" . 0))))))
51f606de
GM
3831 ))
3832
d9e94c22
MS
3833(defun c-mask-paragraph (fill-paragraph apply-outside-literal fun &rest args)
3834 ;; Calls FUN with ARGS ar arguments while the current paragraph is
3835 ;; masked to allow adaptive filling to work correctly. That
3836 ;; includes narrowing the buffer and, if point is inside a comment,
3837 ;; masking the comment starter and ender appropriately.
3838 ;;
3839 ;; FILL-PARAGRAPH is non-nil if called for whole paragraph filling.
3840 ;; The position of point is then less significant when doing masking
3841 ;; and narrowing.
3842 ;;
3843 ;; If APPLY-OUTSIDE-LITERAL is nil then the function will be called
3844 ;; only if the point turns out to be inside a comment or a string.
07cc1196 3845 ;;
0386b551 3846 ;; Note that this function does not do any hidden buffer changes.
d9e94c22 3847
a66cd3ee 3848 (let (fill
e6a24f43 3849 ;; beg and end limit the region to narrow. end is a marker.
51f606de 3850 beg end
130c507e 3851 ;; tmp-pre and tmp-post mark strings that are temporarily
51f606de
GM
3852 ;; inserted at the start and end of the region. tmp-pre is a
3853 ;; cons of the positions of the prepended string. tmp-post is
3854 ;; a marker pointing to the single character of the appended
3855 ;; string.
3856 tmp-pre tmp-post
130c507e
GM
3857 ;; If hang-ender-stuck isn't nil, the comment ender is
3858 ;; hanging. In that case it's set to the number of spaces
3859 ;; that should be between the text and the ender.
3860 hang-ender-stuck
0386b551
AM
3861 ;; auto-fill-spaces is the exact sequence of whitespace between a
3862 ;; comment's last word and the comment ender, temporarily replaced
17264191 3863 ;; with 'x's before calling FUN when FILL-PARAGRAPH is nil.
0386b551 3864 auto-fill-spaces
a66cd3ee
MS
3865 (here (point))
3866 (c-lit-limits c-lit-limits)
3867 (c-lit-type c-lit-type))
d9e94c22 3868
51f606de
GM
3869 ;; Restore point on undo. It's necessary since we do a lot of
3870 ;; hidden inserts and deletes below that should be as transparent
3871 ;; as possible.
51c9af45 3872 (if (and buffer-undo-list (not (eq buffer-undo-list t)))
51f606de 3873 (setq buffer-undo-list (cons (point) buffer-undo-list)))
d9e94c22 3874
51c9af45
AM
3875 ;; Determine the limits and type of the containing literal (if any):
3876 ;; C-LIT-LIMITS, C-LIT-TYPE; and the limits of the current paragraph:
3877 ;; BEG and END.
0386b551
AM
3878 (c-save-buffer-state ()
3879 (save-restriction
3880 ;; Widen to catch comment limits correctly.
3881 (widen)
3882 (unless c-lit-limits
3883 (setq c-lit-limits (c-literal-limits nil fill-paragraph)))
3884 (setq c-lit-limits (c-collect-line-comments c-lit-limits))
3885 (unless c-lit-type
3886 (setq c-lit-type (c-literal-type c-lit-limits))))
d9e94c22 3887
0386b551
AM
3888 (save-excursion
3889 (unless (c-safe (backward-char)
3890 (forward-paragraph)
3891 (>= (point) here))
3892 (goto-char here)
3893 (forward-paragraph))
3894 (setq end (point-marker)))
3895 (save-excursion
3896 (unless (c-safe (forward-char)
3897 (backward-paragraph)
3898 (<= (point) here))
3899 (goto-char here)
3900 (backward-paragraph))
3901 (setq beg (point))))
d9e94c22 3902
130c507e
GM
3903 (unwind-protect
3904 (progn
51c9af45
AM
3905 ;; For each of the possible types of text (string, C comment ...)
3906 ;; determine BEG and END, the region we will narrow to. If we're in
3907 ;; a literal, constrain BEG and END to the limits of this literal.
3908 ;;
3909 ;; For some of these text types, particularly a block comment, we
3910 ;; may need to massage whitespace near literal delimiters, so that
3911 ;; these don't get filled inappropriately.
130c507e 3912 (cond
d9e94c22 3913
a66cd3ee 3914 ((eq c-lit-type 'c++) ; Line comment.
130c507e 3915 (save-excursion
a66cd3ee 3916 ;; Limit to the comment or paragraph end, whichever
130c507e 3917 ;; comes first.
a66cd3ee 3918 (set-marker end (min end (cdr c-lit-limits)))
d9e94c22 3919
a66cd3ee
MS
3920 (when (<= beg (car c-lit-limits))
3921 ;; The region includes the comment starter, so we must
3922 ;; check it.
3923 (goto-char (car c-lit-limits))
130c507e 3924 (back-to-indentation)
a66cd3ee
MS
3925 (if (eq (point) (car c-lit-limits))
3926 ;; Include the first line in the region.
130c507e
GM
3927 (setq beg (c-point 'bol))
3928 ;; The first line contains code before the
3929 ;; comment. We must fake a line that doesn't.
d9e94c22
MS
3930 (setq tmp-pre t))))
3931
3932 (setq apply-outside-literal t))
3933
a66cd3ee 3934 ((eq c-lit-type 'c) ; Block comment.
fd85cfb7
AM
3935 (when
3936 (or (> end (cdr c-lit-limits))
3937 (and (= end (cdr c-lit-limits))
3938 (eq (char-before end) ?/)
3939 (eq (char-before (1- end)) ?*)
3940 ;; disallow "/*/"
3941 (> (- (cdr c-lit-limits) (car c-lit-limits)) 3)))
e6a24f43
AM
3942 ;; There is a comment ender, and the region includes it. If
3943 ;; it's on its own line, it stays on its own line. If it's got
3944 ;; company on the line, it keeps (at least one word of) it.
3945 ;; "=====*/" counts as a comment ender here, but "===== */"
3946 ;; doesn't and "foo*/" doesn't.
51c9af45
AM
3947 (unless
3948 (save-excursion
3949 (goto-char (cdr c-lit-limits))
3950 (beginning-of-line)
dc56b2ba
MR
3951 ;; The following conjunct was added to avoid an
3952 ;; "Invalid search bound (wrong side of point)"
3953 ;; error in the subsequent re-search. Maybe
3954 ;; another fix would be needed (2007-12-08).
3955 (and (> (- (cdr c-lit-limits) 2) (point))
3956 (search-forward-regexp
51c9af45
AM
3957 (concat "\\=[ \t]*\\(" c-current-comment-prefix "\\)")
3958 (- (cdr c-lit-limits) 2) t)
3959 (not (search-forward-regexp
3960 "\\(\\s \\|\\sw\\)"
3961 (- (cdr c-lit-limits) 2) 'limit))
3962 ;; The comment ender IS on its own line. Exclude
3963 ;; this line from the filling.
3964 (set-marker end (c-point 'bol))))
3965
3966 ;; The comment ender is hanging. Replace all space between it
3967 ;; and the last word either by one or two 'x's (when
0386b551
AM
3968 ;; FILL-PARAGRAPH is non-nil), or a row of x's the same width
3969 ;; as the whitespace (when auto filling), and include it in
3970 ;; the region. We'll change them back to whitespace
3971 ;; afterwards. The effect of this is to glue the comment
3972 ;; ender to the last word in the comment during filling.
3973 (let* ((ender-start (save-excursion
3974 (goto-char (cdr c-lit-limits))
3975 (skip-syntax-backward "^w ")
3976 (point)))
3977 (ender-column (save-excursion
3978 (goto-char ender-start)
3979 (current-column)))
3980 (point-rel (- ender-start here))
3981 spaces)
3982
3983 (save-excursion
51c9af45 3984 ;; Insert a CR after the "*/", adjust END
0386b551
AM
3985 (goto-char (cdr c-lit-limits))
3986 (setq tmp-post (point-marker))
3987 (insert ?\n)
3988 (set-marker end (point))
51c9af45 3989
0386b551
AM
3990 (forward-line -1) ; last line of the comment
3991 (if (and (looking-at (concat "[ \t]*\\(\\("
3992 c-current-comment-prefix
3993 "\\)[ \t]*\\)"))
3994 (eq ender-start (match-end 0)))
51c9af45
AM
3995 ;; The comment ender is prefixed by nothing but a
3996 ;; comment line prefix. IS THIS POSSIBLE? (ACM,
3997 ;; 2006/4/28). Remove it along with surrounding ws.
0386b551
AM
3998 (setq spaces (- (match-end 1) (match-end 2)))
3999 (goto-char ender-start))
4000 (skip-chars-backward " \t\r\n") ; Surely this can be
4001 ; " \t"? "*/" is NOT alone on the line (ACM, 2005/8/18)
4002
51c9af45 4003 ;; What's being tested here? 2006/4/20. FIXME!!!
0386b551
AM
4004 (if (/= (point) ender-start)
4005 (progn
4006 (if (<= here (point))
4007 ;; Don't adjust point below if it's
4008 ;; before the string we replace.
4009 (setq point-rel -1))
4010 ;; Keep one or two spaces between the
4011 ;; text and the ender, depending on how
4012 ;; many there are now.
4013 (unless spaces
4014 (setq spaces (- ender-column (current-column))))
4015 (setq auto-fill-spaces (c-delete-and-extract-region
4016 (point) ender-start))
4017 ;; paragraph filling condenses multiple spaces to
4018 ;; single or double spaces. auto-fill doesn't.
4019 (if fill-paragraph
d9e94c22
MS
4020 (setq spaces
4021 (max
4022 (min spaces
4023 (if sentence-end-double-space 2 1))
0386b551
AM
4024 1)))
4025 ;; Insert the filler first to keep marks right.
4026 (insert-char ?x spaces t)
4027 (setq hang-ender-stuck spaces)
4028 (setq point-rel
4029 (and (>= point-rel 0)
4030 (- (point) (min point-rel spaces)))))
4031 (setq point-rel nil)))
4032
4033 (if point-rel
4034 ;; Point was in the middle of the string we
4035 ;; replaced above, so put it back in the same
4036 ;; relative position, counting from the end.
4037 (goto-char point-rel)))
4038 ))
d9e94c22 4039
a66cd3ee
MS
4040 (when (<= beg (car c-lit-limits))
4041 ;; The region includes the comment starter.
51f606de 4042 (save-excursion
a66cd3ee 4043 (goto-char (car c-lit-limits))
07cc1196
MS
4044 (if (looking-at (concat "\\(" comment-start-skip "\\)$"))
4045 ;; Begin with the next line.
4046 (setq beg (c-point 'bonl))
4047 ;; Fake the fill prefix in the first line.
d9e94c22
MS
4048 (setq tmp-pre t))))
4049
4050 (setq apply-outside-literal t))
4051
a66cd3ee 4052 ((eq c-lit-type 'string) ; String.
130c507e 4053 (save-excursion
a66cd3ee
MS
4054 (when (>= end (cdr c-lit-limits))
4055 (goto-char (1- (cdr c-lit-limits)))
130c507e
GM
4056 (setq tmp-post (point-marker))
4057 (insert ?\n)
4058 (set-marker end (point)))
a66cd3ee
MS
4059 (when (<= beg (car c-lit-limits))
4060 (goto-char (1+ (car c-lit-limits)))
130c507e
GM
4061 (setq beg (if (looking-at "\\\\$")
4062 ;; Leave the start line if it's
4063 ;; nothing but an escaped newline.
4064 (1+ (match-end 0))
d9e94c22
MS
4065 (point)))))
4066 (setq apply-outside-literal t))
4067
4068 ((eq c-lit-type 'pound) ; Macro
4069 ;; Narrow to the macro limits if they are nearer than the
4070 ;; paragraph limits. Don't know if this is necessary but
4071 ;; do it for completeness sake (doing auto filling at all
4072 ;; inside macros is bogus to begin with since the line
4073 ;; continuation backslashes aren't handled).
4074 (save-excursion
0386b551
AM
4075 (c-save-buffer-state ()
4076 (c-beginning-of-macro)
4077 (beginning-of-line)
4078 (if (> (point) beg)
4079 (setq beg (point)))
4080 (c-end-of-macro)
4081 (forward-line)
4082 (if (< (point) end)
4083 (set-marker end (point))))))
d9e94c22
MS
4084
4085 (t ; Other code.
4086 ;; Try to avoid comments and macros in the paragraph to
4087 ;; avoid that the adaptive fill mode gets the prefix from
4088 ;; them.
4089 (c-save-buffer-state nil
4090 (save-excursion
4091 (goto-char beg)
4092 (c-forward-syntactic-ws end)
4093 (beginning-of-line)
4094 (setq beg (point))
4095 (goto-char end)
4096 (c-backward-syntactic-ws beg)
4097 (forward-line)
4098 (set-marker end (point))))))
4099
130c507e
GM
4100 (when tmp-pre
4101 ;; Temporarily insert the fill prefix after the comment
4102 ;; starter so that the first line looks like any other
4103 ;; comment line in the narrowed region.
d9e94c22
MS
4104 (setq fill (c-save-buffer-state nil
4105 (c-guess-fill-prefix c-lit-limits c-lit-type)))
130c507e
GM
4106 (unless (string-match (concat "\\`[ \t]*\\("
4107 c-current-comment-prefix
4108 "\\)[ \t]*\\'")
4109 (car fill))
4110 ;; Oops, the prefix doesn't match the comment prefix
4111 ;; regexp. This could produce very confusing
4112 ;; results with adaptive fill packages together with
4113 ;; the insert prefix magic below, since the prefix
4114 ;; often doesn't appear at all. So let's warn about
4115 ;; it.
4116 (message "\
4117Warning: Regexp from `c-comment-prefix-regexp' doesn't match the comment prefix %S"
4118 (car fill)))
4119 ;; Find the right spot on the line, break it, insert
4120 ;; the fill prefix and make sure we're back in the
4121 ;; same column by temporarily prefixing the first word
4122 ;; with a number of 'x'.
4123 (save-excursion
a66cd3ee
MS
4124 (goto-char (car c-lit-limits))
4125 (if (looking-at (if (eq c-lit-type 'c++)
fdea67e7 4126 c-current-comment-prefix
130c507e
GM
4127 comment-start-skip))
4128 (goto-char (match-end 0))
4129 (forward-char 2)
4130 (skip-chars-forward " \t"))
467690bb
MS
4131 (while (and (< (current-column) (cdr fill))
4132 (not (eolp)))
4133 (forward-char 1))
130c507e
GM
4134 (let ((col (current-column)))
4135 (setq beg (1+ (point))
4136 tmp-pre (list (point)))
4137 (unwind-protect
4138 (progn
a66cd3ee
MS
4139 (insert-and-inherit "\n" (car fill))
4140 (insert-char ?x (- col (current-column)) t))
130c507e 4141 (setcdr tmp-pre (point))))))
d9e94c22
MS
4142
4143 (when apply-outside-literal
4144 ;; `apply-outside-literal' is always set to t here if
4145 ;; we're inside a literal.
4146
4147 (let ((fill-prefix
4148 (or fill-prefix
4149 ;; Kludge: If the function that adapts the fill prefix
4150 ;; doesn't produce the required comment starter for
4151 ;; line comments, then force it by setting fill-prefix.
4152 (when (and (eq c-lit-type 'c++)
4153 ;; Kludge the kludge: filladapt-mode doesn't
4154 ;; have this problem, but it currently
4155 ;; doesn't override fill-context-prefix
4156 ;; (version 2.12).
4157 (not (and (boundp 'filladapt-mode)
4158 filladapt-mode))
4159 (not (string-match
4160 "\\`[ \t]*//"
4161 (or (fill-context-prefix beg end)
4162 ""))))
4163 (c-save-buffer-state nil
a66cd3ee 4164 (car (or fill (c-guess-fill-prefix
d9e94c22
MS
4165 c-lit-limits c-lit-type)))))))
4166
4167 ;; Save the relative position of point if it's outside the
4168 ;; region we're going to narrow. Want to restore it in that
4169 ;; case, but otherwise it should be moved according to the
4170 ;; called function.
4171 (point-rel (cond ((< (point) beg) (- (point) beg))
4172 ((> (point) end) (- (point) end)))))
4173
4174 ;; Preparations finally done! Now we can call the
4175 ;; actual function.
4176 (prog1
4177 (save-restriction
4178 (narrow-to-region beg end)
4179 (apply fun args))
4180 (if point-rel
4181 ;; Restore point if it was outside the region.
4182 (if (< point-rel 0)
4183 (goto-char (+ beg point-rel))
4184 (goto-char (+ end point-rel))))))))
4185
130c507e
GM
4186 (when (consp tmp-pre)
4187 (delete-region (car tmp-pre) (cdr tmp-pre)))
d9e94c22 4188
130c507e
GM
4189 (when tmp-post
4190 (save-excursion
4191 (goto-char tmp-post)
4192 (delete-char 1))
4193 (when hang-ender-stuck
4194 ;; Preserve point even if it's in the middle of the string
4195 ;; we replace; save-excursion doesn't work in that case.
4196 (setq here (point))
4197 (goto-char tmp-post)
4198 (skip-syntax-backward "^w ")
4199 (forward-char (- hang-ender-stuck))
0386b551
AM
4200 (if (or fill-paragraph (not auto-fill-spaces))
4201 (insert-char ?\ hang-ender-stuck t)
4202 (insert auto-fill-spaces)
4203 (setq here (- here (- hang-ender-stuck (length auto-fill-spaces)))))
130c507e
GM
4204 (delete-char hang-ender-stuck)
4205 (goto-char here))
4206 (set-marker tmp-post nil))
d9e94c22 4207
a66cd3ee
MS
4208 (set-marker end nil))))
4209
4210(defun c-fill-paragraph (&optional arg)
4211 "Like \\[fill-paragraph] but handles C and C++ style comments.
4212If any of the current line is a comment or within a comment, fill the
4213comment or the paragraph of it that point is in, preserving the
4214comment indentation or line-starting decorations (see the
4215`c-comment-prefix-regexp' and `c-block-comment-prefix' variables for
4216details).
4217
4218If point is inside multiline string literal, fill it. This currently
4219does not respect escaped newlines, except for the special case when it
4220is the very first thing in the string. The intended use for this rule
4221is in situations like the following:
4222
4223char description[] = \"\\
4224A very long description of something that you want to fill to make
4225nicely formatted output.\"\;
4226
4227If point is in any other situation, i.e. in normal code, do nothing.
4228
4229Optional prefix ARG means justify paragraph as well."
4230 (interactive "*P")
4231 (let ((fill-paragraph-function
4232 ;; Avoid infinite recursion.
4233 (if (not (eq fill-paragraph-function 'c-fill-paragraph))
4234 fill-paragraph-function)))
d9e94c22 4235 (c-mask-paragraph t nil 'fill-paragraph arg))
51f606de
GM
4236 ;; Always return t. This has the effect that if filling isn't done
4237 ;; above, it isn't done at all, and it's therefore effectively
4238 ;; disabled in normal code.
4239 t)
4240
4241(defun c-do-auto-fill ()
4242 ;; Do automatic filling if not inside a context where it should be
4243 ;; ignored.
4244 (let ((c-auto-fill-prefix
4245 ;; The decision whether the line should be broken is actually
4246 ;; done in c-indent-new-comment-line, which do-auto-fill
4247 ;; calls to break lines. We just set this special variable
4248 ;; so that we'll know when we're called from there. It's
4249 ;; also used to detect whether fill-prefix is user set or
4250 ;; generated automatically by do-auto-fill.
4251 fill-prefix))
d9e94c22 4252 (c-mask-paragraph nil t 'do-auto-fill)))
51f606de 4253
a66cd3ee
MS
4254(defun c-indent-new-comment-line (&optional soft allow-auto-fill)
4255 "Break line at point and indent, continuing comment or macro if within one.
51f606de
GM
4256If inside a comment and `comment-multi-line' is non-nil, the
4257indentation and line prefix are preserved (see the
4258`c-comment-prefix-regexp' and `c-block-comment-prefix' variables for
b8ded794
GM
4259details). If inside a single line comment and `comment-multi-line' is
4260nil, a new comment of the same type is started on the next line and
a66cd3ee
MS
4261indented as appropriate for comments. If inside a macro, a line
4262continuation backslash is inserted and aligned as appropriate, and the
4263new line is indented according to `c-syntactic-indentation'.
51f606de
GM
4264
4265If a fill prefix is specified, it overrides all the above."
a66cd3ee
MS
4266 ;; allow-auto-fill is used from c-context-line-break to allow auto
4267 ;; filling to break the line more than once. Since this function is
4268 ;; used from auto-fill itself, that's normally disabled to avoid
4269 ;; unnecessary recursion.
51f606de
GM
4270 (interactive)
4271 (let ((fill-prefix fill-prefix)
4272 (do-line-break
4273 (lambda ()
a66cd3ee
MS
4274 (delete-horizontal-space)
4275 (if soft
4276 (insert-and-inherit ?\n)
4277 (newline (if allow-auto-fill nil 1)))))
51f606de
GM
4278 ;; Already know the literal type and limits when called from
4279 ;; c-context-line-break.
130c507e 4280 (c-lit-limits c-lit-limits)
a66cd3ee
MS
4281 (c-lit-type c-lit-type)
4282 (c-macro-start c-macro-start))
0386b551
AM
4283
4284 (c-save-buffer-state ()
4285 (when (not (eq c-auto-fill-prefix t))
4286 ;; Called from do-auto-fill.
4287 (unless c-lit-limits
4288 (setq c-lit-limits (c-literal-limits nil nil t)))
4289 (unless c-lit-type
4290 (setq c-lit-type (c-literal-type c-lit-limits)))
4291 (if (memq (cond ((c-query-and-set-macro-start) 'cpp)
4292 ((null c-lit-type) 'code)
4293 (t c-lit-type))
4294 c-ignore-auto-fill)
4295 (setq fill-prefix t) ; Used as flag in the cond.
4296 (if (and (null c-auto-fill-prefix)
4297 (eq c-lit-type 'c)
4298 (<= (c-point 'bol) (car c-lit-limits)))
4299 ;; The adaptive fill function has generated a prefix, but
4300 ;; we're on the first line in a block comment so it'll be
4301 ;; wrong. Ignore it to guess a better one below.
4302 (setq fill-prefix nil)
4303 (when (and (eq c-lit-type 'c++)
4304 (not (string-match (concat "\\`[ \t]*"
4305 c-line-comment-starter)
4306 (or fill-prefix ""))))
4307 ;; Kludge: If the function that adapted the fill prefix
4308 ;; doesn't produce the required comment starter for line
4309 ;; comments, then we ignore it.
4310 (setq fill-prefix nil)))
4311 )))
4312
51f606de
GM
4313 (cond ((eq fill-prefix t)
4314 ;; A call from do-auto-fill which should be ignored.
4315 )
4316 (fill-prefix
4317 ;; A fill-prefix overrides anything.
4318 (funcall do-line-break)
4319 (insert-and-inherit fill-prefix))
0386b551 4320 ((c-save-buffer-state ()
51f606de 4321 (unless c-lit-limits
a66cd3ee 4322 (setq c-lit-limits (c-literal-limits)))
51f606de
GM
4323 (unless c-lit-type
4324 (setq c-lit-type (c-literal-type c-lit-limits)))
4325 (memq c-lit-type '(c c++)))
a66cd3ee 4326 ;; Some sort of comment.
b8ded794
GM
4327 (if (or comment-multi-line
4328 (save-excursion
4329 (goto-char (car c-lit-limits))
4330 (end-of-line)
4331 (< (point) (cdr c-lit-limits))))
51f606de 4332 ;; Inside a comment that should be continued.
d9e94c22
MS
4333 (let ((fill (c-save-buffer-state nil
4334 (c-guess-fill-prefix
4335 (setq c-lit-limits
4336 (c-collect-line-comments c-lit-limits))
4337 c-lit-type)))
a66cd3ee 4338 (pos (point))
94dd9d6d 4339 (start-col (current-column))
a66cd3ee
MS
4340 (comment-text-end
4341 (or (and (eq c-lit-type 'c)
4342 (save-excursion
4343 (goto-char (- (cdr c-lit-limits) 2))
4344 (if (looking-at "\\*/") (point))))
4345 (cdr c-lit-limits))))
4346 ;; Skip forward past the fill prefix in case
4347 ;; we're standing in it.
4348 ;;
4349 ;; FIXME: This doesn't work well in cases like
4350 ;;
4351 ;; /* Bla bla bla bla bla
4352 ;; bla bla
4353 ;;
4354 ;; If point is on the 'B' then the line will be
4355 ;; broken after "Bla b".
94dd9d6d
AM
4356 ;;
4357 ;; If we have an empty comment, /* */, the next
4358 ;; lot of code pushes point to the */. We fix
4359 ;; this by never allowing point to end up to the
4360 ;; right of where it started.
a66cd3ee
MS
4361 (while (and (< (current-column) (cdr fill))
4362 (not (eolp)))
4363 (forward-char 1))
4364 (if (and (> (point) comment-text-end)
4365 (> (c-point 'bol) (car c-lit-limits)))
51f606de 4366 (progn
a66cd3ee
MS
4367 ;; The skip takes us out of the (block)
4368 ;; comment; insert the fill prefix at bol
4369 ;; instead and keep the position.
4370 (setq pos (copy-marker pos t))
4371 (beginning-of-line)
4372 (insert-and-inherit (car fill))
4373 (if soft (insert-and-inherit ?\n) (newline 1))
4374 (goto-char pos)
4375 (set-marker pos nil))
4376 ;; Don't break in the middle of a comment starter
4377 ;; or ender.
4378 (cond ((> (point) comment-text-end)
4379 (goto-char comment-text-end))
4380 ((< (point) (+ (car c-lit-limits) 2))
4381 (goto-char (+ (car c-lit-limits) 2))))
51f606de 4382 (funcall do-line-break)
94dd9d6d
AM
4383 (insert-and-inherit (car fill))
4384 (if (> (current-column) start-col)
4385 (move-to-column start-col)))) ; can this hit the
4386 ; middle of a TAB?
51f606de
GM
4387 ;; Inside a comment that should be broken.
4388 (let ((comment-start comment-start)
4389 (comment-end comment-end)
4390 col)
4391 (if (eq c-lit-type 'c)
4392 (unless (string-match "[ \t]*/\\*" comment-start)
4393 (setq comment-start "/* " comment-end " */"))
4394 (unless (string-match "[ \t]*//" comment-start)
4395 (setq comment-start "// " comment-end "")))
4396 (setq col (save-excursion
4397 (back-to-indentation)
4398 (current-column)))
4399 (funcall do-line-break)
4400 (when (and comment-end (not (equal comment-end "")))
4401 (forward-char -1)
4402 (insert-and-inherit comment-end)
4403 (forward-char 1))
4404 ;; c-comment-indent may look at the current
4405 ;; indentation, so let's start out with the same
4406 ;; indentation as the previous one.
4407 (indent-to col)
4408 (insert-and-inherit comment-start)
4409 (indent-for-comment))))
a66cd3ee
MS
4410 ((c-query-and-set-macro-start)
4411 ;; In a macro.
4412 (unless (looking-at "[ \t]*\\\\$")
4413 ;; Do not clobber the alignment of the line continuation
4414 ;; slash; c-backslash-region might look at it.
4415 (delete-horizontal-space))
4416 ;; Got an asymmetry here: In normal code this command
4417 ;; doesn't indent the next line syntactically, and otoh a
4418 ;; normal syntactically indenting newline doesn't continue
4419 ;; the macro.
4420 (c-newline-and-indent (if allow-auto-fill nil 1)))
51f606de
GM
4421 (t
4422 ;; Somewhere else in the code.
4423 (let ((col (save-excursion
a66cd3ee
MS
4424 (beginning-of-line)
4425 (while (and (looking-at "[ \t]*\\\\?$")
4426 (= (forward-line -1) 0)))
4427 (current-indentation))))
51f606de
GM
4428 (funcall do-line-break)
4429 (indent-to col))))))
4430
4431(defalias 'c-comment-line-break-function 'c-indent-new-comment-line)
4432(make-obsolete 'c-comment-line-break-function 'c-indent-new-comment-line)
4433
4434;; advice for indent-new-comment-line for older Emacsen
4435(unless (boundp 'comment-line-break-function)
130c507e 4436 (defvar c-inside-line-break-advice nil)
51f606de
GM
4437 (defadvice indent-new-comment-line (around c-line-break-advice
4438 activate preactivate)
4439 "Call `c-indent-new-comment-line' if in CC Mode."
130c507e 4440 (if (or c-inside-line-break-advice
51f606de
GM
4441 (not c-buffer-is-cc-mode))
4442 ad-do-it
130c507e 4443 (let ((c-inside-line-break-advice t))
51f606de
GM
4444 (c-indent-new-comment-line (ad-get-arg 0))))))
4445
4446(defun c-context-line-break ()
4447 "Do a line break suitable to the context.
4448
a66cd3ee
MS
4449When point is outside a comment or macro, insert a newline and indent
4450according to the syntactic context, unless `c-syntactic-indentation'
4451is nil, in which case the new line is indented as the previous
4452non-empty line instead.
4453
4454When point is inside the content of a preprocessor directive, a line
4455continuation backslash is inserted before the line break and aligned
4456appropriately. The end of the cpp directive doesn't count as inside
4457it.
51f606de
GM
4458
4459When point is inside a comment, continue it with the appropriate
4460comment prefix (see the `c-comment-prefix-regexp' and
4461`c-block-comment-prefix' variables for details). The end of a
51c9af45
AM
4462C++-style line comment doesn't count as inside it.
4463
4464When point is inside a string, only insert a backslash when it is also
4465inside a preprocessor directive."
0386b551 4466
51f606de 4467 (interactive "*")
0386b551 4468 (let* (c-lit-limits c-lit-type
a66cd3ee 4469 (c-macro-start c-macro-start))
0386b551 4470
51c9af45
AM
4471 (c-save-buffer-state ()
4472 (setq c-lit-limits (c-literal-limits nil nil t)
4473 c-lit-type (c-literal-type c-lit-limits))
4474 (when (eq c-lit-type 'c++)
4475 (setq c-lit-limits (c-collect-line-comments c-lit-limits)))
4476 (c-query-and-set-macro-start))
0386b551 4477
51c9af45
AM
4478 (cond
4479 ((or (eq c-lit-type 'c)
4480 (and (eq c-lit-type 'c++) ; C++ comment, but not at the very end of it.
4481 (< (save-excursion
4482 (skip-chars-forward " \t")
4483 (point))
4484 (1- (cdr c-lit-limits))))
4485 (and (numberp c-macro-start) ; Macro, but not at the very end of
4486 ; it, not in a string, and not in the
4487 ; cpp keyword.
4488 (not (eq c-lit-type 'string))
4489 (or (not (looking-at "\\s *$"))
4490 (eq (char-before) ?\\))
4491 (<= (save-excursion
4492 (goto-char c-macro-start)
4493 (if (looking-at c-opt-cpp-start)
4494 (goto-char (match-end 0)))
4495 (point))
4496 (point))))
4497 (let ((comment-multi-line t)
4498 (fill-prefix nil))
4499 (c-indent-new-comment-line nil t)))
4500
4501 ((eq c-lit-type 'string)
4502 (if (and (numberp c-macro-start)
4503 (not (eq (char-before) ?\\)))
4504 (insert ?\\))
4505 (newline))
4506
4507 (t (delete-horizontal-space)
4508 (newline)
51f606de
GM
4509 ;; c-indent-line may look at the current indentation, so let's
4510 ;; start out with the same indentation as the previous line.
51c9af45
AM
4511 (let ((col (save-excursion
4512 (backward-char)
4513 (forward-line 0)
4514 (while (and (looking-at "[ \t]*\\\\?$")
4515 (= (forward-line -1) 0)))
4516 (current-indentation))))
4517 (indent-to col))
4518 (indent-according-to-mode)))))
785eecbb 4519
a66cd3ee
MS
4520(defun c-context-open-line ()
4521 "Insert a line break suitable to the context and leave point before it.
4522This is the `c-context-line-break' equivalent to `open-line', which is
4523normally bound to C-o. See `c-context-line-break' for the details."
4524 (interactive "*")
4525 (let ((here (point)))
4526 (unwind-protect
4527 (progn
4528 ;; Temporarily insert a non-whitespace char to keep any
4529 ;; preceding whitespace intact.
4530 (insert ?x)
4531 (c-context-line-break))
4532 (goto-char here)
4533 (delete-char 1))))
4534
785eecbb 4535\f
130c507e 4536(cc-provide 'cc-cmds)
3afbc435 4537
cbee283d 4538;; arch-tag: bf0611dc-d1f4-449e-9e45-4ec7c6936677
785eecbb 4539;;; cc-cmds.el ends here