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