aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/progmodes/cc-align.el392
-rw-r--r--lisp/progmodes/cc-cmds.el1369
-rw-r--r--lisp/progmodes/cc-compat.el149
-rw-r--r--lisp/progmodes/cc-defs.el185
-rw-r--r--lisp/progmodes/cc-engine.el1704
-rw-r--r--lisp/progmodes/cc-langs.el551
-rw-r--r--lisp/progmodes/cc-menus.el103
-rw-r--r--lisp/progmodes/cc-mode.el344
-rw-r--r--lisp/progmodes/cc-styles.el617
-rw-r--r--lisp/progmodes/cc-vars.el391
10 files changed, 5805 insertions, 0 deletions
diff --git a/lisp/progmodes/cc-align.el b/lisp/progmodes/cc-align.el
new file mode 100644
index 00000000000..3902e1efc4a
--- /dev/null
+++ b/lisp/progmodes/cc-align.el
@@ -0,0 +1,392 @@
1;;; cc-align.el --- custom indentation functions for CC Mode
2
3;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
4
5;; Authors: 1992-1997 Barry A. Warsaw
6;; 1987 Dave Detlefs and Stewart Clamen
7;; 1985 Richard M. Stallman
8;; Maintainer: cc-mode-help@python.org
9;; Created: 22-Apr-1997 (split from cc-mode.el)
10;; Version: 5.12
11;; Keywords: c languages oop
12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software; you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation; either version 2, or (at your option)
18;; any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs; see the file COPYING. If not, write to the
27;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28;; Boston, MA 02111-1307, USA.
29
30(eval-when-compile
31 (require 'cc-defs)
32 (require 'cc-vars)
33 (require 'cc-engine)
34 (require 'cc-langs))
35
36
37;; Standard indentation line-ups
38(defun c-lineup-arglist (langelem)
39 ;; lineup the current arglist line with the arglist appearing just
40 ;; after the containing paren which starts the arglist.
41 (save-excursion
42 (let* ((containing-sexp
43 (save-excursion
44 ;; arglist-cont-nonempty gives relpos ==
45 ;; to boi of containing-sexp paren. This
46 ;; is good when offset is +, but bad
47 ;; when it is c-lineup-arglist, so we
48 ;; have to special case a kludge here.
49 (if (memq (car langelem) '(arglist-intro arglist-cont-nonempty))
50 (progn
51 (beginning-of-line)
52 (backward-up-list 1)
53 (skip-chars-forward " \t" (c-point 'eol)))
54 (goto-char (cdr langelem)))
55 (point)))
56 (langelem-col (c-langelem-col langelem t)))
57 (if (save-excursion
58 (beginning-of-line)
59 (looking-at "[ \t]*)"))
60 (progn (goto-char (match-end 0))
61 (forward-sexp -1)
62 (forward-char 1)
63 (c-forward-syntactic-ws)
64 (- (current-column) langelem-col))
65 (goto-char containing-sexp)
66 (or (eolp)
67 (not (memq (char-after) '(?{ ?\( )))
68 (let ((eol (c-point 'eol))
69 (here (progn
70 (forward-char 1)
71 (skip-chars-forward " \t")
72 (point))))
73 (c-forward-syntactic-ws)
74 (if (< (point) eol)
75 (goto-char here))))
76 (- (current-column) langelem-col)
77 ))))
78
79(defun c-lineup-arglist-intro-after-paren (langelem)
80 ;; lineup an arglist-intro line to just after the open paren
81 (save-excursion
82 (let ((langelem-col (c-langelem-col langelem t))
83 (ce-curcol (save-excursion
84 (beginning-of-line)
85 (backward-up-list 1)
86 (skip-chars-forward " \t" (c-point 'eol))
87 (current-column))))
88 (- ce-curcol langelem-col -1))))
89
90(defun c-lineup-arglist-close-under-paren (langelem)
91 ;; lineup an arglist-intro line to just after the open paren
92 (save-excursion
93 (let ((langelem-col (c-langelem-col langelem t))
94 (ce-curcol (save-excursion
95 (beginning-of-line)
96 (backward-up-list 1)
97 (current-column))))
98 (- ce-curcol langelem-col))))
99
100(defun c-lineup-streamop (langelem)
101 ;; lineup stream operators
102 (save-excursion
103 (let ((langelem-col (c-langelem-col langelem)))
104 (re-search-forward "<<\\|>>" (c-point 'eol) 'move)
105 (goto-char (match-beginning 0))
106 (- (current-column) langelem-col))))
107
108(defun c-lineup-multi-inher (langelem)
109 ;; line up multiple inheritance lines
110 (save-excursion
111 (let ((eol (c-point 'eol))
112 (here (point))
113 (langelem-col (c-langelem-col langelem)))
114 (skip-chars-forward "^:" eol)
115 (skip-chars-forward " \t:" eol)
116 (if (or (eolp)
117 (looking-at c-comment-start-regexp))
118 (c-forward-syntactic-ws here))
119 (- (current-column) langelem-col)
120 )))
121
122(defun c-lineup-java-inher (langelem)
123 ;; line up Java implements and extends continuations
124 (save-excursion
125 (let ((langelem-col (c-langelem-col langelem)))
126 (forward-word 1)
127 (if (looking-at "[ \t]*$")
128 langelem-col
129 (c-forward-syntactic-ws)
130 (- (current-column) langelem-col)))))
131
132(defun c-lineup-java-throws (langelem)
133 ;; lineup func-decl-cont's in Java which are continuations of throws
134 ;; declarations. If `throws' starts the previous line, line up to
135 ;; just after that keyword. If not, lineup under the previous line.
136 (save-excursion
137 (let ((iopl (c-point 'iopl))
138 (langelem-col (c-langelem-col langelem t))
139 (extra 0))
140 (back-to-indentation)
141 (cond
142 ((looking-at "throws[ \t\n]")
143 (goto-char (cdr langelem))
144 (setq extra c-basic-offset))
145 ((and (goto-char iopl)
146 (looking-at "throws[ \t\n]"))
147 (forward-word 1)
148 (skip-chars-forward " \t")
149 (when (eolp)
150 (back-to-indentation)
151 (setq extra c-basic-offset)))
152 (t (goto-char iopl)))
153 (+ (- (current-column) langelem-col) extra))))
154
155(defun c-lineup-C-comments (langelem)
156 ;; line up C block comment continuation lines
157 (save-excursion
158 (let ((here (point))
159 (stars (progn (back-to-indentation)
160 (skip-chars-forward "*")))
161 (langelem-col (c-langelem-col langelem)))
162 (back-to-indentation)
163 (if (not (re-search-forward "/\\([*]+\\)" (c-point 'eol) t))
164 (progn
165 (if (not (looking-at "[*]+"))
166 (progn
167 ;; we now have to figure out where this comment begins.
168 (goto-char here)
169 (back-to-indentation)
170 (if (looking-at "[*]+/")
171 (progn (goto-char (match-end 0))
172 (forward-comment -1))
173 (goto-char (cdr langelem))
174 (back-to-indentation))))
175 (- (current-column) langelem-col))
176 (if (zerop stars)
177 (progn
178 (skip-chars-forward " \t")
179 (- (current-column) langelem-col))
180 ;; how many stars on comment opening line? if greater than
181 ;; on current line, align left. if less than or equal,
182 ;; align right. this should also pick up Javadoc style
183 ;; comments.
184 (if (> (length (match-string 1)) stars)
185 (progn
186 (back-to-indentation)
187 (- (current-column) -1 langelem-col))
188 (- (current-column) stars langelem-col))
189 )))))
190
191(defun c-lineup-comment (langelem)
192 ;; support old behavior for comment indentation. we look at
193 ;; c-comment-only-line-offset to decide how to indent comment
194 ;; only-lines
195 (save-excursion
196 (back-to-indentation)
197 ;; this highly kludgiforous flag prevents the mapcar over
198 ;; c-syntactic-context from entering an infinite loop
199 (let ((recurse-prevention-flag (boundp 'recurse-prevention-flag)))
200 (cond
201 ;; CASE 1: preserve comment-column
202 (recurse-prevention-flag 0)
203 ((= (current-column) comment-column)
204 ;; we have to subtract out all other indentation
205 (- comment-column (apply '+ (mapcar 'c-get-offset
206 c-syntactic-context))))
207 ;; indent as specified by c-comment-only-line-offset
208 ((not (bolp))
209 (or (car-safe c-comment-only-line-offset)
210 c-comment-only-line-offset))
211 (t
212 (or (cdr-safe c-comment-only-line-offset)
213 (car-safe c-comment-only-line-offset)
214 -1000)) ;jam it against the left side
215 ))))
216
217(defun c-lineup-runin-statements (langelem)
218 ;; line up statements in coding standards which place the first
219 ;; statement on the same line as the block opening brace.
220 (if (eq (char-after (cdr langelem)) ?{)
221 (save-excursion
222 (let ((langelem-col (c-langelem-col langelem)))
223 (forward-char 1)
224 (skip-chars-forward " \t")
225 (- (current-column) langelem-col)))
226 0))
227
228(defun c-lineup-math (langelem)
229 ;; line up math statement-cont after the equals
230 (save-excursion
231 (let ((equalp (save-excursion
232 (goto-char (c-point 'boi))
233 (skip-chars-forward "^=" (c-point 'eol))
234 (and (eq (char-after) ?=)
235 (- (point) (c-point 'boi)))))
236 (langelem-col (c-langelem-col langelem))
237 donep)
238 (while (and (not donep)
239 (< (point) (c-point 'eol)))
240 (skip-chars-forward "^=" (c-point 'eol))
241 (if (c-in-literal (cdr langelem))
242 (forward-char 1)
243 (setq donep t)))
244 (if (not (eq (char-after) ?=))
245 ;; there's no equal sign on the line
246 c-basic-offset
247 ;; calculate indentation column after equals and ws, unless
248 ;; our line contains an equals sign
249 (if (not equalp)
250 (progn
251 (forward-char 1)
252 (skip-chars-forward " \t")
253 (setq equalp 0)))
254 (- (current-column) equalp langelem-col))
255 )))
256
257(defun c-lineup-ObjC-method-call (langelem)
258 ;; Line up methods args as elisp-mode does with function args: go to
259 ;; the position right after the message receiver, and if you are at
260 ;; (eolp) indent the current line by a constant offset from the
261 ;; opening bracket; otherwise we are looking at the first character
262 ;; of the first method call argument, so lineup the current line
263 ;; with it.
264 (save-excursion
265 (let* ((extra (save-excursion
266 (back-to-indentation)
267 (c-backward-syntactic-ws (cdr langelem))
268 (if (eq (char-before) ?:)
269 (- c-basic-offset)
270 0)))
271 (open-bracket-pos (cdr langelem))
272 (open-bracket-col (progn
273 (goto-char open-bracket-pos)
274 (current-column)))
275 (target-col (progn
276 (forward-char)
277 (forward-sexp)
278 (skip-chars-forward " \t")
279 (if (eolp)
280 (+ open-bracket-col c-basic-offset)
281 (current-column))))
282 )
283 (- target-col open-bracket-col extra))))
284
285(defun c-lineup-ObjC-method-args (langelem)
286 ;; Line up the colons that separate args. This is done trying to
287 ;; align colons vertically.
288 (save-excursion
289 (let* ((here (c-point 'boi))
290 (curcol (progn (goto-char here) (current-column)))
291 (eol (c-point 'eol))
292 (relpos (cdr langelem))
293 (first-col-column (progn
294 (goto-char relpos)
295 (skip-chars-forward "^:" eol)
296 (and (eq (char-after) ?:)
297 (current-column)))))
298 (if (not first-col-column)
299 c-basic-offset
300 (goto-char here)
301 (skip-chars-forward "^:" eol)
302 (if (eq (char-after) ?:)
303 (+ curcol (- first-col-column (current-column)))
304 c-basic-offset)))))
305
306(defun c-lineup-ObjC-method-args-2 (langelem)
307 ;; Line up the colons that separate args. This is done trying to
308 ;; align the colon on the current line with the previous one.
309 (save-excursion
310 (let* ((here (c-point 'boi))
311 (curcol (progn (goto-char here) (current-column)))
312 (eol (c-point 'eol))
313 (relpos (cdr langelem))
314 (prev-col-column (progn
315 (skip-chars-backward "^:" relpos)
316 (and (eq (char-before) ?:)
317 (- (current-column) 1)))))
318 (if (not prev-col-column)
319 c-basic-offset
320 (goto-char here)
321 (skip-chars-forward "^:" eol)
322 (if (eq (char-after) ?:)
323 (+ curcol (- prev-col-column (current-column)))
324 c-basic-offset)))))
325
326(defun c-snug-do-while (syntax pos)
327 "Dynamically calculate brace hanginess for do-while statements.
328Using this function, `while' clauses that end a `do-while' block will
329remain on the same line as the brace that closes that block.
330
331See `c-hanging-braces-alist' for how to utilize this function as an
332ACTION associated with `block-close' syntax."
333 (save-excursion
334 (let (langelem)
335 (if (and (eq syntax 'block-close)
336 (setq langelem (assq 'block-close c-syntactic-context))
337 (progn (goto-char (cdr langelem))
338 (if (eq (char-after) ?{)
339 (c-safe (forward-sexp -1)))
340 (looking-at "\\<do\\>[^_]")))
341 '(before)
342 '(before after)))))
343
344(defun c-gnu-impose-minimum ()
345 "Imposes a minimum indentation for lines inside a top-level construct.
346The variable `c-label-minimum-indentation' specifies the minimum
347indentation amount."
348 (let ((non-top-levels '(defun-block-intro statement statement-cont
349 statement-block-intro statement-case-intro
350 statement-case-open substatement substatement-open
351 case-label label do-while-closure else-clause
352 ))
353 (syntax c-syntactic-context)
354 langelem)
355 (while syntax
356 (setq langelem (car (car syntax))
357 syntax (cdr syntax))
358 ;; don't adjust comment-only lines
359 (cond ((eq langelem 'comment-intro)
360 (setq syntax nil))
361 ((memq langelem non-top-levels)
362 (save-excursion
363 (setq syntax nil)
364 (back-to-indentation)
365 (if (zerop (current-column))
366 (insert (make-string c-label-minimum-indentation 32)))
367 ))
368 ))))
369
370
371;; Useful for c-hanging-semi&comma-criteria
372(defun c-semi&comma-inside-parenlist ()
373 "Determine if a newline should be added after a semicolon.
374If a comma was inserted, no determination is made. If a semicolon was
375inserted inside a parenthesis list, no newline is added otherwise a
376newline is added. In either case, checking is stopped. This supports
377exactly the old newline insertion behavior."
378 ;; newline only after semicolon, but only if that semicolon is not
379 ;; inside a parenthesis list (e.g. a for loop statement)
380 (if (not (eq last-command-char ?\;))
381 nil ; continue checking
382 (if (condition-case nil
383 (save-excursion
384 (up-list -1)
385 (not (eq (char-after) ?\()))
386 (error t))
387 t
388 'stop)))
389
390
391(provide 'cc-align)
392;;; cc-align.el ends here
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
new file mode 100644
index 00000000000..62e89522bbb
--- /dev/null
+++ b/lisp/progmodes/cc-cmds.el
@@ -0,0 +1,1369 @@
1;;; cc-cmds.el --- user level commands for CC Mode
2
3;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
4
5;; Authors: 1992-1997 Barry A. Warsaw
6;; 1987 Dave Detlefs and Stewart Clamen
7;; 1985 Richard M. Stallman
8;; Maintainer: cc-mode-help@python.org
9;; Created: 22-Apr-1997 (split from cc-mode.el)
10;; Version: 5.12
11;; Keywords: c languages oop
12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software; you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation; either version 2, or (at your option)
18;; any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs; see the file COPYING. If not, write to the
27;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28;; Boston, MA 02111-1307, USA.
29
30
31(defun c-calculate-state (arg prevstate)
32 ;; Calculate the new state of PREVSTATE, t or nil, based on arg. If
33 ;; arg is nil or zero, toggle the state. If arg is negative, turn
34 ;; the state off, and if arg is positive, turn the state on
35 (if (or (not arg)
36 (zerop (setq arg (prefix-numeric-value arg))))
37 (not prevstate)
38 (> arg 0)))
39
40;; Auto-newline and hungry-delete
41(defun c-toggle-auto-state (arg)
42 "Toggle auto-newline feature.
43Optional numeric ARG, if supplied turns on auto-newline when positive,
44turns it off when negative, and just toggles it when zero.
45
46When the auto-newline feature is enabled (as evidenced by the `/a' or
47`/ah' on the modeline after the mode name) newlines are automatically
48inserted after special characters such as brace, comma, semi-colon,
49and colon."
50 (interactive "P")
51 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
52 (c-update-modeline)
53 (c-keep-region-active))
54
55(defun c-toggle-hungry-state (arg)
56 "Toggle hungry-delete-key feature.
57Optional numeric ARG, if supplied turns on hungry-delete when positive,
58turns it off when negative, and just toggles it when zero.
59
60When the hungry-delete-key feature is enabled (as evidenced by the
61`/h' or `/ah' on the modeline after the mode name) the delete key
62gobbles all preceding whitespace in one fell swoop."
63 (interactive "P")
64 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
65 (c-update-modeline)
66 (c-keep-region-active))
67
68(defun c-toggle-auto-hungry-state (arg)
69 "Toggle auto-newline and hungry-delete-key features.
70Optional numeric ARG, if supplied turns on auto-newline and
71hungry-delete when positive, turns them off when negative, and just
72toggles them when zero.
73
74See `c-toggle-auto-state' and `c-toggle-hungry-state' for details."
75 (interactive "P")
76 (setq c-auto-newline (c-calculate-state arg c-auto-newline))
77 (setq c-hungry-delete-key (c-calculate-state arg c-hungry-delete-key))
78 (c-update-modeline)
79 (c-keep-region-active))
80
81
82;; Electric keys
83
84;; Note: In XEmacs 20.3 the Delete and BackSpace keysyms have been
85;; separated and "\177" is no longer an alias for both keys. Also,
86;; the variable delete-key-deletes-forward controls in which direction
87;; the Delete keysym deletes characters. The functions
88;; c-electric-delete and c-electric-backspace attempt to deal with
89;; this new functionality. For Emacs 19 and XEmacs 19 backwards
90;; compatibility, the old behavior has moved to c-electric-backspace
91;; and c-backspace-function.
92
93(defun c-electric-backspace (arg)
94 "Deletes preceding character or whitespace.
95If `c-hungry-delete-key' is non-nil, as evidenced by the \"/h\" or
96\"/ah\" string on the mode line, then all preceding whitespace is
97consumed. If however an ARG is supplied, or `c-hungry-delete-key' is
98nil, or point is inside a literal then the function in the variable
99`c-backspace-function' is called.
100
101See also \\[c-electric-delete]."
102 (interactive "P")
103 (if (or (not c-hungry-delete-key)
104 arg
105 (c-in-literal))
106 (funcall c-backspace-function (prefix-numeric-value arg))
107 (let ((here (point)))
108 (skip-chars-backward " \t\n")
109 (if (/= (point) here)
110 (delete-region (point) here)
111 (funcall c-backspace-function 1)
112 ))))
113
114(defun c-electric-delete (arg)
115 "Deletes preceding or following character or whitespace.
116
117The behavior of this function depends on the variable
118`delete-key-deletes-forward'. If this variable is nil (or does not
119exist, as in older Emacsen), then this function behaves identical to
120\\[c-electric-backspace].
121
122If `delete-key-deletes-forward' is non-nil, then deletion occurs in
123the forward direction. So if `c-hungry-delete-key' is non-nil, as
124evidenced by the \"/h\" or \"/ah\" string on the mode line, then all
125following whitespace is consumed. If however an ARG is supplied, or
126`c-hungry-delete-key' is nil, or point is inside a literal then the
127function in the variable `c-delete-function' is called."
128 (interactive "P")
129 (if (and (boundp 'delete-key-deletes-forward)
130 delete-key-deletes-forward)
131 (if (or (not c-hungry-delete-key)
132 arg
133 (c-in-literal))
134 (funcall c-delete-function (prefix-numeric-value arg))
135 (let ((here (point)))
136 (skip-chars-forward " \t\n")
137 (if (/= (point) here)
138 (delete-region (point) here)
139 (funcall c-delete-function 1))))
140 ;; act just like c-electric-backspace
141 (c-electric-backspace arg)))
142
143(defun c-electric-pound (arg)
144 "Electric pound (`#') insertion.
145Inserts a `#' character specially depending on the variable
146`c-electric-pound-behavior'. If a numeric ARG is supplied, or if
147point is inside a literal, nothing special happens."
148 (interactive "P")
149 (if (or (c-in-literal)
150 arg
151 (not (memq 'alignleft c-electric-pound-behavior)))
152 ;; do nothing special
153 (self-insert-command (prefix-numeric-value arg))
154 ;; place the pound character at the left edge
155 (let ((pos (- (point-max) (point)))
156 (bolp (bolp)))
157 (beginning-of-line)
158 (delete-horizontal-space)
159 (insert-char last-command-char 1)
160 (and (not bolp)
161 (goto-char (- (point-max) pos)))
162 )))
163
164(defun c-electric-brace (arg)
165 "Insert a brace.
166
167If the auto-newline feature is turned on, as evidenced by the \"/a\"
168or \"/ah\" string on the mode line, newlines are inserted before and
169after braces based on the value of `c-hanging-braces-alist'.
170
171Also, the line is re-indented unless a numeric ARG is supplied, there
172are non-whitespace characters present on the line after the brace, or
173the brace is inserted inside a literal."
174 (interactive "P")
175 (let* ((c-state-cache (c-parse-state))
176 (safepos (c-safe-position (point) c-state-cache))
177 (literal (c-in-literal safepos)))
178 ;; if we're in a literal, or we're not at the end of the line, or
179 ;; a numeric arg is provided, or auto-newlining is turned off,
180 ;; then just insert the character.
181 (if (or literal arg
182; (not c-auto-newline)
183 (not (looking-at "[ \t]*$")))
184 (self-insert-command (prefix-numeric-value arg))
185 (let* ((syms '(class-open class-close defun-open defun-close
186 inline-open inline-close brace-list-open brace-list-close
187 brace-list-intro brace-list-entry block-open block-close
188 substatement-open statement-case-open
189 extern-lang-open extern-lang-close))
190 ;; we want to inhibit blinking the paren since this will
191 ;; be most disruptive. we'll blink it ourselves later on
192 (old-blink-paren blink-paren-function)
193 blink-paren-function
194 (insertion-point (point))
195 delete-temp-newline
196 (preserve-p (eq 32 (char-syntax (char-before))))
197 ;; shut this up too
198 (c-echo-syntactic-information-p nil)
199 (syntax (progn
200 ;; only insert a newline if there is
201 ;; non-whitespace behind us
202 (if (save-excursion
203 (skip-chars-backward " \t")
204 (not (bolp)))
205 (progn (newline)
206 (setq delete-temp-newline t)))
207 (self-insert-command (prefix-numeric-value arg))
208 ;; state cache doesn't change
209 (c-guess-basic-syntax)))
210 (newlines (and
211 c-auto-newline
212 (or (c-lookup-lists syms syntax c-hanging-braces-alist)
213 '(ignore before after)))))
214 ;; If syntax is a function symbol, then call it using the
215 ;; defined semantics.
216 (if (and (not (consp (cdr newlines)))
217 (functionp (cdr newlines)))
218 (let ((c-syntactic-context syntax))
219 (setq newlines
220 (funcall (cdr newlines) (car newlines) insertion-point))))
221 ;; does a newline go before the open brace?
222 (if (memq 'before newlines)
223 ;; we leave the newline we've put in there before,
224 ;; but we need to re-indent the line above
225 (let ((pos (- (point-max) (point)))
226 (here (point))
227 (c-state-cache c-state-cache))
228 (forward-line -1)
229 ;; we may need to update the cache. this should still be
230 ;; faster than recalculating the state in many cases
231 (save-excursion
232 (save-restriction
233 (narrow-to-region here (point))
234 (if (and (c-safe (progn (backward-up-list -1) t))
235 (memq (char-before) '(?\) ?}))
236 (progn (widen)
237 (c-safe (progn (forward-sexp -1) t))))
238 (setq c-state-cache
239 (c-hack-state (point) 'open c-state-cache))
240 (if (and (car c-state-cache)
241 (not (consp (car c-state-cache)))
242 (<= (point) (car c-state-cache)))
243 (setq c-state-cache (cdr c-state-cache))
244 ))))
245 (let ((here (point))
246 (shift (c-indent-line)))
247 (setq c-state-cache (c-adjust-state (c-point 'bol) here
248 (- shift) c-state-cache)))
249 (goto-char (- (point-max) pos))
250 ;; if the buffer has changed due to the indentation, we
251 ;; need to recalculate syntax for the current line, but
252 ;; we won't need to update the state cache.
253 (if (/= (point) here)
254 (setq syntax (c-guess-basic-syntax))))
255 ;; must remove the newline we just stuck in (if we really did it)
256 (and delete-temp-newline
257 (save-excursion
258 ;; if there is whitespace before point, then preserve
259 ;; at least one space.
260 (delete-indentation)
261 (just-one-space)
262 (if (not preserve-p)
263 (delete-char -1))))
264 ;; since we're hanging the brace, we need to recalculate
265 ;; syntax. Update the state to accurately reflect the
266 ;; beginning of the line. We punt if we cross any open or
267 ;; closed parens because its just too hard to modify the
268 ;; known state. This limitation will be fixed in v5.
269 (save-excursion
270 (let ((bol (c-point 'bol)))
271 (if (zerop (car (parse-partial-sexp bol (1- (point)))))
272 (setq c-state-cache (c-whack-state bol c-state-cache)
273 syntax (c-guess-basic-syntax))
274 ;; gotta punt. this requires some horrible kludgery
275 (beginning-of-line)
276 (makunbound 'c-state-cache)
277 (setq c-state-cache (c-parse-state)
278 syntax nil))))
279 )
280 ;; now adjust the line's indentation. don't update the state
281 ;; cache since c-guess-basic-syntax isn't called when the
282 ;; syntax is passed to c-indent-line
283 (let ((here (point))
284 (shift (c-indent-line syntax)))
285 (setq c-state-cache (c-adjust-state (c-point 'bol) here
286 (- shift) c-state-cache)))
287 ;; Do all appropriate clean ups
288 (let ((here (point))
289 (pos (- (point-max) (point)))
290 mbeg mend)
291 ;; clean up empty defun braces
292 (if (and c-auto-newline
293 (memq 'empty-defun-braces c-cleanup-list)
294 (eq last-command-char ?\})
295 (c-intersect-lists '(defun-close class-close inline-close)
296 syntax)
297 (progn
298 (forward-char -1)
299 (skip-chars-backward " \t\n")
300 (eq (char-before) ?\{))
301 ;; make sure matching open brace isn't in a comment
302 (not (c-in-literal)))
303 (delete-region (point) (1- here)))
304 ;; clean up brace-else-brace
305 (if (and c-auto-newline
306 (memq 'brace-else-brace c-cleanup-list)
307 (eq last-command-char ?\{)
308 (re-search-backward "}[ \t\n]*else[ \t\n]*{" nil t)
309 (progn
310 (setq mbeg (match-beginning 0)
311 mend (match-end 0))
312 (= mend here))
313 (not (c-in-literal)))
314 (progn
315 (delete-region mbeg mend)
316 (insert "} else {")))
317 ;; clean up brace-elseif-brace
318 (if (and c-auto-newline
319 (memq 'brace-elseif-brace c-cleanup-list)
320 (eq last-command-char ?\{)
321 (re-search-backward "}[ \t\n]*else[ \t\n]+if[ \t\n]*" nil t)
322 (save-excursion
323 (goto-char (match-end 0))
324 (c-safe (forward-sexp 1))
325 (skip-chars-forward " \t\n")
326 (setq mbeg (match-beginning 0)
327 mend (match-end 0))
328 (= here (1+ (point))))
329 (not (c-in-literal)))
330 (progn
331 (delete-region mbeg mend)
332 (insert "} else if ")))
333 (goto-char (- (point-max) pos))
334 )
335 ;; does a newline go after the brace?
336 (if (memq 'after newlines)
337 (progn
338 (newline)
339 ;; update on c-state-cache
340 (let* ((bufpos (- (point) 2))
341 (which (if (eq (char-after bufpos) ?{) 'open 'close))
342 (c-state-cache (c-hack-state bufpos which c-state-cache)))
343 (c-indent-line))))
344 ;; blink the paren
345 (and (eq last-command-char ?\})
346 old-blink-paren
347 (save-excursion
348 (c-backward-syntactic-ws safepos)
349 (funcall old-blink-paren)))
350 ))))
351
352(defun c-electric-slash (arg)
353 "Insert a slash character.
354If slash is second of a double-slash C++ style comment introducing
355construct, and we are on a comment-only-line, indent line as comment.
356If numeric ARG is supplied or point is inside a literal, indentation
357is inhibited."
358 (interactive "P")
359 (let ((indentp (and (not arg)
360 (eq (char-before) ?/)
361 (eq last-command-char ?/)
362 (not (c-in-literal))))
363 ;; shut this up
364 (c-echo-syntactic-information-p nil))
365 (self-insert-command (prefix-numeric-value arg))
366 (if indentp
367 (c-indent-line))))
368
369(defun c-electric-star (arg)
370 "Insert a star character.
371If the star is the second character of a C style comment introducing
372construct, and we are on a comment-only-line, indent line as comment.
373If numeric ARG is supplied or point is inside a literal, indentation
374is inhibited."
375 (interactive "P")
376 (self-insert-command (prefix-numeric-value arg))
377 ;; if we are in a literal, or if arg is given do not re-indent the
378 ;; current line, unless this star introduces a comment-only line.
379 (if (and (not arg)
380 (memq (c-in-literal) '(c))
381 (eq (char-before) ?*)
382 (save-excursion
383 (forward-char -1)
384 (skip-chars-backward "*")
385 (if (eq (char-before) ?/)
386 (forward-char -1))
387 (skip-chars-backward " \t")
388 (bolp)))
389 ;; shut this up
390 (let (c-echo-syntactic-information-p)
391 (c-indent-line))
392 ))
393
394(defun c-electric-semi&comma (arg)
395 "Insert a comma or semicolon.
396When the auto-newline feature is turned on, as evidenced by the \"/a\"
397or \"/ah\" string on the mode line, a newline might be inserted. See
398the variable `c-hanging-semi&comma-criteria' for how newline insertion
399is determined.
400
401When semicolon is inserted, the line is re-indented unless a numeric
402arg is supplied, point is inside a literal, or there are
403non-whitespace characters on the line following the semicolon."
404 (interactive "P")
405 (let* ((lim (c-most-enclosing-brace (c-parse-state)))
406 (literal (c-in-literal lim))
407 (here (point))
408 ;; shut this up
409 (c-echo-syntactic-information-p nil))
410 (if (or literal
411 arg
412 (not (looking-at "[ \t]*$")))
413 (self-insert-command (prefix-numeric-value arg))
414 ;; do some special stuff with the character
415 (self-insert-command (prefix-numeric-value arg))
416 ;; do all cleanups, reindentations, and newline insertions, but
417 ;; only if c-auto-newline is turned on
418 (if (not c-auto-newline) nil
419 ;; clean ups
420 (let ((pos (- (point-max) (point))))
421 (if (and (or (and
422 (eq last-command-char ?,)
423 (memq 'list-close-comma c-cleanup-list))
424 (and
425 (eq last-command-char ?\;)
426 (memq 'defun-close-semi c-cleanup-list)))
427 (progn
428 (forward-char -1)
429 (skip-chars-backward " \t\n")
430 (eq (char-before) ?}))
431 ;; make sure matching open brace isn't in a comment
432 (not (c-in-literal lim)))
433 (delete-region (point) here))
434 (goto-char (- (point-max) pos)))
435 ;; re-indent line
436 (c-indent-line)
437 ;; check to see if a newline should be added
438 (let ((criteria c-hanging-semi&comma-criteria)
439 answer add-newline-p)
440 (while criteria
441 (setq answer (funcall (car criteria)))
442 ;; only nil value means continue checking
443 (if (not answer)
444 (setq criteria (cdr criteria))
445 (setq criteria nil)
446 ;; only 'stop specifically says do not add a newline
447 (setq add-newline-p (not (eq answer 'stop)))
448 ))
449 (if add-newline-p
450 (progn (newline)
451 (c-indent-line)))
452 )))))
453
454(defun c-electric-colon (arg)
455 "Insert a colon.
456
457If the auto-newline feature is turned on, as evidenced by the \"/a\"
458or \"/ah\" string on the mode line, newlines are inserted before and
459after colons based on the value of `c-hanging-colons-alist'.
460
461Also, the line is re-indented unless a numeric ARG is supplied, there
462are non-whitespace characters present on the line after the colon, or
463the colon is inserted inside a literal.
464
465This function cleans up double colon scope operators based on the
466value of `c-cleanup-list'."
467 (interactive "P")
468 (let* ((bod (c-point 'bod))
469 (literal (c-in-literal bod))
470 syntax newlines
471 ;; shut this up
472 (c-echo-syntactic-information-p nil))
473 (if (or literal
474 arg
475 (not (looking-at "[ \t]*$")))
476 (self-insert-command (prefix-numeric-value arg))
477 ;; insert the colon, then do any specified cleanups
478 (self-insert-command (prefix-numeric-value arg))
479 (let ((pos (- (point-max) (point)))
480 (here (point)))
481 (if (and c-auto-newline
482 (memq 'scope-operator c-cleanup-list)
483 (eq (char-before) ?:)
484 (progn
485 (forward-char -1)
486 (skip-chars-backward " \t\n")
487 (eq (char-before) ?:))
488 (not (c-in-literal))
489 (not (eq (char-after (- (point) 2)) ?:)))
490 (delete-region (point) (1- here)))
491 (goto-char (- (point-max) pos)))
492 ;; lets do some special stuff with the colon character
493 (setq syntax (c-guess-basic-syntax)
494 ;; some language elements can only be determined by
495 ;; checking the following line. Lets first look for ones
496 ;; that can be found when looking on the line with the
497 ;; colon
498 newlines
499 (and c-auto-newline
500 (or (c-lookup-lists '(case-label label access-label)
501 syntax c-hanging-colons-alist)
502 (c-lookup-lists '(member-init-intro inher-intro)
503 (prog2
504 (insert "\n")
505 (c-guess-basic-syntax)
506 (delete-char -1))
507 c-hanging-colons-alist))))
508 ;; indent the current line
509 (c-indent-line syntax)
510 ;; does a newline go before the colon? Watch out for already
511 ;; non-hung colons. However, we don't unhang them because that
512 ;; would be a cleanup (and anti-social).
513 (if (and (memq 'before newlines)
514 (save-excursion
515 (skip-chars-backward ": \t")
516 (not (bolp))))
517 (let ((pos (- (point-max) (point))))
518 (forward-char -1)
519 (newline)
520 (c-indent-line)
521 (goto-char (- (point-max) pos))))
522 ;; does a newline go after the colon?
523 (if (memq 'after (cdr-safe newlines))
524 (progn
525 (newline)
526 (c-indent-line)))
527 )))
528
529(defun c-electric-lt-gt (arg)
530 "Insert a less-than, or greater-than character.
531When the auto-newline feature is turned on, as evidenced by the \"/a\"
532or \"/ah\" string on the mode line, the line will be re-indented if
533the character inserted is the second of a C++ style stream operator
534and the buffer is in C++ mode.
535
536The line will also not be re-indented if a numeric argument is
537supplied, or point is inside a literal."
538 (interactive "P")
539 (let ((indentp (and (not arg)
540 (eq (char-before) last-command-char)
541 (not (c-in-literal))))
542 ;; shut this up
543 (c-echo-syntactic-information-p nil))
544 (self-insert-command (prefix-numeric-value arg))
545 (if indentp
546 (c-indent-line))))
547
548
549
550;; better movement routines for ThisStyleOfVariablesCommonInCPlusPlus
551;; originally contributed by Terry_Glanfield.Southern@rxuk.xerox.com
552(defun c-forward-into-nomenclature (&optional arg)
553 "Move forward to end of a nomenclature section or word.
554With arg, to it arg times."
555 (interactive "p")
556 (let ((case-fold-search nil))
557 (if (> arg 0)
558 (re-search-forward "\\W*\\([A-Z]*[a-z0-9]*\\)" (point-max) t arg)
559 (while (and (< arg 0)
560 (re-search-backward
561 "\\(\\(\\W\\|[a-z0-9]\\)[A-Z]+\\|\\W\\w+\\)"
562 (point-min) 0))
563 (forward-char 1)
564 (setq arg (1+ arg)))))
565 (c-keep-region-active))
566
567(defun c-backward-into-nomenclature (&optional arg)
568 "Move backward to beginning of a nomenclature section or word.
569With optional ARG, move that many times. If ARG is negative, move
570forward."
571 (interactive "p")
572 (c-forward-into-nomenclature (- arg))
573 (c-keep-region-active))
574
575(defun c-scope-operator ()
576 "Insert a double colon scope operator at point.
577No indentation or other \"electric\" behavior is performed."
578 (interactive)
579 (insert "::"))
580
581
582(defun c-beginning-of-statement (&optional count lim sentence-flag)
583 "Go to the beginning of the innermost C statement.
584With prefix arg, go back N - 1 statements. If already at the
585beginning of a statement then go to the beginning of the preceding
586one. If within a string or comment, or next to a comment (only
587whitespace between), move by sentences instead of statements.
588
589When called from a program, this function takes 3 optional args: the
590repetition count, a buffer position limit which is the farthest back
591to search, and a flag saying whether to do sentence motion when in a
592comment."
593 (interactive (list (prefix-numeric-value current-prefix-arg)
594 nil t))
595 (let ((here (point))
596 (count (or count 1))
597 (lim (or lim (c-point 'bod)))
598 state)
599 (save-excursion
600 (goto-char lim)
601 (setq state (parse-partial-sexp (point) here nil nil)))
602 (if (and sentence-flag
603 (or (nth 3 state)
604 (nth 4 state)
605; (looking-at (concat "[ \t]*" comment-start-skip))
606 (save-excursion
607 (skip-chars-backward " \t")
608 (goto-char (- (point) 2))
609 (looking-at "\\*/"))))
610 (forward-sentence (- count))
611 (while (> count 0)
612 (c-beginning-of-statement-1 lim)
613 (setq count (1- count)))
614 (while (< count 0)
615 (c-end-of-statement-1)
616 (setq count (1+ count))))
617 ;; its possible we've been left up-buf of lim
618 (goto-char (max (point) lim))
619 )
620 (c-keep-region-active))
621
622(defun c-end-of-statement (&optional count lim sentence-flag)
623 "Go to the end of the innermost C statement.
624
625With prefix arg, go forward N - 1 statements. Move forward to end of
626the next statement if already at end. If within a string or comment,
627move by sentences instead of statements.
628
629When called from a program, this function takes 3 optional args: the
630repetition count, a buffer position limit which is the farthest back
631to search, and a flag saying whether to do sentence motion when in a
632comment."
633 (interactive (list (prefix-numeric-value current-prefix-arg)
634 nil t))
635 (c-beginning-of-statement (- (or count 1)) lim sentence-flag)
636 (c-keep-region-active))
637
638
639;; set up electric character functions to work with pending-del,
640;; (a.k.a. delsel) mode. All symbols get the t value except
641;; c-electric-delete which gets 'supersede.
642(mapcar
643 (function
644 (lambda (sym)
645 (put sym 'delete-selection t) ; for delsel (Emacs)
646 (put sym 'pending-delete t))) ; for pending-del (XEmacs)
647 '(c-electric-pound
648 c-electric-brace
649 c-electric-slash
650 c-electric-star
651 c-electric-semi&comma
652 c-electric-lt-gt
653 c-electric-colon))
654(put 'c-electric-delete 'delete-selection 'supersede) ; delsel
655(put 'c-electric-delete 'pending-delete 'supersede) ; pending-del
656
657
658;; This is used by indent-for-comment to decide how much to indent a
659;; comment in C code based on its context.
660(defun c-comment-indent ()
661 (if (looking-at (concat "^\\(" c-comment-start-regexp "\\)"))
662 0 ;Existing comment at bol stays there.
663 (let ((opoint (point))
664 placeholder)
665 (save-excursion
666 (beginning-of-line)
667 (cond
668 ;; CASE 1: A comment following a solitary close-brace should
669 ;; have only one space.
670 ((looking-at (concat "[ \t]*}[ \t]*\\($\\|"
671 c-comment-start-regexp
672 "\\)"))
673 (search-forward "}")
674 (1+ (current-column)))
675 ;; CASE 2: 2 spaces after #endif
676 ((or (looking-at "^#[ \t]*endif[ \t]*")
677 (looking-at "^#[ \t]*else[ \t]*"))
678 7)
679 ;; CASE 3: when comment-column is nil, calculate the offset
680 ;; according to c-offsets-alist. E.g. identical to hitting
681 ;; TAB.
682 ((and c-indent-comments-syntactically-p
683 (save-excursion
684 (skip-chars-forward " \t")
685 (or (looking-at comment-start)
686 (eolp))))
687 (let ((syntax (c-guess-basic-syntax)))
688 ;; BOGOSITY ALERT: if we're looking at the eol, its
689 ;; because indent-for-comment hasn't put the comment-start
690 ;; in the buffer yet. this will screw up the syntactic
691 ;; analysis so we kludge in the necessary info. Another
692 ;; kludge is that if we're at the bol, then we really want
693 ;; to ignore any anchoring as specified by
694 ;; c-comment-only-line-offset since it doesn't apply here.
695 (if (save-excursion
696 (beginning-of-line)
697 (skip-chars-forward " \t")
698 (eolp))
699 (c-add-syntax 'comment-intro))
700 (let ((c-comment-only-line-offset
701 (if (consp c-comment-only-line-offset)
702 c-comment-only-line-offset
703 (cons c-comment-only-line-offset
704 c-comment-only-line-offset))))
705 (apply '+ (mapcar 'c-get-offset syntax)))))
706 ;; CASE 4: use comment-column if previous line is a
707 ;; comment-only line indented to the left of comment-column
708 ((save-excursion
709 (beginning-of-line)
710 (and (not (bobp))
711 (forward-line -1))
712 (skip-chars-forward " \t")
713 (prog1
714 (looking-at c-comment-start-regexp)
715 (setq placeholder (point))))
716 (goto-char placeholder)
717 (if (< (current-column) comment-column)
718 comment-column
719 (current-column)))
720 ;; CASE 5: If comment-column is 0, and nothing but space
721 ;; before the comment, align it at 0 rather than 1.
722 ((progn
723 (goto-char opoint)
724 (skip-chars-backward " \t")
725 (and (= comment-column 0) (bolp)))
726 0)
727 ;; CASE 6: indent at comment column except leave at least one
728 ;; space.
729 (t (max (1+ (current-column))
730 comment-column))
731 )))))
732
733;; used by outline-minor-mode
734(defun c-outline-level ()
735 (save-excursion
736 (skip-chars-forward "\t ")
737 (current-column)))
738
739
740(defun c-up-conditional (count)
741 "Move back to the containing preprocessor conditional, leaving mark behind.
742A prefix argument acts as a repeat count. With a negative argument,
743move forward to the end of the containing preprocessor conditional.
744When going backwards, `#elif' is treated like `#else' followed by
745`#if'. When going forwards, `#elif' is ignored."
746 (interactive "p")
747 (c-forward-conditional (- count) t)
748 (c-keep-region-active))
749
750(defun c-backward-conditional (count &optional up-flag)
751 "Move back across a preprocessor conditional, leaving mark behind.
752A prefix argument acts as a repeat count. With a negative argument,
753move forward across a preprocessor conditional."
754 (interactive "p")
755 (c-forward-conditional (- count) up-flag)
756 (c-keep-region-active))
757
758(defun c-forward-conditional (count &optional up-flag)
759 "Move forward across a preprocessor conditional, leaving mark behind.
760A prefix argument acts as a repeat count. With a negative argument,
761move backward across a preprocessor conditional."
762 (interactive "p")
763 (let* ((forward (> count 0))
764 (increment (if forward -1 1))
765 (search-function (if forward 're-search-forward 're-search-backward))
766 (new))
767 (save-excursion
768 (while (/= count 0)
769 (let ((depth (if up-flag 0 -1)) found)
770 (save-excursion
771 ;; Find the "next" significant line in the proper direction.
772 (while (and (not found)
773 ;; Rather than searching for a # sign that
774 ;; comes at the beginning of a line aside from
775 ;; whitespace, search first for a string
776 ;; starting with # sign. Then verify what
777 ;; precedes it. This is faster on account of
778 ;; the fastmap feature of the regexp matcher.
779 (funcall search-function
780 "#[ \t]*\\(if\\|elif\\|endif\\)"
781 nil t))
782 (beginning-of-line)
783 ;; Now verify it is really a preproc line.
784 (if (looking-at "^[ \t]*#[ \t]*\\(if\\|elif\\|endif\\)")
785 (let ((prev depth))
786 ;; Update depth according to what we found.
787 (beginning-of-line)
788 (cond ((looking-at "[ \t]*#[ \t]*endif")
789 (setq depth (+ depth increment)))
790 ((looking-at "[ \t]*#[ \t]*elif")
791 (if (and forward (= depth 0))
792 (setq found (point))))
793 (t (setq depth (- depth increment))))
794 ;; If we are trying to move across, and we find an
795 ;; end before we find a beginning, get an error.
796 (if (and (< prev 0) (< depth prev))
797 (error (if forward
798 "No following conditional at this level"
799 "No previous conditional at this level")))
800 ;; When searching forward, start from next line so
801 ;; that we don't find the same line again.
802 (if forward (forward-line 1))
803 ;; If this line exits a level of conditional, exit
804 ;; inner loop.
805 (if (< depth 0)
806 (setq found (point))))
807 ;; else
808 (if forward (forward-line 1))
809 )))
810 (or found
811 (error "No containing preprocessor conditional"))
812 (goto-char (setq new found)))
813 (setq count (+ count increment))))
814 (push-mark)
815 (goto-char new))
816 (c-keep-region-active))
817
818
819;; commands to indent lines, regions, defuns, and expressions
820(defun c-indent-command (&optional whole-exp)
821 "Indent current line as C code, and/or insert some whitespace.
822
823If `c-tab-always-indent' is t, always just indent the current line.
824If nil, indent the current line only if point is at the left margin or
825in the line's indentation; otherwise insert some whitespace[*]. If
826other than nil or t, then some whitespace[*] is inserted only within
827literals (comments and strings) and inside preprocessor directives,
828but the line is always reindented.
829
830A numeric argument, regardless of its value, means indent rigidly all
831the lines of the expression starting after point so that this line
832becomes properly indented. The relative indentation among the lines
833of the expression are preserved.
834
835 [*] The amount and kind of whitespace inserted is controlled by the
836 variable `c-insert-tab-function', which is called to do the actual
837 insertion of whitespace. Normally the function in this variable
838 just inserts a tab character, or the equivalent number of spaces,
839 depending on the variable `indent-tabs-mode'."
840
841 (interactive "P")
842 (let ((bod (c-point 'bod)))
843 (if whole-exp
844 ;; If arg, always indent this line as C
845 ;; and shift remaining lines of expression the same amount.
846 (let ((shift-amt (c-indent-line))
847 beg end)
848 (save-excursion
849 (if (eq c-tab-always-indent t)
850 (beginning-of-line))
851 (setq beg (point))
852 (forward-sexp 1)
853 (setq end (point))
854 (goto-char beg)
855 (forward-line 1)
856 (setq beg (point)))
857 (if (> end beg)
858 (indent-code-rigidly beg end (- shift-amt) "#")))
859 ;; No arg supplied, use c-tab-always-indent to determine
860 ;; behavior
861 (cond
862 ;; CASE 1: indent when at column zero or in lines indentation,
863 ;; otherwise insert a tab
864 ((not c-tab-always-indent)
865 (if (save-excursion
866 (skip-chars-backward " \t")
867 (not (bolp)))
868 (funcall c-insert-tab-function)
869 (c-indent-line)))
870 ;; CASE 2: just indent the line
871 ((eq c-tab-always-indent t)
872 (c-indent-line))
873 ;; CASE 3: if in a literal, insert a tab, but always indent the
874 ;; line
875 (t
876 (if (c-in-literal bod)
877 (funcall c-insert-tab-function))
878 (c-indent-line)
879 )))))
880
881(defun c-indent-exp (&optional shutup-p)
882 "Indent each line in balanced expression following point.
883Optional SHUTUP-P if non-nil, inhibits message printing and error checking."
884 (interactive "P")
885 (let ((here (point))
886 end progress-p)
887 (unwind-protect
888 (let ((c-echo-syntactic-information-p nil) ;keep quiet for speed
889 (start (progn
890 ;; try to be smarter about finding the range of
891 ;; lines to indent. skip all following
892 ;; whitespace. failing that, try to find any
893 ;; opening brace on the current line
894 (skip-chars-forward " \t\n")
895 (if (memq (char-after) '(?\( ?\[ ?\{))
896 (point)
897 (let ((state (parse-partial-sexp (point)
898 (c-point 'eol))))
899 (and (nth 1 state)
900 (goto-char (nth 1 state))
901 (memq (char-after) '(?\( ?\[ ?\{))
902 (point)))))))
903 ;; find balanced expression end
904 (setq end (and (c-safe (progn (forward-sexp 1) t))
905 (point-marker)))
906 ;; sanity check
907 (and (not start)
908 (not shutup-p)
909 (error "Cannot find start of balanced expression to indent."))
910 (and (not end)
911 (not shutup-p)
912 (error "Cannot find end of balanced expression to indent."))
913 (c-progress-init start end 'c-indent-exp)
914 (setq progress-p t)
915 (goto-char start)
916 (beginning-of-line)
917 (while (< (point) end)
918 (if (not (looking-at "[ \t]*$"))
919 (c-indent-line))
920 (c-progress-update)
921 (forward-line 1)))
922 ;; make sure marker is deleted
923 (and end
924 (set-marker end nil))
925 (and progress-p
926 (c-progress-fini 'c-indent-exp))
927 (goto-char here))))
928
929(defun c-indent-defun ()
930 "Re-indents the current top-level function def, struct or class declaration."
931 (interactive)
932 (let ((here (point-marker))
933 (c-echo-syntactic-information-p nil)
934 (brace (c-least-enclosing-brace (c-parse-state))))
935 (if brace
936 (goto-char brace)
937 (beginning-of-defun))
938 ;; if we're sitting at b-o-b, it might be because there was no
939 ;; least enclosing brace and we were sitting on the defun's open
940 ;; brace.
941 (if (and (bobp) (not (eq (char-after) ?\{)))
942 (goto-char here))
943 ;; if defun-prompt-regexp is non-nil, b-o-d might not leave us at
944 ;; the open brace. I consider this an Emacs bug.
945 (and (boundp 'defun-prompt-regexp)
946 defun-prompt-regexp
947 (looking-at defun-prompt-regexp)
948 (goto-char (match-end 0)))
949 ;; catch all errors in c-indent-exp so we can 1. give more
950 ;; meaningful error message, and 2. restore point
951 (unwind-protect
952 (c-indent-exp)
953 (goto-char here)
954 (set-marker here nil))))
955
956(defun c-indent-region (start end)
957 ;; Indent every line whose first char is between START and END inclusive.
958 (save-excursion
959 (goto-char start)
960 ;; Advance to first nonblank line.
961 (skip-chars-forward " \t\n")
962 (beginning-of-line)
963 (let (endmark)
964 (unwind-protect
965 (let ((c-tab-always-indent t)
966 ;; shut up any echo msgs on indiv lines
967 (c-echo-syntactic-information-p nil)
968 fence)
969 (c-progress-init start end 'c-indent-region)
970 (setq endmark (copy-marker end))
971 (while (and (bolp)
972 (not (eobp))
973 (< (point) endmark))
974 ;; update progress
975 (c-progress-update)
976 ;; Indent one line as with TAB.
977 (let (nextline sexpend sexpbeg)
978 ;; skip blank lines
979 (skip-chars-forward " \t\n")
980 (beginning-of-line)
981 ;; indent the current line
982 (c-indent-line)
983 (setq fence (point))
984 (if (save-excursion
985 (beginning-of-line)
986 (looking-at "[ \t]*#"))
987 (forward-line 1)
988 (save-excursion
989 ;; Find beginning of following line.
990 (setq nextline (c-point 'bonl))
991 ;; Find first beginning-of-sexp for sexp extending past
992 ;; this line.
993 (beginning-of-line)
994 (while (< (point) nextline)
995 (condition-case nil
996 (progn
997 (forward-sexp 1)
998 (setq sexpend (point)))
999 (error (setq sexpend nil)
1000 (goto-char nextline)))
1001 (c-forward-syntactic-ws))
1002 (if sexpend
1003 (progn
1004 ;; make sure the sexp we found really starts on the
1005 ;; current line and extends past it
1006 (goto-char sexpend)
1007 (setq sexpend (point-marker))
1008 (c-safe (backward-sexp 1))
1009 (setq sexpbeg (point))))
1010 (if (and sexpbeg (< sexpbeg fence))
1011 (setq sexpbeg fence)))
1012 ;; check to see if the next line starts a
1013 ;; comment-only line
1014 (save-excursion
1015 (forward-line 1)
1016 (skip-chars-forward " \t")
1017 (if (looking-at c-comment-start-regexp)
1018 (setq sexpbeg (c-point 'bol))))
1019 ;; If that sexp ends within the region, indent it all at
1020 ;; once, fast.
1021 (condition-case nil
1022 (if (and sexpend
1023 (> sexpend nextline)
1024 (<= sexpend endmark))
1025 (progn
1026 (goto-char sexpbeg)
1027 (c-indent-exp 'shutup)
1028 (c-progress-update)
1029 (goto-char sexpend)))
1030 (error
1031 (goto-char sexpbeg)
1032 (c-indent-line)))
1033 ;; Move to following line and try again.
1034 (and sexpend
1035 (markerp sexpend)
1036 (set-marker sexpend nil))
1037 (forward-line 1)
1038 (setq fence (point))))))
1039 (set-marker endmark nil)
1040 (c-progress-fini 'c-indent-region)
1041 (c-echo-parsing-error)
1042 ))))
1043
1044(defun c-mark-function ()
1045 "Put mark at end of a C, C++, or Objective-C defun, point at beginning."
1046 (interactive)
1047 (let ((here (point))
1048 ;; there should be a c-point position for 'eod
1049 (eod (save-excursion (end-of-defun) (point)))
1050 (state (c-parse-state))
1051 brace)
1052 (while state
1053 (setq brace (car state))
1054 (if (consp brace)
1055 (goto-char (cdr brace))
1056 (goto-char brace))
1057 (setq state (cdr state)))
1058 (if (eq (char-after) ?{)
1059 (progn
1060 (forward-line -1)
1061 (while (not (or (bobp)
1062 (looking-at "[ \t]*$")))
1063 (forward-line -1)))
1064 (forward-line 1)
1065 (skip-chars-forward " \t\n"))
1066 (push-mark here)
1067 (push-mark eod nil t)))
1068
1069
1070;; for progress reporting
1071(defvar c-progress-info nil)
1072
1073(defun c-progress-init (start end context)
1074 ;; start the progress update messages. if this emacs doesn't have a
1075 ;; built-in timer, just be dumb about it
1076 (if (not (fboundp 'current-time))
1077 (message "indenting region... (this may take a while)")
1078 ;; if progress has already been initialized, do nothing. otherwise
1079 ;; initialize the counter with a vector of:
1080 ;; [start end lastsec context]
1081 (if c-progress-info
1082 ()
1083 (setq c-progress-info (vector start
1084 (save-excursion
1085 (goto-char end)
1086 (point-marker))
1087 (nth 1 (current-time))
1088 context))
1089 (message "indenting region..."))))
1090
1091(defun c-progress-update ()
1092 ;; update progress
1093 (if (not (and c-progress-info c-progress-interval))
1094 nil
1095 (let ((now (nth 1 (current-time)))
1096 (start (aref c-progress-info 0))
1097 (end (aref c-progress-info 1))
1098 (lastsecs (aref c-progress-info 2)))
1099 ;; should we update? currently, update happens every 2 seconds,
1100 ;; what's the right value?
1101 (if (< c-progress-interval (- now lastsecs))
1102 (progn
1103 (message "indenting region... (%d%% complete)"
1104 (/ (* 100 (- (point) start)) (- end start)))
1105 (aset c-progress-info 2 now)))
1106 )))
1107
1108(defun c-progress-fini (context)
1109 ;; finished
1110 (if (or (eq context (aref c-progress-info 3))
1111 (eq context t))
1112 (progn
1113 (set-marker (aref c-progress-info 1) nil)
1114 (setq c-progress-info nil)
1115 (message "indenting region...done"))))
1116
1117
1118
1119;;; This page handles insertion and removal of backslashes for C macros.
1120
1121(defun c-backslash-region (from to delete-flag)
1122 "Insert, align, or delete end-of-line backslashes on the lines in the region.
1123With no argument, inserts backslashes and aligns existing backslashes.
1124With an argument, deletes the backslashes.
1125
1126This function does not modify blank lines at the start of the region.
1127If the region ends at the start of a line, it always deletes the
1128backslash (if any) at the end of the previous line.
1129
1130You can put the region around an entire macro definition and use this
1131command to conveniently insert and align the necessary backslashes."
1132 (interactive "r\nP")
1133 (save-excursion
1134 (goto-char from)
1135 (let ((column c-backslash-column)
1136 (endmark (make-marker)))
1137 (move-marker endmark to)
1138 ;; Compute the smallest column number past the ends of all the lines.
1139 (if (not delete-flag)
1140 (while (< (point) to)
1141 (end-of-line)
1142 (if (eq (char-before) ?\\)
1143 (progn (forward-char -1)
1144 (skip-chars-backward " \t")))
1145 (setq column (max column (1+ (current-column))))
1146 (forward-line 1)))
1147 ;; Adjust upward to a tab column, if that doesn't push past the margin.
1148 (if (> (% column tab-width) 0)
1149 (let ((adjusted (* (/ (+ column tab-width -1) tab-width) tab-width)))
1150 (if (< adjusted (window-width))
1151 (setq column adjusted))))
1152 ;; Don't modify blank lines at start of region.
1153 (goto-char from)
1154 (while (and (< (point) endmark) (eolp))
1155 (forward-line 1))
1156 ;; Add or remove backslashes on all the lines.
1157 (while (< (point) endmark)
1158 (if (and (not delete-flag)
1159 ;; Un-backslashify the last line
1160 ;; if the region ends right at the start of the next line.
1161 (save-excursion
1162 (forward-line 1)
1163 (< (point) endmark)))
1164 (c-append-backslash column)
1165 (c-delete-backslash))
1166 (forward-line 1))
1167 (move-marker endmark nil)))
1168 (c-keep-region-active))
1169
1170(defun c-append-backslash (column)
1171 (end-of-line)
1172 (if (eq (char-before) ?\\)
1173 (progn (forward-char -1)
1174 (delete-horizontal-space)
1175 (indent-to column))
1176 (indent-to column)
1177 (insert "\\")))
1178
1179(defun c-delete-backslash ()
1180 (end-of-line)
1181 (or (bolp)
1182 (progn
1183 (forward-char -1)
1184 (if (looking-at "\\\\")
1185 (delete-region (1+ (point))
1186 (progn (skip-chars-backward " \t") (point)))))))
1187
1188
1189(defun c-fill-paragraph (&optional arg)
1190 "Like \\[fill-paragraph] but handles C and C++ style comments.
1191If any of the current line is a comment or within a comment,
1192fill the comment or the paragraph of it that point is in,
1193preserving the comment indentation or line-starting decorations.
1194
1195Optional prefix ARG means justify paragraph as well."
1196 (interactive "P")
1197 (let* (comment-start-place
1198 (first-line
1199 ;; Check for obvious entry to comment.
1200 (save-excursion
1201 (beginning-of-line)
1202 (skip-chars-forward " \t\n")
1203 (and (looking-at comment-start-skip)
1204 (setq comment-start-place (point)))))
1205 (re1 "\\|[ \t]*/\\*[ \t]*$\\|[ \t]*\\*/[ \t]*$\\|[ \t/*]*$"))
1206 (if (and c-double-slash-is-comments-p
1207 (save-excursion
1208 (beginning-of-line)
1209 (looking-at ".*//")))
1210 (let ((fill-prefix fill-prefix)
1211 ;; Lines containing just a comment start or just an end
1212 ;; should not be filled into paragraphs they are next
1213 ;; to.
1214 (paragraph-start (concat paragraph-start re1))
1215 (paragraph-separate (concat paragraph-separate re1)))
1216 (save-excursion
1217 (beginning-of-line)
1218 ;; Move up to first line of this comment.
1219 (while (and (not (bobp))
1220 (looking-at "[ \t]*//[ \t]*[^ \t\n]"))
1221 (forward-line -1))
1222 (if (not (looking-at ".*//[ \t]*[^ \t\n]"))
1223 (forward-line 1))
1224 ;; Find the comment start in this line.
1225 (re-search-forward "[ \t]*//[ \t]*")
1226 ;; Set the fill-prefix to be what all lines except the first
1227 ;; should start with. But do not alter a user set fill-prefix.
1228 (if (null fill-prefix)
1229 (setq fill-prefix (buffer-substring (match-beginning 0)
1230 (match-end 0))))
1231 (save-restriction
1232 ;; Narrow down to just the lines of this comment.
1233 (narrow-to-region (c-point 'bol)
1234 (save-excursion
1235 (forward-line 1)
1236 (while (looking-at fill-prefix)
1237 (forward-line 1))
1238 (point)))
1239 (fill-paragraph arg)
1240 t)))
1241 ;; else C style comments
1242 (if (or first-line
1243 ;; t if we enter a comment between start of function and
1244 ;; this line.
1245 (eq (c-in-literal) 'c)
1246 ;; t if this line contains a comment starter.
1247 (setq first-line
1248 (save-excursion
1249 (beginning-of-line)
1250 (prog1
1251 (re-search-forward comment-start-skip
1252 (save-excursion (end-of-line)
1253 (point))
1254 t)
1255 (setq comment-start-place (point))))))
1256 ;; Inside a comment: fill one comment paragraph.
1257 (let ((fill-prefix
1258 ;; The prefix for each line of this paragraph
1259 ;; is the appropriate part of the start of this line,
1260 ;; up to the column at which text should be indented.
1261 (save-excursion
1262 (beginning-of-line)
1263 (if (looking-at "[ \t]*/\\*.*\\*/")
1264 (progn (re-search-forward comment-start-skip)
1265 (make-string (current-column) ?\ ))
1266 (if first-line (forward-line 1))
1267
1268 (let ((line-width (progn (end-of-line) (current-column))))
1269 (beginning-of-line)
1270 (prog1
1271 (buffer-substring
1272 (point)
1273
1274 ;; How shall we decide where the end of the
1275 ;; fill-prefix is?
1276 (progn
1277 (beginning-of-line)
1278 (skip-chars-forward " \t*" (c-point 'eol))
1279 ;; kludge alert, watch out for */, in
1280 ;; which case fill-prefix should *not*
1281 ;; be "*"!
1282 (if (and (eq (char-after) ?/)
1283 (eq (char-before) ?*))
1284 (forward-char -1))
1285 (point)))
1286
1287 ;; If the comment is only one line followed
1288 ;; by a blank line, calling move-to-column
1289 ;; above may have added some spaces and tabs
1290 ;; to the end of the line; the fill-paragraph
1291 ;; function will then delete it and the
1292 ;; newline following it, so we'll lose a
1293 ;; blank line when we shouldn't. So delete
1294 ;; anything move-to-column added to the end
1295 ;; of the line. We record the line width
1296 ;; instead of the position of the old line
1297 ;; end because move-to-column might break a
1298 ;; tab into spaces, and the new characters
1299 ;; introduced there shouldn't be deleted.
1300
1301 ;; If you can see a better way to do this,
1302 ;; please make the change. This seems very
1303 ;; messy to me.
1304 (delete-region (progn (move-to-column line-width)
1305 (point))
1306 (progn (end-of-line) (point))))))))
1307
1308 ;; Lines containing just a comment start or just an end
1309 ;; should not be filled into paragraphs they are next
1310 ;; to.
1311 (paragraph-start (concat paragraph-start re1))
1312 (paragraph-separate (concat paragraph-separate re1))
1313 (chars-to-delete 0)
1314 )
1315 (save-restriction
1316 ;; Don't fill the comment together with the code
1317 ;; following it. So temporarily exclude everything
1318 ;; before the comment start, and everything after the
1319 ;; line where the comment ends. If comment-start-place
1320 ;; is non-nil, the comment starter is there. Otherwise,
1321 ;; point is inside the comment.
1322 (narrow-to-region (save-excursion
1323 (if comment-start-place
1324 (goto-char comment-start-place)
1325 (search-backward "/*"))
1326 (if (and (not c-hanging-comment-starter-p)
1327 (looking-at
1328 (concat c-comment-start-regexp
1329 "[ \t]*$")))
1330 (forward-line 1))
1331 ;; Protect text before the comment
1332 ;; start by excluding it. Add
1333 ;; spaces to bring back proper
1334 ;; indentation of that point.
1335 (let ((column (current-column)))
1336 (prog1 (point)
1337 (setq chars-to-delete column)
1338 (insert-char ?\ column))))
1339 (save-excursion
1340 (if comment-start-place
1341 (goto-char (+ comment-start-place 2)))
1342 (search-forward "*/" nil 'move)
1343 (forward-line 1)
1344 (point)))
1345 (fill-paragraph arg)
1346 (save-excursion
1347 ;; Delete the chars we inserted to avoid clobbering
1348 ;; the stuff before the comment start.
1349 (goto-char (point-min))
1350 (if (> chars-to-delete 0)
1351 (delete-region (point) (+ (point) chars-to-delete)))
1352 ;; Find the comment ender (should be on last line of
1353 ;; buffer, given the narrowing) and don't leave it on
1354 ;; its own line, unless that's the style that's desired.
1355 (goto-char (point-max))
1356 (forward-line -1)
1357 (search-forward "*/" nil 'move)
1358 (beginning-of-line)
1359 (if (and c-hanging-comment-ender-p
1360 (looking-at "[ \t]*\\*/"))
1361 ;(delete-indentation)))))
1362 (let ((fill-column (+ fill-column 9999)))
1363 (forward-line -1)
1364 (fill-region-as-paragraph (point) (point-max))))))
1365 t)))))
1366
1367
1368(provide 'cc-cmds)
1369;;; cc-cmds.el ends here
diff --git a/lisp/progmodes/cc-compat.el b/lisp/progmodes/cc-compat.el
new file mode 100644
index 00000000000..3415515bfb8
--- /dev/null
+++ b/lisp/progmodes/cc-compat.el
@@ -0,0 +1,149 @@
1;;; cc-compat.el --- cc-mode compatibility with c-mode.el confusion
2
3;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
4
5;; Author: 1994-1997 Barry A. Warsaw
6;; Maintainer: cc-mode-help@python.org
7;; Created: August 1994, split from cc-mode.el
8;; Version: 5.12
9;; Keywords: c languages oop
10
11;; This file is part of GNU Emacs.
12
13;; GNU Emacs is free software; you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
15;; the Free Software Foundation; either version 2, or (at your option)
16;; any later version.
17
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
24;; along with GNU Emacs; see the file COPYING. If not, write to the
25;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
26;; Boston, MA 02111-1307, USA.
27
28;;; Commentary:
29;;
30;; Boring old c-mode.el (BOCM) is confusion and brain melt. cc-mode.el
31;; is clarity of thought and purity of chi. If you are still unwilling
32;; to accept enlightenment, this might help, or it may prolong your
33;; agony.
34;;
35;; To use, add the following to your c-mode-hook:
36;;
37;; (require 'cc-compat)
38;; (c-set-style "BOCM")
39
40;;; Code:
41
42(eval-when-compile
43 (require 'cc-styles)
44 (require 'cc-engine))
45
46
47;; In case c-mode.el isn't loaded
48(defvar c-indent-level 2
49 "*Indentation of C statements with respect to containing block.")
50(defvar c-brace-imaginary-offset 0
51 "*Imagined indentation of a C open brace that actually follows a statement.")
52(defvar c-brace-offset 0
53 "*Extra indentation for braces, compared with other text in same context.")
54(defvar c-argdecl-indent 5
55 "*Indentation level of declarations of C function arguments.")
56(defvar c-label-offset -2
57 "*Offset of C label lines and case statements relative to usual indentation.")
58(defvar c-continued-statement-offset 2
59 "*Extra indent for lines not starting new statements.")
60(defvar c-continued-brace-offset 0
61 "*Extra indent for substatements that start with open-braces.
62This is in addition to c-continued-statement-offset.")
63
64
65
66;; these offsets are taken by brute force testing c-mode.el, since
67;; there's no logic to what it does.
68(let* ((offsets '(c-offsets-alist .
69 ((defun-block-intro . cc-block-intro-offset)
70 (statement-block-intro . cc-block-intro-offset)
71 (defun-open . 0)
72 (class-open . 0)
73 (inline-open . c-brace-offset)
74 (block-open . c-brace-offset)
75 (block-close . cc-block-close-offset)
76 (brace-list-open . c-brace-offset)
77 (substatement-open . cc-substatement-open-offset)
78 (substatement . c-continued-statement-offset)
79 (knr-argdecl-intro . c-argdecl-indent)
80 (case-label . c-label-offset)
81 (access-label . c-label-offset)
82 (label . c-label-offset)
83 ))))
84 (c-add-style "BOCM" offsets))
85
86
87(defun cc-block-intro-offset (langelem)
88 ;; taken directly from calculate-c-indent confusion
89 (save-excursion
90 (c-backward-syntactic-ws)
91 (if (eq (char-before) ?{)
92 (forward-char -1)
93 (goto-char (cdr langelem)))
94 (let* ((curcol (save-excursion
95 (goto-char (cdr langelem))
96 (current-column)))
97 (bocm-lossage
98 ;; If no previous statement, indent it relative to line
99 ;; brace is on. For open brace in column zero, don't let
100 ;; statement start there too. If c-indent-level is zero,
101 ;; use c-brace-offset + c-continued-statement-offset
102 ;; instead. For open-braces not the first thing in a line,
103 ;; add in c-brace-imaginary-offset.
104 (+ (if (and (bolp) (zerop c-indent-level))
105 (+ c-brace-offset c-continued-statement-offset)
106 c-indent-level)
107 ;; Move back over whitespace before the openbrace. If
108 ;; openbrace is not first nonwhite thing on the line,
109 ;; add the c-brace-imaginary-offset.
110 (progn (skip-chars-backward " \t")
111 (if (bolp) 0 c-brace-imaginary-offset))
112 ;; If the openbrace is preceded by a parenthesized exp,
113 ;; move to the beginning of that; possibly a different
114 ;; line
115 (progn
116 (if (eq (char-before) ?\))
117 (forward-sexp -1))
118 ;; Get initial indentation of the line we are on.
119 (current-indentation)))))
120 (- bocm-lossage curcol))))
121
122
123(defun cc-block-close-offset (langelem)
124 (save-excursion
125 (let* ((here (point))
126 bracep
127 (curcol (progn
128 (goto-char (cdr langelem))
129 (current-column)))
130 (bocm-lossage (progn
131 (goto-char (cdr langelem))
132 (if (eq (char-after) ?{)
133 (setq bracep t)
134 (goto-char here)
135 (beginning-of-line)
136 (backward-up-list 1)
137 (forward-char 1)
138 (c-forward-syntactic-ws))
139 (current-column))))
140 (- bocm-lossage curcol
141 (if bracep 0 c-indent-level)))))
142
143
144(defun cc-substatement-open-offset (langelem)
145 (+ c-continued-statement-offset c-continued-brace-offset))
146
147
148(provide 'cc-compat)
149;;; cc-compat.el ends here
diff --git a/lisp/progmodes/cc-defs.el b/lisp/progmodes/cc-defs.el
new file mode 100644
index 00000000000..354ba3508ad
--- /dev/null
+++ b/lisp/progmodes/cc-defs.el
@@ -0,0 +1,185 @@
1;;; cc-defs.el --- definitions for CC Mode
2
3;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
4
5;; Authors: 1992-1997 Barry A. Warsaw
6;; 1987 Dave Detlefs and Stewart Clamen
7;; 1985 Richard M. Stallman
8;; Maintainer: cc-mode-help@python.org
9;; Created: 22-Apr-1997 (split from cc-mode.el)
10;; Version: 5.12
11;; Keywords: c languages oop
12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software; you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation; either version 2, or (at your option)
18;; any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs; see the file COPYING. If not, write to the
27;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28;; Boston, MA 02111-1307, USA.
29
30
31;; Figure out what features this Emacs has
32(defconst c-emacs-features
33 (let ((infodock-p (boundp 'infodock-version))
34 (comments
35 ;; XEmacs 19 and beyond use 8-bit modify-syntax-entry flags.
36 ;; Emacs 19 uses a 1-bit flag. We will have to set up our
37 ;; syntax tables differently to handle this.
38 (let ((table (copy-syntax-table))
39 entry)
40 (modify-syntax-entry ?a ". 12345678" table)
41 (cond
42 ;; XEmacs 19, and beyond Emacs 19.34
43 ((arrayp table)
44 (setq entry (aref table ?a))
45 ;; In Emacs, table entries are cons cells
46 (if (consp entry) (setq entry (car entry))))
47 ;; XEmacs 20
48 ((fboundp 'get-char-table) (setq entry (get-char-table ?a table)))
49 ;; before and including Emacs 19.34
50 ((and (fboundp 'char-table-p)
51 (char-table-p table))
52 (setq entry (car (char-table-range table [?a]))))
53 ;; incompatible
54 (t (error "CC Mode is incompatible with this version of Emacs")))
55 (if (= (logand (lsh entry -16) 255) 255)
56 '8-bit
57 '1-bit))))
58 (if infodock-p
59 (list comments 'infodock)
60 (list comments)))
61 "A list of features extant in the Emacs you are using.
62There are many flavors of Emacs out there, each with different
63features supporting those needed by CC Mode. Here's the current
64supported list, along with the values for this variable:
65
66 XEmacs 19: (8-bit)
67 XEmacs 20: (8-bit)
68 Emacs 19: (1-bit)
69
70Infodock (based on XEmacs) has an additional symbol on this list:
71'infodock.")
72
73
74
75(defsubst c-point (position)
76 ;; Returns the value of point at certain commonly referenced POSITIONs.
77 ;; POSITION can be one of the following symbols:
78 ;;
79 ;; bol -- beginning of line
80 ;; eol -- end of line
81 ;; bod -- beginning of defun
82 ;; boi -- back to indentation
83 ;; ionl -- indentation of next line
84 ;; iopl -- indentation of previous line
85 ;; bonl -- beginning of next line
86 ;; bopl -- beginning of previous line
87 ;;
88 ;; This function does not modify point or mark.
89 (let ((here (point)))
90 (cond
91 ((eq position 'bol) (beginning-of-line))
92 ((eq position 'eol) (end-of-line))
93 ((eq position 'bod)
94 (beginning-of-defun)
95 ;; if defun-prompt-regexp is non-nil, b-o-d won't leave us at
96 ;; the open brace.
97 (and defun-prompt-regexp
98 (looking-at defun-prompt-regexp)
99 (goto-char (match-end 0)))
100 )
101 ((eq position 'boi) (back-to-indentation))
102 ((eq position 'bonl) (forward-line 1))
103 ((eq position 'bopl) (forward-line -1))
104 ((eq position 'iopl)
105 (forward-line -1)
106 (back-to-indentation))
107 ((eq position 'ionl)
108 (forward-line 1)
109 (back-to-indentation))
110 (t (error "unknown buffer position requested: %s" position))
111 )
112 (prog1
113 (point)
114 (goto-char here))))
115
116(defmacro c-safe (&rest body)
117 ;; safely execute BODY, return nil if an error occurred
118 (` (condition-case nil
119 (progn (,@ body))
120 (error nil))))
121
122(defmacro c-add-syntax (symbol &optional relpos)
123 ;; a simple macro to append the syntax in symbol to the syntax list.
124 ;; try to increase performance by using this macro
125 (` (setq syntax (cons (cons (, symbol) (, relpos)) syntax))))
126
127(defsubst c-auto-newline ()
128 ;; if auto-newline feature is turned on, insert a newline character
129 ;; and return t, otherwise return nil.
130 (and c-auto-newline
131 (not (c-in-literal))
132 (not (newline))))
133
134(defsubst c-intersect-lists (list alist)
135 ;; return the element of ALIST that matches the first element found
136 ;; in LIST. Uses assq.
137 (let (match)
138 (while (and list
139 (not (setq match (assq (car list) alist))))
140 (setq list (cdr list)))
141 match))
142
143(defsubst c-lookup-lists (list alist1 alist2)
144 ;; first, find the first entry from LIST that is present in ALIST1,
145 ;; then find the entry in ALIST2 for that entry.
146 (assq (car (c-intersect-lists list alist1)) alist2))
147
148(defsubst c-langelem-col (langelem &optional preserve-point)
149 ;; convenience routine to return the column of langelem's relpos.
150 ;; Leaves point at the relpos unless preserve-point is non-nil.
151 (let ((here (point)))
152 (goto-char (cdr langelem))
153 (prog1 (current-column)
154 (if preserve-point
155 (goto-char here))
156 )))
157
158(defsubst c-update-modeline ()
159 ;; set the c-auto-hungry-string for the correct designation on the modeline
160 (setq c-auto-hungry-string
161 (if c-auto-newline
162 (if c-hungry-delete-key "/ah" "/a")
163 (if c-hungry-delete-key "/h" nil)))
164 (force-mode-line-update))
165
166(defsubst c-keep-region-active ()
167 ;; Do whatever is necessary to keep the region active in XEmacs.
168 ;; Ignore byte-compiler warnings you might see. This is not needed
169 ;; for Emacs.
170 (and (boundp 'zmacs-region-stays)
171 (setq zmacs-region-stays t)))
172
173(defsubst c-load-all ()
174 ;; make sure all necessary components of CC Mode are loaded in.
175 (require 'cc-vars)
176 (require 'cc-engine)
177 (require 'cc-langs)
178 (require 'cc-menus)
179 (require 'cc-align)
180 (require 'cc-styles)
181 (require 'cc-cmds))
182
183
184(provide 'cc-defs)
185;;; cc-defs.el ends here
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
new file mode 100644
index 00000000000..3ac0ed52b74
--- /dev/null
+++ b/lisp/progmodes/cc-engine.el
@@ -0,0 +1,1704 @@
1;;; cc-engine.el --- core syntax guessing engine for CC mode
2
3;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
4
5;; Authors: 1992-1997 Barry A. Warsaw
6;; 1987 Dave Detlefs and Stewart Clamen
7;; 1985 Richard M. Stallman
8;; Maintainer: cc-mode-help@python.org
9;; Created: 22-Apr-1997 (split from cc-mode.el)
10;; Version: 5.12
11;; Keywords: c languages oop
12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software; you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation; either version 2, or (at your option)
18;; any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs; see the file COPYING. If not, write to the
27;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28;; Boston, MA 02111-1307, USA.
29
30
31;; WARNING: Be *exceptionally* careful about modifications to this
32;; function! Much of CC Mode depends on this Doing The Right Thing.
33;; If you break it you will be sorry.
34
35(defun c-beginning-of-statement-1 (&optional lim)
36 ;; move to the start of the current statement, or the previous
37 ;; statement if already at the beginning of one.
38 (let ((firstp t)
39 (substmt-p t)
40 donep c-in-literal-cache
41 ;; KLUDGE ALERT: maybe-labelp is used to pass information
42 ;; between c-crosses-statement-barrier-p and
43 ;; c-beginning-of-statement-1. A better way should be
44 ;; implemented.
45 maybe-labelp saved
46 (last-begin (point)))
47 ;; first check for bare semicolon
48 (if (and (progn (c-backward-syntactic-ws lim)
49 (eq (char-before) ?\;))
50 (c-safe (progn (forward-char -1)
51 (setq saved (point))
52 t))
53 (progn (c-backward-syntactic-ws lim)
54 (memq (char-before) '(?\; ?{ ?} ?:)))
55 )
56 (setq last-begin saved)
57 (goto-char last-begin)
58 (while (not donep)
59 ;; stop at beginning of buffer
60 (if (bobp) (setq donep t)
61 ;; go backwards one balanced expression, but be careful of
62 ;; unbalanced paren being reached
63 (if (not (c-safe (progn (backward-sexp 1) t)))
64 (progn
65 (if firstp
66 (backward-up-list 1)
67 (goto-char last-begin))
68 ;; skip over any unary operators, or other special
69 ;; characters appearing at front of identifier
70 (save-excursion
71 (c-backward-syntactic-ws lim)
72 (skip-chars-backward "-+!*&:.~ \t\n")
73 (if (eq (char-before) ?\()
74 (setq last-begin (point))))
75 (goto-char last-begin)
76 (setq last-begin (point)
77 donep t)))
78
79 (setq maybe-labelp nil)
80 ;; see if we're in a literal. if not, then this bufpos may be
81 ;; a candidate for stopping
82 (cond
83 ;; CASE 0: did we hit the error condition above?
84 (donep)
85 ;; CASE 1: are we in a literal?
86 ((eq (c-in-literal lim) 'pound)
87 (beginning-of-line))
88 ;; CASE 2: some other kind of literal?
89 ((c-in-literal lim))
90 ;; CASE 3: are we looking at a conditional keyword?
91 ((or (looking-at c-conditional-key)
92 (and (eq (char-after) ?\()
93 (save-excursion
94 (forward-sexp 1)
95 (c-forward-syntactic-ws)
96 (not (eq (char-after) ?\;)))
97 (let ((here (point))
98 (foundp (progn
99 (c-backward-syntactic-ws lim)
100 (forward-word -1)
101 (and lim
102 (<= lim (point))
103 (not (c-in-literal lim))
104 (looking-at c-conditional-key)
105 ))))
106 ;; did we find a conditional?
107 (if (not foundp)
108 (goto-char here))
109 foundp)))
110 ;; are we in the middle of an else-if clause?
111 (if (save-excursion
112 (and (not substmt-p)
113 (c-safe (progn (forward-sexp -1) t))
114 (looking-at "\\<else\\>[ \t\n]+\\<if\\>")
115 (not (c-in-literal lim))))
116 (progn
117 (forward-sexp -1)
118 (c-backward-to-start-of-if lim)))
119 ;; are we sitting at an else clause, that we are not a
120 ;; substatement of?
121 (if (and (not substmt-p)
122 (looking-at "\\<else\\>[^_]"))
123 (c-backward-to-start-of-if lim))
124 ;; are we sitting at the while of a do-while?
125 (if (and (looking-at "\\<while\\>[^_]")
126 (c-backward-to-start-of-do lim))
127 (setq substmt-p nil))
128 (setq last-begin (point)
129 donep substmt-p))
130 ;; CASE 4: are we looking at a label?
131 ((looking-at c-label-key))
132 ;; CASE 5: is this the first time we're checking?
133 (firstp (setq firstp nil
134 substmt-p (not (c-crosses-statement-barrier-p
135 (point) last-begin))
136 last-begin (point)))
137 ;; CASE 6: have we crossed a statement barrier?
138 ((c-crosses-statement-barrier-p (point) last-begin)
139 (setq donep t))
140 ;; CASE 7: ignore labels
141 ((and maybe-labelp
142 (or (and c-access-key (looking-at c-access-key))
143 ;; with switch labels, we have to go back further
144 ;; to try to pick up the case or default
145 ;; keyword. Potential bogosity alert: we assume
146 ;; `case' or `default' is first thing on line
147 (let ((here (point)))
148 (beginning-of-line)
149 (c-forward-syntactic-ws)
150 (if (looking-at c-switch-label-key)
151 t
152 (goto-char here)
153 nil))
154 (looking-at c-label-key))))
155 ;; CASE 8: ObjC or Java method def
156 ((and c-method-key
157 (setq last-begin (c-in-method-def-p)))
158 (setq donep t))
159 ;; CASE 9: nothing special
160 (t (setq last-begin (point)))
161 ))))
162 (goto-char last-begin)
163 ;; we always do want to skip over non-whitespace modifier
164 ;; characters that didn't get skipped above
165 (skip-chars-backward "-+!*&:.~" (c-point 'boi))))
166
167(defun c-end-of-statement-1 ()
168 (condition-case ()
169 (progn
170 (while (and (not (eobp))
171 (let ((beg (point)))
172 (forward-sexp 1)
173 (let ((end (point)))
174 (save-excursion
175 (goto-char beg)
176 (not (re-search-forward "[;{}]" end t)))))))
177 (re-search-backward "[;}]")
178 (forward-char 1))
179 (error
180 (let ((beg (point)))
181 (backward-up-list -1)
182 (let ((end (point)))
183 (goto-char beg)
184 (search-forward ";" end 'move))))))
185
186
187
188(defun c-crosses-statement-barrier-p (from to)
189 ;; Does buffer positions FROM to TO cross a C statement boundary?
190 (let ((here (point))
191 (lim from)
192 crossedp)
193 (condition-case ()
194 (progn
195 (goto-char from)
196 (while (and (not crossedp)
197 (< (point) to))
198 (skip-chars-forward "^;{}:" to)
199 (if (not (c-in-literal lim))
200 (progn
201 (if (memq (char-after) '(?\; ?{ ?}))
202 (setq crossedp t)
203 (if (eq (char-after) ?:)
204 (setq maybe-labelp t))
205 (forward-char 1))
206 (setq lim (point)))
207 (forward-char 1))))
208 (error (setq crossedp nil)))
209 (goto-char here)
210 crossedp))
211
212
213;; Skipping of "syntactic whitespace", defined as lexical whitespace,
214;; C and C++ style comments, and preprocessor directives. Search no
215;; farther back or forward than optional LIM. If LIM is omitted,
216;; `beginning-of-defun' is used for backward skipping, point-max is
217;; used for forward skipping.
218
219(defun c-forward-syntactic-ws (&optional lim)
220 ;; Forward skip of syntactic whitespace for Emacs 19.
221 (save-restriction
222 (let* ((lim (or lim (point-max)))
223 (here lim)
224 (hugenum (point-max)))
225 (narrow-to-region lim (point))
226 (while (/= here (point))
227 (setq here (point))
228 (forward-comment hugenum)
229 ;; skip preprocessor directives
230 (if (and (eq (char-after) ?#)
231 (= (c-point 'boi) (point)))
232 (end-of-line)
233 )))))
234
235(defun c-backward-syntactic-ws (&optional lim)
236 ;; Backward skip over syntactic whitespace for Emacs 19.
237 (save-restriction
238 (let* ((lim (or lim (c-point 'bod)))
239 (here lim)
240 (hugenum (- (point-max))))
241 (if (< lim (point))
242 (progn
243 (narrow-to-region lim (point))
244 (while (/= here (point))
245 (setq here (point))
246 (forward-comment hugenum)
247 (if (eq (c-in-literal lim) 'pound)
248 (beginning-of-line))
249 )))
250 )))
251
252
253;; Return `c' if in a C-style comment, `c++' if in a C++ style
254;; comment, `string' if in a string literal, `pound' if on a
255;; preprocessor line, or nil if not in a comment at all. Optional LIM
256;; is used as the backward limit of the search. If omitted, or nil,
257;; `beginning-of-defun' is used."
258
259(defun c-in-literal (&optional lim)
260 ;; Determine if point is in a C++ literal. we cache the last point
261 ;; calculated if the cache is enabled
262 (if (and (boundp 'c-in-literal-cache)
263 c-in-literal-cache
264 (= (point) (aref c-in-literal-cache 0)))
265 (aref c-in-literal-cache 1)
266 (let ((rtn (save-excursion
267 (let* ((lim (or lim (c-point 'bod)))
268 (here (point))
269 (state (parse-partial-sexp lim (point))))
270 (cond
271 ((nth 3 state) 'string)
272 ((nth 4 state) (if (nth 7 state) 'c++ 'c))
273 ((progn
274 (goto-char here)
275 (beginning-of-line)
276 (looking-at "[ \t]*#"))
277 'pound)
278 (t nil))))))
279 ;; cache this result if the cache is enabled
280 (and (boundp 'c-in-literal-cache)
281 (setq c-in-literal-cache (vector (point) rtn)))
282 rtn)))
283
284
285;; utilities for moving and querying around syntactic elements
286(defvar c-parsing-error nil)
287
288(defun c-parse-state ()
289 ;; Finds and records all open parens between some important point
290 ;; earlier in the file and point.
291 ;;
292 ;; if there's a state cache, return it
293 (setq c-parsing-error nil)
294 (if (boundp 'c-state-cache) c-state-cache
295 (let* (at-bob
296 (pos (save-excursion
297 ;; go back 2 bods, but ignore any bogus positions
298 ;; returned by beginning-of-defun (i.e. open paren
299 ;; in column zero)
300 (let ((cnt 2))
301 (while (not (or at-bob (zerop cnt)))
302 (beginning-of-defun)
303 (if (eq (char-after) ?\{)
304 (setq cnt (1- cnt)))
305 (if (bobp)
306 (setq at-bob t))))
307 (point)))
308 (here (save-excursion
309 ;;(skip-chars-forward " \t}")
310 (point)))
311 (last-bod pos) (last-pos pos)
312 placeholder state sexp-end)
313 ;; cache last bod position
314 (while (catch 'backup-bod
315 (setq state nil)
316 (while (and pos (< pos here))
317 (setq last-pos pos)
318 (if (and (setq pos (c-safe (scan-lists pos 1 -1)))
319 (<= pos here))
320 (progn
321 (setq sexp-end (c-safe (scan-sexps (1- pos) 1)))
322 (if (and sexp-end
323 (<= sexp-end here))
324 ;; we want to record both the start and end
325 ;; of this sexp, but we only want to record
326 ;; the last-most of any of them before here
327 (progn
328 (if (eq (char-after (1- pos)) ?\{)
329 (setq state (cons (cons (1- pos) sexp-end)
330 (if (consp (car state))
331 (cdr state)
332 state))))
333 (setq pos sexp-end))
334 ;; we're contained in this sexp so put pos on
335 ;; front of list
336 (setq state (cons (1- pos) state))))
337 ;; something bad happened. check to see if we
338 ;; crossed an unbalanced close brace. if so, we
339 ;; didn't really find the right `important bufpos'
340 ;; so lets back up and try again
341 (if (and (not pos) (not at-bob)
342 (setq placeholder
343 (c-safe (scan-lists last-pos 1 1)))
344 ;;(char-after (1- placeholder))
345 (<= placeholder here)
346 (eq (char-after (1- placeholder)) ?\}))
347 (while t
348 (setq last-bod (c-safe (scan-lists last-bod -1 1)))
349 (if (not last-bod)
350 (progn
351 ;; bogus, but what can we do here?
352 (setq c-parsing-error (1- placeholder))
353 (throw 'backup-bod nil))
354 (setq at-bob (= last-bod (point-min))
355 pos last-bod)
356 (if (= (char-after last-bod) ?\{)
357 (throw 'backup-bod t)))
358 )) ;end-if
359 )) ;end-while
360 nil))
361 state)))
362
363(defun c-whack-state (bufpos state)
364 ;; whack off any state information that appears on STATE which lies
365 ;; after the bounds of BUFPOS.
366 (let (newstate car)
367 (while state
368 (setq car (car state)
369 state (cdr state))
370 (if (consp car)
371 ;; just check the car, because in a balanced brace
372 ;; expression, it must be impossible for the corresponding
373 ;; close brace to be before point, but the open brace to be
374 ;; after.
375 (if (<= bufpos (car car))
376 nil ; whack it off
377 ;; its possible that the open brace is before bufpos, but
378 ;; the close brace is after. In that case, convert this
379 ;; to a non-cons element.
380 (if (<= bufpos (cdr car))
381 (setq newstate (append newstate (list (car car))))
382 ;; we know that both the open and close braces are
383 ;; before bufpos, so we also know that everything else
384 ;; on state is before bufpos, so we can glom up the
385 ;; whole thing and exit.
386 (setq newstate (append newstate (list car) state)
387 state nil)))
388 (if (<= bufpos car)
389 nil ; whack it off
390 ;; it's before bufpos, so everything else should too
391 (setq newstate (append newstate (list car) state)
392 state nil))))
393 newstate))
394
395(defun c-hack-state (bufpos which state)
396 ;; Using BUFPOS buffer position, and WHICH (must be 'open or
397 ;; 'close), hack the c-parse-state STATE and return the results.
398 (if (eq which 'open)
399 (let ((car (car state)))
400 (if (or (null car)
401 (consp car)
402 (/= bufpos car))
403 (cons bufpos state)
404 state))
405 (if (not (eq which 'close))
406 (error "c-hack-state, bad argument: %s" which))
407 ;; 'close brace
408 (let ((car (car state))
409 (cdr (cdr state)))
410 (if (consp car)
411 (setq car (car cdr)
412 cdr (cdr cdr)))
413 ;; TBD: is this test relevant???
414 (if (consp car)
415 state ;on error, don't change
416 ;; watch out for balanced expr already on cdr of list
417 (cons (cons car bufpos)
418 (if (consp (car cdr))
419 (cdr cdr) cdr))
420 ))))
421
422(defun c-adjust-state (from to shift state)
423 ;; Adjust all points in state that lie in the region FROM..TO by
424 ;; SHIFT amount (as would be returned by c-indent-line).
425 (mapcar
426 (function
427 (lambda (e)
428 (if (consp e)
429 (let ((car (car e))
430 (cdr (cdr e)))
431 (if (and (<= from car) (< car to))
432 (setcar e (+ shift car)))
433 (if (and (<= from cdr) (< cdr to))
434 (setcdr e (+ shift cdr))))
435 (if (and (<= from e) (< e to))
436 (setq e (+ shift e))))
437 e))
438 state))
439
440
441(defun c-beginning-of-inheritance-list (&optional lim)
442 ;; Go to the first non-whitespace after the colon that starts a
443 ;; multiple inheritance introduction. Optional LIM is the farthest
444 ;; back we should search.
445 (let ((lim (or lim (c-point 'bod)))
446 (placeholder (progn
447 (back-to-indentation)
448 (point))))
449 (c-backward-syntactic-ws lim)
450 (while (and (> (point) lim)
451 (memq (char-before) '(?, ?:))
452 (progn
453 (beginning-of-line)
454 (setq placeholder (point))
455 (skip-chars-forward " \t")
456 (not (looking-at c-class-key))
457 ))
458 (c-backward-syntactic-ws lim))
459 (goto-char placeholder)
460 (skip-chars-forward "^:" (c-point 'eol))))
461
462(defun c-beginning-of-macro (&optional lim)
463 ;; Go to the beginning of the macro. Right now we don't support
464 ;; multi-line macros too well
465 (back-to-indentation))
466
467(defun c-in-method-def-p ()
468 ;; Return nil if we aren't in a method definition, otherwise the
469 ;; position of the initial [+-].
470 (save-excursion
471 (beginning-of-line)
472 (and c-method-key
473 (looking-at c-method-key)
474 (point))
475 ))
476
477(defun c-just-after-func-arglist-p (&optional containing)
478 ;; Return t if we are between a function's argument list closing
479 ;; paren and its opening brace. Note that the list close brace
480 ;; could be followed by a "const" specifier or a member init hanging
481 ;; colon. Optional CONTAINING is position of containing s-exp open
482 ;; brace. If not supplied, point is used as search start.
483 (save-excursion
484 (c-backward-syntactic-ws)
485 (let ((checkpoint (or containing (point))))
486 (goto-char checkpoint)
487 ;; could be looking at const specifier
488 (if (and (eq (char-before) ?t)
489 (forward-word -1)
490 (looking-at "\\<const\\>"))
491 (c-backward-syntactic-ws)
492 ;; otherwise, we could be looking at a hanging member init
493 ;; colon
494 (goto-char checkpoint)
495 (if (and (eq (char-before) ?:)
496 (progn
497 (forward-char -1)
498 (c-backward-syntactic-ws)
499 (looking-at "[ \t\n]*:\\([^:]+\\|$\\)")))
500 nil
501 (goto-char checkpoint))
502 )
503 (and (eq (char-before) ?\))
504 ;; check if we are looking at a method def
505 (or (not c-method-key)
506 (progn
507 (forward-sexp -1)
508 (forward-char -1)
509 (c-backward-syntactic-ws)
510 (not (or (memq (char-before) '(?- ?+))
511 ;; or a class category
512 (progn
513 (forward-sexp -2)
514 (looking-at c-class-key))
515 )))))
516 )))
517
518;; defuns to look backwards for things
519(defun c-backward-to-start-of-do (&optional lim)
520 ;; Move to the start of the last "unbalanced" do expression.
521 ;; Optional LIM is the farthest back to search. If none is found,
522 ;; nil is returned and point is left unchanged, otherwise t is returned.
523 (let ((do-level 1)
524 (case-fold-search nil)
525 (lim (or lim (c-point 'bod)))
526 (here (point))
527 foundp)
528 (while (not (zerop do-level))
529 ;; we protect this call because trying to execute this when the
530 ;; while is not associated with a do will throw an error
531 (condition-case nil
532 (progn
533 (backward-sexp 1)
534 (cond
535 ((memq (c-in-literal lim) '(c c++)))
536 ((looking-at "while\\b[^_]")
537 (setq do-level (1+ do-level)))
538 ((looking-at "do\\b[^_]")
539 (if (zerop (setq do-level (1- do-level)))
540 (setq foundp t)))
541 ((<= (point) lim)
542 (setq do-level 0)
543 (goto-char lim))))
544 (error
545 (goto-char lim)
546 (setq do-level 0))))
547 (if (not foundp)
548 (goto-char here))
549 foundp))
550
551(defun c-backward-to-start-of-if (&optional lim)
552 ;; Move to the start of the last "unbalanced" if and return t. If
553 ;; none is found, and we are looking at an if clause, nil is
554 ;; returned. If none is found and we are looking at an else clause,
555 ;; an error is thrown.
556 (let ((if-level 1)
557 (here (c-point 'bol))
558 (case-fold-search nil)
559 (lim (or lim (c-point 'bod)))
560 (at-if (looking-at "if\\b[^_]")))
561 (catch 'orphan-if
562 (while (and (not (bobp))
563 (not (zerop if-level)))
564 (c-backward-syntactic-ws)
565 (condition-case nil
566 (backward-sexp 1)
567 (error
568 (if at-if
569 (throw 'orphan-if nil)
570 (error "No matching `if' found for `else' on line %d."
571 (1+ (count-lines 1 here))))))
572 (cond
573 ((looking-at "else\\b[^_]")
574 (setq if-level (1+ if-level)))
575 ((looking-at "if\\b[^_]")
576 ;; check for else if... skip over
577 (let ((here (point)))
578 (c-safe (forward-sexp -1))
579 (if (looking-at "\\<else\\>[ \t]+\\<if\\>")
580 nil
581 (setq if-level (1- if-level))
582 (goto-char here))))
583 ((< (point) lim)
584 (setq if-level 0)
585 (goto-char lim))
586 ))
587 t)))
588
589(defun c-skip-conditional ()
590 ;; skip forward over conditional at point, including any predicate
591 ;; statements in parentheses. No error checking is performed.
592 (forward-sexp (cond
593 ;; else if()
594 ((looking-at "\\<else\\>[ \t]+\\<if\\>") 3)
595 ;; do, else, try, finally
596 ((looking-at "\\<\\(do\\|else\\|try\\|finally\\)\\>") 1)
597 ;; for, if, while, switch, catch, synchronized
598 (t 2))))
599
600(defun c-skip-case-statement-forward (state &optional lim)
601 ;; skip forward over case/default bodies, with optional maximal
602 ;; limit. if no next case body is found, nil is returned and point
603 ;; is not moved
604 (let ((lim (or lim (point-max)))
605 (here (point))
606 donep foundp bufpos
607 (safepos (point))
608 (balanced (car state)))
609 ;; search until we've passed the limit, or we've found our match
610 (while (and (< (point) lim)
611 (not donep))
612 (setq safepos (point))
613 ;; see if we can find a case statement, not in a literal
614 (if (and (re-search-forward c-switch-label-key lim 'move)
615 (setq bufpos (match-beginning 0))
616 (not (c-in-literal safepos))
617 (/= bufpos here))
618 ;; if we crossed into a balanced sexp, we know the case is
619 ;; not part of our switch statement, so just bound over the
620 ;; sexp and keep looking.
621 (if (and (consp balanced)
622 (> bufpos (car balanced))
623 (< bufpos (cdr balanced)))
624 (goto-char (cdr balanced))
625 (goto-char bufpos)
626 (setq donep t
627 foundp t))))
628 (if (not foundp)
629 (goto-char here))
630 foundp))
631
632(defun c-search-uplist-for-classkey (brace-state)
633 ;; search for the containing class, returning a 2 element vector if
634 ;; found. aref 0 contains the bufpos of the class key, and aref 1
635 ;; contains the bufpos of the open brace.
636 (if (null brace-state)
637 ;; no brace-state means we cannot be inside a class
638 nil
639 (let ((carcache (car brace-state))
640 search-start search-end)
641 (if (consp carcache)
642 ;; a cons cell in the first element means that there is some
643 ;; balanced sexp before the current bufpos. this we can
644 ;; ignore. the nth 1 and nth 2 elements define for us the
645 ;; search boundaries
646 (setq search-start (nth 2 brace-state)
647 search-end (nth 1 brace-state))
648 ;; if the car was not a cons cell then nth 0 and nth 1 define
649 ;; for us the search boundaries
650 (setq search-start (nth 1 brace-state)
651 search-end (nth 0 brace-state)))
652 ;; search-end cannot be a cons cell
653 (and (consp search-end)
654 (error "consp search-end: %s" search-end))
655 ;; if search-end is nil, or if the search-end character isn't an
656 ;; open brace, we are definitely not in a class
657 (if (or (not search-end)
658 (< search-end (point-min))
659 (not (eq (char-after search-end) ?{)))
660 nil
661 ;; now, we need to look more closely at search-start. if
662 ;; search-start is nil, then our start boundary is really
663 ;; point-min.
664 (if (not search-start)
665 (setq search-start (point-min))
666 ;; if search-start is a cons cell, then we can start
667 ;; searching from the end of the balanced sexp just ahead of
668 ;; us
669 (if (consp search-start)
670 (setq search-start (cdr search-start))))
671 ;; now we can do a quick regexp search from search-start to
672 ;; search-end and see if we can find a class key. watch for
673 ;; class like strings in literals
674 (save-excursion
675 (save-restriction
676 (goto-char search-start)
677 (let ((search-key (concat c-class-key "\\|extern[^_]"))
678 foundp class match-end)
679 (while (and (not foundp)
680 (progn
681 (c-forward-syntactic-ws)
682 (> search-end (point)))
683 (re-search-forward search-key search-end t))
684 (setq class (match-beginning 0)
685 match-end (match-end 0))
686 (if (c-in-literal search-start)
687 nil ; its in a comment or string, ignore
688 (goto-char class)
689 (skip-chars-forward " \t\n")
690 (setq foundp (vector (c-point 'boi) search-end))
691 (cond
692 ;; check for embedded keywords
693 ((let ((char (char-after (1- class))))
694 (and char
695 (memq (char-syntax char) '(?w ?_))))
696 (goto-char match-end)
697 (setq foundp nil))
698 ;; make sure we're really looking at the start of a
699 ;; class definition, and not a forward decl, return
700 ;; arg, template arg list, or an ObjC or Java method.
701 ((and c-method-key
702 (re-search-forward c-method-key search-end t))
703 (setq foundp nil))
704 ;; Its impossible to define a regexp for this, and
705 ;; nearly so to do it programmatically.
706 ;;
707 ;; ; picks up forward decls
708 ;; = picks up init lists
709 ;; ) picks up return types
710 ;; > picks up templates, but remember that we can
711 ;; inherit from templates!
712 ((let ((skipchars "^;=)"))
713 ;; try to see if we found the `class' keyword
714 ;; inside a template arg list
715 (save-excursion
716 (skip-chars-backward "^<>" search-start)
717 (if (eq (char-before) ?<)
718 (setq skipchars (concat skipchars ">"))))
719 (skip-chars-forward skipchars search-end)
720 (/= (point) search-end))
721 (setq foundp nil))
722 )))
723 foundp))
724 )))))
725
726(defun c-inside-bracelist-p (containing-sexp brace-state)
727 ;; return the buffer position of the beginning of the brace list
728 ;; statement if we're inside a brace list, otherwise return nil.
729 ;; CONTAINING-SEXP is the buffer pos of the innermost containing
730 ;; paren. BRACE-STATE is the remainder of the state of enclosing braces
731 ;;
732 ;; N.B.: This algorithm can potentially get confused by cpp macros
733 ;; places in inconvenient locations. Its a trade-off we make for
734 ;; speed.
735 (or
736 ;; this will pick up enum lists
737 (condition-case ()
738 (save-excursion
739 (goto-char containing-sexp)
740 (forward-sexp -1)
741 (if (or (looking-at "enum[\t\n ]+")
742 (progn (forward-sexp -1)
743 (looking-at "enum[\t\n ]+")))
744 (point)))
745 (error nil))
746 ;; this will pick up array/aggregate init lists, even if they are nested.
747 (save-excursion
748 (let (bufpos failedp)
749 (while (and (not bufpos)
750 containing-sexp)
751 (if (consp containing-sexp)
752 (setq containing-sexp (car brace-state)
753 brace-state (cdr brace-state))
754 ;; see if significant character just before brace is an equal
755 (goto-char containing-sexp)
756 (setq failedp nil)
757 (condition-case ()
758 (progn
759 (forward-sexp -1)
760 (forward-sexp 1)
761 (c-forward-syntactic-ws containing-sexp))
762 (error (setq failedp t)))
763 (if (or failedp (not (eq (char-after) ?=)))
764 ;; lets see if we're nested. find the most nested
765 ;; containing brace
766 (setq containing-sexp (car brace-state)
767 brace-state (cdr brace-state))
768 ;; we've hit the beginning of the aggregate list
769 (c-beginning-of-statement-1 (c-most-enclosing-brace brace-state))
770 (setq bufpos (point)))
771 ))
772 bufpos))
773 ))
774
775
776(defun c-most-enclosing-brace (state)
777 ;; return the bufpos of the most enclosing brace that hasn't been
778 ;; narrowed out by any enclosing class, or nil if none was found
779 (let (enclosingp)
780 (while (and state (not enclosingp))
781 (setq enclosingp (car state)
782 state (cdr state))
783 (if (consp enclosingp)
784 (setq enclosingp nil)
785 (if (> (point-min) enclosingp)
786 (setq enclosingp nil))
787 (setq state nil)))
788 enclosingp))
789
790(defun c-least-enclosing-brace (state)
791 ;; return the bufpos of the least (highest) enclosing brace that
792 ;; hasn't been narrowed out by any enclosing class, or nil if none
793 ;; was found.
794 (c-most-enclosing-brace (nreverse state)))
795
796(defun c-safe-position (bufpos state)
797 ;; return the closest known safe position higher up than point
798 (let ((safepos nil))
799 (while state
800 (setq safepos
801 (if (consp (car state))
802 (cdr (car state))
803 (car state)))
804 (if (< safepos bufpos)
805 (setq state nil)
806 (setq state (cdr state))))
807 safepos))
808
809(defun c-narrow-out-enclosing-class (state lim)
810 ;; narrow the buffer so that the enclosing class is hidden
811 (let (inclass-p)
812 (and state
813 (setq inclass-p (c-search-uplist-for-classkey state))
814 (narrow-to-region
815 (progn
816 (goto-char (1+ (aref inclass-p 1)))
817 (skip-chars-forward " \t\n" lim)
818 ;; if point is now left of the class opening brace, we're
819 ;; hosed, so try a different tact
820 (if (<= (point) (aref inclass-p 1))
821 (progn
822 (goto-char (1+ (aref inclass-p 1)))
823 (c-forward-syntactic-ws lim)))
824 (point))
825 ;; end point is the end of the current line
826 (progn
827 (goto-char lim)
828 (c-point 'eol))))
829 ;; return the class vector
830 inclass-p))
831
832
833;; This function implements the main decision tree for determining the
834;; syntactic analysis of the current line of code. Yes, it's huge and
835;; bloated!
836
837(defun c-guess-basic-syntax ()
838 (save-excursion
839 (save-restriction
840 (beginning-of-line)
841 (let* ((indent-point (point))
842 (case-fold-search nil)
843 (fullstate (c-parse-state))
844 (state fullstate)
845 (in-method-intro-p (and (eq major-mode 'objc-mode)
846 c-method-key
847 (looking-at c-method-key)))
848 literal containing-sexp char-before-ip char-after-ip lim
849 syntax placeholder c-in-literal-cache inswitch-p
850 injava-inher
851 ;; narrow out any enclosing class or extern "C" block
852 (inclass-p (c-narrow-out-enclosing-class state indent-point))
853 (inextern-p (and inclass-p
854 (save-excursion
855 (save-restriction
856 (widen)
857 (goto-char (aref inclass-p 0))
858 (looking-at "extern[^_]")))))
859 )
860
861 ;; get the buffer position of the most nested opening brace,
862 ;; if there is one, and it hasn't been narrowed out
863 (save-excursion
864 (goto-char indent-point)
865 (skip-chars-forward " \t}")
866 (skip-chars-backward " \t")
867 (while (and state
868 (not in-method-intro-p)
869 (not containing-sexp))
870 (setq containing-sexp (car state)
871 state (cdr state))
872 (if (consp containing-sexp)
873 ;; if cdr == point, then containing sexp is the brace
874 ;; that opens the sexp we close
875 (if (= (cdr containing-sexp) (point))
876 (setq containing-sexp (car containing-sexp))
877 ;; otherwise, ignore this element
878 (setq containing-sexp nil))
879 ;; ignore the bufpos if its been narrowed out by the
880 ;; containing class
881 (if (<= containing-sexp (point-min))
882 (setq containing-sexp nil)))))
883
884 ;; set the limit on the farthest back we need to search
885 (setq lim (or containing-sexp
886 (if (consp (car fullstate))
887 (cdr (car fullstate))
888 nil)
889 (point-min)))
890
891 ;; cache char before and after indent point, and move point to
892 ;; the most likely position to perform the majority of tests
893 (goto-char indent-point)
894 (skip-chars-forward " \t")
895 (setq char-after-ip (char-after))
896 (c-backward-syntactic-ws lim)
897 (setq char-before-ip (char-before))
898 (goto-char indent-point)
899 (skip-chars-forward " \t")
900
901 ;; are we in a literal?
902 (setq literal (c-in-literal lim))
903
904 ;; now figure out syntactic qualities of the current line
905 (cond
906 ;; CASE 1: in a string.
907 ((memq literal '(string))
908 (c-add-syntax 'string (c-point 'bopl)))
909 ;; CASE 2: in a C or C++ style comment.
910 ((memq literal '(c c++))
911 ;; we need to catch multi-paragraph C comments
912 (while (and (zerop (forward-line -1))
913 (looking-at "^[ \t]*$")))
914 (c-add-syntax literal (c-point 'boi)))
915 ;; CASE 3: in a cpp preprocessor
916 ((eq literal 'pound)
917 (c-beginning-of-macro lim)
918 (c-add-syntax 'cpp-macro (c-point 'boi)))
919 ;; CASE 4: in an objective-c method intro
920 (in-method-intro-p
921 (c-add-syntax 'objc-method-intro (c-point 'boi)))
922 ;; CASE 5: Line is at top level.
923 ((null containing-sexp)
924 (cond
925 ;; CASE 5A: we are looking at a defun, class, or
926 ;; inline-inclass method opening brace
927 ((eq char-after-ip ?{)
928 (cond
929 ;; CASE 5A.1: extern declaration
930 ((save-excursion
931 (goto-char indent-point)
932 (skip-chars-forward " \t")
933 (and (c-safe (progn (backward-sexp 2) t))
934 (looking-at "extern[^_]")
935 (progn
936 (setq placeholder (point))
937 (forward-sexp 1)
938 (c-forward-syntactic-ws)
939 (eq (char-after) ?\"))))
940 (goto-char placeholder)
941 (c-add-syntax 'extern-lang-open (c-point 'boi)))
942 ;; CASE 5A.2: we are looking at a class opening brace
943 ((save-excursion
944 (goto-char indent-point)
945 (skip-chars-forward " \t{")
946 ;; TBD: watch out! there could be a bogus
947 ;; c-state-cache in place when we get here. we have
948 ;; to go through much chicanery to ignore the cache.
949 ;; But of course, there may not be! BLECH! BOGUS!
950 (let ((decl
951 (if (boundp 'c-state-cache)
952 (let ((old-cache c-state-cache))
953 (prog2
954 (makunbound 'c-state-cache)
955 (c-search-uplist-for-classkey (c-parse-state))
956 (setq c-state-cache old-cache)))
957 (c-search-uplist-for-classkey (c-parse-state))
958 )))
959 (and decl
960 (setq placeholder (aref decl 0)))
961 ))
962 (c-add-syntax 'class-open placeholder))
963 ;; CASE 5A.3: brace list open
964 ((save-excursion
965 (c-beginning-of-statement-1 lim)
966 ;; c-b-o-s could have left us at point-min
967 (and (bobp)
968 (c-forward-syntactic-ws indent-point))
969 (if (looking-at "typedef[^_]")
970 (progn (forward-sexp 1)
971 (c-forward-syntactic-ws indent-point)))
972 (setq placeholder (c-point 'boi))
973 (and (or (looking-at "enum[ \t\n]+")
974 (eq char-before-ip ?=))
975 (save-excursion
976 (skip-chars-forward "^;(" indent-point)
977 (not (memq (char-after) '(?\; ?\()))
978 )))
979 (c-add-syntax 'brace-list-open placeholder))
980 ;; CASE 5A.4: inline defun open
981 ((and inclass-p (not inextern-p))
982 (c-add-syntax 'inline-open)
983 (c-add-syntax 'inclass (aref inclass-p 0)))
984 ;; CASE 5A.5: ordinary defun open
985 (t
986 (goto-char placeholder)
987 (c-add-syntax 'defun-open (c-point 'bol))
988 )))
989 ;; CASE 5B: first K&R arg decl or member init
990 ((c-just-after-func-arglist-p)
991 (cond
992 ;; CASE 5B.1: a member init
993 ((or (eq char-before-ip ?:)
994 (eq char-after-ip ?:))
995 ;; this line should be indented relative to the beginning
996 ;; of indentation for the topmost-intro line that contains
997 ;; the prototype's open paren
998 ;; TBD: is the following redundant?
999 (if (eq char-before-ip ?:)
1000 (forward-char -1))
1001 (c-backward-syntactic-ws lim)
1002 ;; TBD: is the preceding redundant?
1003 (if (eq (char-before) ?:)
1004 (progn (forward-char -1)
1005 (c-backward-syntactic-ws lim)))
1006 (if (eq (char-before) ?\))
1007 (backward-sexp 1))
1008 (setq placeholder (point))
1009 (save-excursion
1010 (and (c-safe (backward-sexp 1) t)
1011 (looking-at "throw[^_]")
1012 (c-safe (backward-sexp 1) t)
1013 (setq placeholder (point))))
1014 (goto-char placeholder)
1015 (c-add-syntax 'member-init-intro (c-point 'boi))
1016 ;; we don't need to add any class offset since this
1017 ;; should be relative to the ctor's indentation
1018 )
1019 ;; CASE 5B.2: K&R arg decl intro
1020 (c-recognize-knr-p
1021 (c-add-syntax 'knr-argdecl-intro (c-point 'boi))
1022 (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
1023 ;; CASE 5B.3: Nether region after a C++ or Java func
1024 ;; decl, which could include a `throws' declaration.
1025 (t
1026 (c-beginning-of-statement-1 lim)
1027 (c-add-syntax 'func-decl-cont (c-point 'boi))
1028 )))
1029 ;; CASE 5C: inheritance line. could be first inheritance
1030 ;; line, or continuation of a multiple inheritance
1031 ((or (and c-baseclass-key (looking-at c-baseclass-key))
1032 (and (or (eq char-before-ip ?:)
1033 ;; watch out for scope operator
1034 (save-excursion
1035 (and (eq char-after-ip ?:)
1036 (c-safe (progn (forward-char 1) t))
1037 (not (eq (char-after) ?:))
1038 )))
1039 (save-excursion
1040 (c-backward-syntactic-ws lim)
1041 (if (eq char-before-ip ?:)
1042 (progn
1043 (forward-char -1)
1044 (c-backward-syntactic-ws lim)))
1045 (back-to-indentation)
1046 (looking-at c-class-key)))
1047 ;; for Java
1048 (and (eq major-mode 'java-mode)
1049 (let ((fence (save-excursion
1050 (c-beginning-of-statement-1 lim)
1051 (point)))
1052 cont done)
1053 (save-excursion
1054 (while (not done)
1055 (cond ((looking-at c-Java-special-key)
1056 (setq injava-inher (cons cont (point))
1057 done t))
1058 ((or (not (c-safe (forward-sexp -1) t))
1059 (<= (point) fence))
1060 (setq done t))
1061 )
1062 (setq cont t)))
1063 injava-inher)
1064 (not (c-crosses-statement-barrier-p (cdr injava-inher)
1065 (point)))
1066 ))
1067 (cond
1068 ;; CASE 5C.1: non-hanging colon on an inher intro
1069 ((eq char-after-ip ?:)
1070 (c-backward-syntactic-ws lim)
1071 (c-add-syntax 'inher-intro (c-point 'boi))
1072 ;; don't add inclass symbol since relative point already
1073 ;; contains any class offset
1074 )
1075 ;; CASE 5C.2: hanging colon on an inher intro
1076 ((eq char-before-ip ?:)
1077 (c-add-syntax 'inher-intro (c-point 'boi))
1078 (and inclass-p (c-add-syntax 'inclass (aref inclass-p 0))))
1079 ;; CASE 5C.3: in a Java implements/extends
1080 (injava-inher
1081 (let ((where (cdr injava-inher))
1082 (cont (car injava-inher)))
1083 (goto-char where)
1084 (cond ((looking-at "throws[ \t\n]")
1085 (c-add-syntax 'func-decl-cont
1086 (progn (c-beginning-of-statement-1 lim)
1087 (c-point 'boi))))
1088 (cont (c-add-syntax 'inher-cont where))
1089 (t (c-add-syntax 'inher-intro
1090 (progn (goto-char (cdr injava-inher))
1091 (c-beginning-of-statement-1 lim)
1092 (point))))
1093 )))
1094 ;; CASE 5C.4: a continued inheritance line
1095 (t
1096 (c-beginning-of-inheritance-list lim)
1097 (c-add-syntax 'inher-cont (point))
1098 ;; don't add inclass symbol since relative point already
1099 ;; contains any class offset
1100 )))
1101 ;; CASE 5D: this could be a top-level compound statement or a
1102 ;; member init list continuation
1103 ((eq char-before-ip ?,)
1104 (goto-char indent-point)
1105 (c-backward-syntactic-ws lim)
1106 (while (and (< lim (point))
1107 (eq (char-before) ?,))
1108 ;; this will catch member inits with multiple
1109 ;; line arglists
1110 (forward-char -1)
1111 (c-backward-syntactic-ws (c-point 'bol))
1112 (if (eq (char-before) ?\))
1113 (backward-sexp 1))
1114 ;; now continue checking
1115 (beginning-of-line)
1116 (c-backward-syntactic-ws lim))
1117 (cond
1118 ;; CASE 5D.1: hanging member init colon, but watch out
1119 ;; for bogus matches on access specifiers inside classes.
1120 ((and (eq (char-before) ?:)
1121 (save-excursion
1122 (forward-word -1)
1123 (not (looking-at c-access-key))))
1124 (goto-char indent-point)
1125 (c-backward-syntactic-ws lim)
1126 (c-safe (backward-sexp 1))
1127 (c-add-syntax 'member-init-cont (c-point 'boi))
1128 ;; we do not need to add class offset since relative
1129 ;; point is the member init above us
1130 )
1131 ;; CASE 5D.2: non-hanging member init colon
1132 ((progn
1133 (c-forward-syntactic-ws indent-point)
1134 (eq (char-after) ?:))
1135 (skip-chars-forward " \t:")
1136 (c-add-syntax 'member-init-cont (point)))
1137 ;; CASE 5D.3: perhaps a multiple inheritance line?
1138 ((looking-at c-inher-key)
1139 (c-add-syntax 'inher-cont (c-point 'boi)))
1140 ;; CASE 5D.4: perhaps a template list continuation?
1141 ((save-excursion
1142 (skip-chars-backward "^<" lim)
1143 ;; not sure if this is the right test, but it should
1144 ;; be fast and mostly accurate.
1145 (and (eq (char-before) ?<)
1146 (not (c-in-literal lim))))
1147 ;; we can probably indent it just like and arglist-cont
1148 (c-add-syntax 'arglist-cont (point)))
1149 ;; CASE 5D.5: perhaps a top-level statement-cont
1150 (t
1151 (c-beginning-of-statement-1 lim)
1152 ;; skip over any access-specifiers
1153 (and inclass-p c-access-key
1154 (while (looking-at c-access-key)
1155 (forward-line 1)))
1156 ;; skip over comments, whitespace
1157 (c-forward-syntactic-ws indent-point)
1158 (c-add-syntax 'statement-cont (c-point 'boi)))
1159 ))
1160 ;; CASE 5E: we are looking at a access specifier
1161 ((and inclass-p
1162 c-access-key
1163 (looking-at c-access-key))
1164 (c-add-syntax 'access-label (c-point 'bonl))
1165 (c-add-syntax 'inclass (aref inclass-p 0)))
1166 ;; CASE 5F: extern-lang-close?
1167 ((and inextern-p
1168 (eq char-after-ip ?}))
1169 (c-add-syntax 'extern-lang-close (aref inclass-p 1)))
1170 ;; CASE 5G: we are looking at the brace which closes the
1171 ;; enclosing nested class decl
1172 ((and inclass-p
1173 (eq char-after-ip ?})
1174 (save-excursion
1175 (save-restriction
1176 (widen)
1177 (forward-char 1)
1178 (and
1179 (condition-case nil
1180 (progn (backward-sexp 1) t)
1181 (error nil))
1182 (= (point) (aref inclass-p 1))
1183 ))))
1184 (save-restriction
1185 (widen)
1186 (goto-char (aref inclass-p 0))
1187 (c-add-syntax 'class-close (c-point 'boi))))
1188 ;; CASE 5H: we could be looking at subsequent knr-argdecls
1189 ((and c-recognize-knr-p
1190 ;; here we essentially use the hack that is used in
1191 ;; Emacs' c-mode.el to limit how far back we should
1192 ;; look. The assumption is made that argdecls are
1193 ;; indented at least one space and that function
1194 ;; headers are not indented.
1195 (let ((limit (save-excursion
1196 (re-search-backward "^[^ \^L\t\n#]" nil 'move)
1197 (point))))
1198 (save-excursion
1199 (c-backward-syntactic-ws limit)
1200 (setq placeholder (point))
1201 (while (and (memq (char-before) '(?\; ?,))
1202 (> (point) limit))
1203 (beginning-of-line)
1204 (setq placeholder (point))
1205 (c-backward-syntactic-ws limit))
1206 (and (eq (char-before) ?\))
1207 (or (not c-method-key)
1208 (progn
1209 (forward-sexp -1)
1210 (forward-char -1)
1211 (c-backward-syntactic-ws)
1212 (not (or (memq (char-before) '(?- ?+))
1213 ;; or a class category
1214 (progn
1215 (forward-sexp -2)
1216 (looking-at c-class-key))
1217 )))))
1218 ))
1219 (save-excursion
1220 (c-beginning-of-statement-1)
1221 (not (looking-at "typedef[ \t\n]+"))))
1222 (goto-char placeholder)
1223 (c-add-syntax 'knr-argdecl (c-point 'boi)))
1224 ;; CASE 5I: we are at the topmost level, make sure we skip
1225 ;; back past any access specifiers
1226 ((progn
1227 (c-backward-syntactic-ws lim)
1228 (while (and inclass-p
1229 c-access-key
1230 (not (bobp))
1231 (save-excursion
1232 (c-safe (progn (backward-sexp 1) t))
1233 (looking-at c-access-key)))
1234 (backward-sexp 1)
1235 (c-backward-syntactic-ws lim))
1236 (or (bobp)
1237 (memq (char-before) '(?\; ?\}))))
1238 ;; real beginning-of-line could be narrowed out due to
1239 ;; enclosure in a class block
1240 (save-restriction
1241 (widen)
1242 (c-add-syntax 'topmost-intro (c-point 'bol))
1243 (if inclass-p
1244 (progn
1245 (goto-char (aref inclass-p 1))
1246 (if inextern-p
1247 (c-add-syntax 'inextern-lang)
1248 (c-add-syntax 'inclass (c-point 'boi)))))
1249 ))
1250 ;; CASE 5J: we are at an ObjC or Java method definition
1251 ;; continuation line.
1252 ((and c-method-key
1253 (progn
1254 (c-beginning-of-statement-1 lim)
1255 (beginning-of-line)
1256 (looking-at c-method-key)))
1257 (c-add-syntax 'objc-method-args-cont (point)))
1258 ;; CASE 5K: we are at a topmost continuation line
1259 (t
1260 (c-beginning-of-statement-1 lim)
1261 (c-forward-syntactic-ws)
1262 (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
1263 )) ; end CASE 5
1264 ;; CASE 6: line is an expression, not a statement. Most
1265 ;; likely we are either in a function prototype or a function
1266 ;; call argument list
1267 ((not (eq (char-after containing-sexp) ?{))
1268 (c-backward-syntactic-ws containing-sexp)
1269 (cond
1270 ;; CASE 6A: we are looking at the arglist closing paren
1271 ((and (not (eq char-before-ip ?,))
1272 (memq char-after-ip '(?\) ?\])))
1273 (goto-char containing-sexp)
1274 (c-add-syntax 'arglist-close (c-point 'boi)))
1275 ;; CASE 6B: we are looking at the first argument in an empty
1276 ;; argument list. Use arglist-close if we're actually
1277 ;; looking at a close paren or bracket.
1278 ((memq char-before-ip '(?\( ?\[))
1279 (goto-char containing-sexp)
1280 (c-add-syntax 'arglist-intro (c-point 'boi)))
1281 ;; CASE 6C: we are inside a conditional test clause. treat
1282 ;; these things as statements
1283 ((save-excursion
1284 (goto-char containing-sexp)
1285 (and (c-safe (progn (forward-sexp -1) t))
1286 (looking-at "\\<for\\>[^_]")))
1287 (goto-char (1+ containing-sexp))
1288 (c-forward-syntactic-ws indent-point)
1289 (c-beginning-of-statement-1 containing-sexp)
1290 (if (eq char-before-ip ?\;)
1291 (c-add-syntax 'statement (point))
1292 (c-add-syntax 'statement-cont (point))
1293 ))
1294 ;; CASE 6D: maybe a continued method call. This is the case
1295 ;; when we are inside a [] bracketed exp, and what precede
1296 ;; the opening bracket is not an identifier.
1297 ((and c-method-key
1298 (eq (char-after containing-sexp) ?\[)
1299 (save-excursion
1300 (goto-char (1- containing-sexp))
1301 (c-backward-syntactic-ws (c-point 'bod))
1302 (if (not (looking-at c-symbol-key))
1303 (c-add-syntax 'objc-method-call-cont containing-sexp))
1304 )))
1305 ;; CASE 6E: we are looking at an arglist continuation line,
1306 ;; but the preceding argument is on the same line as the
1307 ;; opening paren. This case includes multi-line
1308 ;; mathematical paren groupings, but we could be on a
1309 ;; for-list continuation line
1310 ((and (save-excursion
1311 (goto-char (1+ containing-sexp))
1312 (skip-chars-forward " \t")
1313 (not (eolp)))
1314 (save-excursion
1315 (c-beginning-of-statement-1 lim)
1316 (skip-chars-backward " \t([")
1317 (<= (point) containing-sexp)))
1318 (goto-char containing-sexp)
1319 (c-add-syntax 'arglist-cont-nonempty (c-point 'boi)))
1320 ;; CASE 6F: we are looking at just a normal arglist
1321 ;; continuation line
1322 (t (c-beginning-of-statement-1 containing-sexp)
1323 (forward-char 1)
1324 (c-forward-syntactic-ws indent-point)
1325 (c-add-syntax 'arglist-cont (c-point 'boi)))
1326 ))
1327 ;; CASE 7: func-local multi-inheritance line
1328 ((and c-baseclass-key
1329 (save-excursion
1330 (goto-char indent-point)
1331 (skip-chars-forward " \t")
1332 (looking-at c-baseclass-key)))
1333 (goto-char indent-point)
1334 (skip-chars-forward " \t")
1335 (cond
1336 ;; CASE 7A: non-hanging colon on an inher intro
1337 ((eq char-after-ip ?:)
1338 (c-backward-syntactic-ws lim)
1339 (c-add-syntax 'inher-intro (c-point 'boi)))
1340 ;; CASE 7B: hanging colon on an inher intro
1341 ((eq char-before-ip ?:)
1342 (c-add-syntax 'inher-intro (c-point 'boi)))
1343 ;; CASE 7C: a continued inheritance line
1344 (t
1345 (c-beginning-of-inheritance-list lim)
1346 (c-add-syntax 'inher-cont (point))
1347 )))
1348 ;; CASE 8: we are inside a brace-list
1349 ((setq placeholder (c-inside-bracelist-p containing-sexp state))
1350 (cond
1351 ;; CASE 8A: brace-list-close brace
1352 ((and (eq char-after-ip ?})
1353 (c-safe (progn (forward-char 1)
1354 (backward-sexp 1)
1355 t))
1356 (= (point) containing-sexp))
1357 (c-add-syntax 'brace-list-close (c-point 'boi)))
1358 ;; CASE 8B: we're looking at the first line in a brace-list
1359 ((save-excursion
1360 (goto-char indent-point)
1361 (c-backward-syntactic-ws containing-sexp)
1362 (= (point) (1+ containing-sexp)))
1363 (goto-char containing-sexp)
1364 (c-add-syntax 'brace-list-intro (c-point 'boi))
1365 )
1366 ;;)) ; end CASE 8B
1367 ;; CASE 8C: this is just a later brace-list-entry
1368 (t (goto-char (1+ containing-sexp))
1369 (c-forward-syntactic-ws indent-point)
1370 (if (eq char-after-ip ?{)
1371 (c-add-syntax 'brace-list-open (point))
1372 (c-add-syntax 'brace-list-entry (point))
1373 )) ; end CASE 8C
1374 )) ; end CASE 8
1375 ;; CASE 9: A continued statement
1376 ((and (not (memq char-before-ip '(?\; ?} ?:)))
1377 (> (point)
1378 (save-excursion
1379 (c-beginning-of-statement-1 containing-sexp)
1380 (setq placeholder (point))))
1381 (/= placeholder containing-sexp))
1382 (goto-char indent-point)
1383 (skip-chars-forward " \t")
1384 (let ((after-cond-placeholder
1385 (save-excursion
1386 (goto-char placeholder)
1387 (if (looking-at c-conditional-key)
1388 (progn
1389 (c-safe (c-skip-conditional))
1390 (c-forward-syntactic-ws)
1391 (if (eq (char-after) ?\;)
1392 (progn
1393 (forward-char 1)
1394 (c-forward-syntactic-ws)))
1395 (point))
1396 nil))))
1397 (cond
1398 ;; CASE 9A: substatement
1399 ((and after-cond-placeholder
1400 (>= after-cond-placeholder indent-point))
1401 (goto-char placeholder)
1402 (if (eq char-after-ip ?{)
1403 (c-add-syntax 'substatement-open (c-point 'boi))
1404 (c-add-syntax 'substatement (c-point 'boi))))
1405 ;; CASE 9B: open braces for class or brace-lists
1406 ((eq char-after-ip ?{)
1407 (cond
1408 ;; CASE 9B.1: class-open
1409 ((save-excursion
1410 (goto-char indent-point)
1411 (skip-chars-forward " \t{")
1412 (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
1413 (and decl
1414 (setq placeholder (aref decl 0)))
1415 ))
1416 (c-add-syntax 'class-open placeholder))
1417 ;; CASE 9B.2: brace-list-open
1418 ((or (save-excursion
1419 (goto-char placeholder)
1420 (looking-at "\\<enum\\>"))
1421 (eq char-before-ip ?=))
1422 (c-add-syntax 'brace-list-open placeholder))
1423 ;; CASE 9B.3: catch-all for unknown construct.
1424 (t
1425 ;; Can and should I add an extensibility hook here?
1426 ;; Something like c-recognize-hook so support for
1427 ;; unknown constructs could be added. It's probably a
1428 ;; losing proposition, so I dunno.
1429 (goto-char placeholder)
1430 (c-add-syntax 'statement-cont (c-point 'boi))
1431 (c-add-syntax 'block-open))
1432 ))
1433 ;; CASE 9C: iostream insertion or extraction operator
1434 ((looking-at "<<\\|>>")
1435 (goto-char placeholder)
1436 (and after-cond-placeholder
1437 (goto-char after-cond-placeholder))
1438 (while (and (re-search-forward "<<\\|>>" indent-point 'move)
1439 (c-in-literal placeholder)))
1440 ;; if we ended up at indent-point, then the first
1441 ;; streamop is on a separate line. Indent the line like
1442 ;; a statement-cont instead
1443 (if (/= (point) indent-point)
1444 (c-add-syntax 'stream-op (c-point 'boi))
1445 (c-backward-syntactic-ws lim)
1446 (c-add-syntax 'statement-cont (c-point 'boi))))
1447 ;; CASE 9D: continued statement. find the accurate
1448 ;; beginning of statement or substatement
1449 (t
1450 (c-beginning-of-statement-1 after-cond-placeholder)
1451 ;; KLUDGE ALERT! c-beginning-of-statement-1 can leave
1452 ;; us before the lim we're passing in. It should be
1453 ;; fixed, but I'm worried about side-effects at this
1454 ;; late date. Fix for v5.
1455 (goto-char (or (and after-cond-placeholder
1456 (max after-cond-placeholder (point)))
1457 (point)))
1458 (c-add-syntax 'statement-cont (point)))
1459 )))
1460 ;; CASE 10: an else clause?
1461 ((looking-at "\\<else\\>[^_]")
1462 (c-backward-to-start-of-if containing-sexp)
1463 (c-add-syntax 'else-clause (c-point 'boi)))
1464 ;; CASE 11: Statement. But what kind? Lets see if its a
1465 ;; while closure of a do/while construct
1466 ((progn
1467 (goto-char indent-point)
1468 (skip-chars-forward " \t")
1469 (and (looking-at "while\\b[^_]")
1470 (save-excursion
1471 (c-backward-to-start-of-do containing-sexp)
1472 (setq placeholder (point))
1473 (looking-at "do\\b[^_]"))
1474 ))
1475 (c-add-syntax 'do-while-closure placeholder))
1476 ;; CASE 12: A case or default label
1477 ((looking-at c-switch-label-key)
1478 (goto-char containing-sexp)
1479 ;; check for hanging braces
1480 (if (/= (point) (c-point 'boi))
1481 (forward-sexp -1))
1482 (c-add-syntax 'case-label (c-point 'boi)))
1483 ;; CASE 13: any other label
1484 ((looking-at c-label-key)
1485 (goto-char containing-sexp)
1486 (c-add-syntax 'label (c-point 'boi)))
1487 ;; CASE 14: block close brace, possibly closing the defun or
1488 ;; the class
1489 ((eq char-after-ip ?})
1490 (let* ((lim (c-safe-position containing-sexp fullstate))
1491 (relpos (save-excursion
1492 (goto-char containing-sexp)
1493 (if (/= (point) (c-point 'boi))
1494 (c-beginning-of-statement-1 lim))
1495 (c-point 'boi))))
1496 (cond
1497 ;; CASE 14A: does this close an inline?
1498 ((let ((inclass-p (progn
1499 (goto-char containing-sexp)
1500 (c-search-uplist-for-classkey state))))
1501 ;; inextern-p in higher level let*
1502 (setq inextern-p (and inclass-p
1503 (progn
1504 (goto-char (aref inclass-p 0))
1505 (looking-at "extern[^_]"))))
1506 (and inclass-p (not inextern-p)))
1507 (c-add-syntax 'inline-close relpos))
1508 ;; CASE 14B: if there an enclosing brace that hasn't
1509 ;; been narrowed out by a class, then this is a
1510 ;; block-close
1511 ((and (not inextern-p)
1512 (c-most-enclosing-brace state))
1513 (c-add-syntax 'block-close relpos))
1514 ;; CASE 14C: find out whether we're closing a top-level
1515 ;; class or a defun
1516 (t
1517 (save-restriction
1518 (narrow-to-region (point-min) indent-point)
1519 (let ((decl (c-search-uplist-for-classkey (c-parse-state))))
1520 (if decl
1521 (c-add-syntax 'class-close (aref decl 0))
1522 (c-add-syntax 'defun-close relpos)))))
1523 )))
1524 ;; CASE 15: statement catchall
1525 (t
1526 ;; we know its a statement, but we need to find out if it is
1527 ;; the first statement in a block
1528 (goto-char containing-sexp)
1529 (forward-char 1)
1530 (c-forward-syntactic-ws indent-point)
1531 ;; now skip forward past any case/default clauses we might find.
1532 (while (or (c-skip-case-statement-forward fullstate indent-point)
1533 (and (looking-at c-switch-label-key)
1534 (not inswitch-p)))
1535 (setq inswitch-p t))
1536 ;; we want to ignore non-case labels when skipping forward
1537 (while (and (looking-at c-label-key)
1538 (goto-char (match-end 0)))
1539 (c-forward-syntactic-ws indent-point))
1540 (cond
1541 ;; CASE 15A: we are inside a case/default clause inside a
1542 ;; switch statement. find out if we are at the statement
1543 ;; just after the case/default label.
1544 ((and inswitch-p
1545 (progn
1546 (goto-char indent-point)
1547 (c-backward-syntactic-ws containing-sexp)
1548 (back-to-indentation)
1549 (setq placeholder (point))
1550 (looking-at c-switch-label-key)))
1551 (goto-char indent-point)
1552 (skip-chars-forward " \t")
1553 (if (eq (char-after) ?{)
1554 (c-add-syntax 'statement-case-open placeholder)
1555 (c-add-syntax 'statement-case-intro placeholder)))
1556 ;; CASE 15B: continued statement
1557 ((eq char-before-ip ?,)
1558 (c-add-syntax 'statement-cont (c-point 'boi)))
1559 ;; CASE 15C: a question/colon construct? But make sure
1560 ;; what came before was not a label, and what comes after
1561 ;; is not a globally scoped function call!
1562 ((or (and (memq char-before-ip '(?: ??))
1563 (save-excursion
1564 (goto-char indent-point)
1565 (c-backward-syntactic-ws lim)
1566 (back-to-indentation)
1567 (not (looking-at c-label-key))))
1568 (and (memq char-after-ip '(?: ??))
1569 (save-excursion
1570 (goto-char indent-point)
1571 (skip-chars-forward " \t")
1572 ;; watch out for scope operator
1573 (not (looking-at "::")))))
1574 (c-add-syntax 'statement-cont (c-point 'boi)))
1575 ;; CASE 15D: any old statement
1576 ((< (point) indent-point)
1577 (let ((safepos (c-most-enclosing-brace fullstate))
1578 relpos done)
1579 (goto-char indent-point)
1580 (c-beginning-of-statement-1 safepos)
1581 ;; It is possible we're on the brace that opens a nested
1582 ;; function.
1583 (if (and (eq (char-after) ?{)
1584 (save-excursion
1585 (c-backward-syntactic-ws safepos)
1586 (not (eq (char-before) ?\;))))
1587 (c-beginning-of-statement-1 safepos))
1588 (if (and inswitch-p
1589 (looking-at c-switch-label-key))
1590 (progn
1591 (goto-char placeholder)
1592 (end-of-line)
1593 (forward-sexp -1)))
1594 (setq relpos (c-point 'boi))
1595 (while (and (not done)
1596 (<= safepos (point))
1597 (/= relpos (point)))
1598 (c-beginning-of-statement-1 safepos)
1599 (if (= relpos (c-point 'boi))
1600 (setq done t))
1601 (setq relpos (c-point 'boi)))
1602 (c-add-syntax 'statement relpos)
1603 (if (eq char-after-ip ?{)
1604 (c-add-syntax 'block-open))))
1605 ;; CASE 15E: first statement in an inline, or first
1606 ;; statement in a top-level defun. we can tell this is it
1607 ;; if there are no enclosing braces that haven't been
1608 ;; narrowed out by a class (i.e. don't use bod here!)
1609 ((save-excursion
1610 (save-restriction
1611 (widen)
1612 (goto-char containing-sexp)
1613 (c-narrow-out-enclosing-class state containing-sexp)
1614 (not (c-most-enclosing-brace state))))
1615 (goto-char containing-sexp)
1616 ;; if not at boi, then defun-opening braces are hung on
1617 ;; right side, so we need a different relpos
1618 (if (/= (point) (c-point 'boi))
1619 (progn
1620 (c-backward-syntactic-ws)
1621 (c-safe (forward-sexp (if (eq (char-before) ?\))
1622 -1 -2)))
1623 ;; looking at a Java throws clause following a
1624 ;; method's parameter list
1625 (c-beginning-of-statement-1)
1626 ))
1627 (c-add-syntax 'defun-block-intro (c-point 'boi)))
1628 ;; CASE 15F: first statement in a block
1629 (t (goto-char containing-sexp)
1630 (if (/= (point) (c-point 'boi))
1631 (c-beginning-of-statement-1
1632 (if (= (point) lim)
1633 (c-safe-position (point) state) lim)))
1634 (c-add-syntax 'statement-block-intro (c-point 'boi))
1635 (if (eq char-after-ip ?{)
1636 (c-add-syntax 'block-open)))
1637 ))
1638 )
1639
1640 ;; now we need to look at any modifiers
1641 (goto-char indent-point)
1642 (skip-chars-forward " \t")
1643 ;; are we looking at a comment only line?
1644 (if (looking-at c-comment-start-regexp)
1645 (c-add-syntax 'comment-intro))
1646 ;; we might want to give additional offset to friends (in C++).
1647 (if (and (eq major-mode 'c++-mode)
1648 (looking-at c-C++-friend-key))
1649 (c-add-syntax 'friend))
1650 ;; return the syntax
1651 syntax))))
1652
1653
1654(defun c-echo-parsing-error ()
1655 (if (not c-parsing-error)
1656 nil
1657 (message "unbalanced close brace at bufpos %d -- INDENTATION IS SUSPECT!"
1658 c-parsing-error)
1659 (ding))
1660 c-parsing-error)
1661
1662;; indent via syntactic language elements
1663(defun c-indent-line (&optional syntax)
1664 ;; indent the current line as C/C++/ObjC code. Optional SYNTAX is the
1665 ;; syntactic information for the current line. Returns the amount of
1666 ;; indentation change
1667 (let* ((c-syntactic-context (or syntax (c-guess-basic-syntax)))
1668 (pos (- (point-max) (point)))
1669 (indent (apply '+ (mapcar 'c-get-offset c-syntactic-context)))
1670 (shift-amt (- (current-indentation) indent)))
1671 (and c-echo-syntactic-information-p
1672 (not (c-echo-parsing-error))
1673 (message "syntax: %s, indent= %d" c-syntactic-context indent))
1674 (if (zerop shift-amt)
1675 nil
1676 (delete-region (c-point 'bol) (c-point 'boi))
1677 (beginning-of-line)
1678 (indent-to indent))
1679 (if (< (point) (c-point 'boi))
1680 (back-to-indentation)
1681 ;; If initial point was within line's indentation, position after
1682 ;; the indentation. Else stay at same point in text.
1683 (if (> (- (point-max) pos) (point))
1684 (goto-char (- (point-max) pos)))
1685 )
1686 (run-hooks 'c-special-indent-hook)
1687 shift-amt))
1688
1689(defun c-show-syntactic-information (arg)
1690 "Show syntactic information for current line.
1691With universal argument, inserts the analysis as a comment on that line."
1692 (interactive "P")
1693 (let ((syntax (c-guess-basic-syntax)))
1694 (if (not (consp arg))
1695 (if (not (c-echo-parsing-error))
1696 (message "syntactic analysis: %s" syntax))
1697 (indent-for-comment)
1698 (insert (format "%s" syntax))
1699 ))
1700 (c-keep-region-active))
1701
1702
1703(provide 'cc-engine)
1704;;; cc-engine.el ends here
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
new file mode 100644
index 00000000000..03667e1870a
--- /dev/null
+++ b/lisp/progmodes/cc-langs.el
@@ -0,0 +1,551 @@
1;;; cc-langs.el --- specific language support for CC Mode
2
3;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
4
5;; Authors: 1992-1997 Barry A. Warsaw
6;; 1987 Dave Detlefs and Stewart Clamen
7;; 1985 Richard M. Stallman
8;; Maintainer: cc-mode-help@python.org
9;; Created: 22-Apr-1997 (split from cc-mode.el)
10;; Version: 5.12
11;; Keywords: c languages oop
12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software; you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation; either version 2, or (at your option)
18;; any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs; see the file COPYING. If not, write to the
27;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28;; Boston, MA 02111-1307, USA.
29
30
31;; Regular expressions and other values which must be parameterized on
32;; a per-language basis.
33
34;; Keywords defining protection levels
35(defconst c-protection-key "\\<\\(public\\|protected\\|private\\)\\>")
36
37;; Regex describing a `symbol' in all languages We cannot use just
38;; `word' syntax class since `_' cannot be in word class. Putting
39;; underscore in word class breaks forward word movement behavior that
40;; users are familiar with.
41(defconst c-symbol-key "\\(\\w\\|\\s_\\)+")
42
43
44;; keywords introducing class definitions. language specific
45(defconst c-C-class-key "\\(struct\\|union\\)")
46(defconst c-C++-class-key "\\(class\\|struct\\|union\\)")
47
48(defconst c-ObjC-class-key
49 (concat
50 "@\\(interface\\|implementation\\)\\s +"
51 c-symbol-key ;name of the class
52 "\\(\\s *:\\s *" c-symbol-key "\\)?" ;maybe followed by the superclass
53 "\\(\\s *<[^>]+>\\)?" ;and maybe the adopted protocols list
54 ))
55
56(defconst c-Java-class-key
57 (concat
58 "\\(" c-protection-key "\\s +\\)?"
59 "\\(interface\\|class\\)\\s +"
60 c-symbol-key ;name of the class
61 "\\(\\s *extends\\s *" c-symbol-key "\\)?" ;maybe followed by superclass
62 ;;"\\(\\s *implements *[^{]+{\\)?" ;maybe the adopted protocols list
63 ))
64
65(defvar c-class-key c-C-class-key)
66(make-variable-buffer-local 'c-class-key)
67
68
69;; regexp describing access protection clauses. language specific
70(defvar c-access-key nil)
71(make-variable-buffer-local 'c-access-key)
72(defconst c-C++-access-key (concat c-protection-key "[ \t]*:"))
73(defconst c-ObjC-access-key (concat "@" c-protection-key))
74(defconst c-Java-access-key nil)
75
76
77;; keywords introducing conditional blocks
78(defconst c-C-conditional-key nil)
79(defconst c-C++-conditional-key nil)
80(defconst c-Java-conditional-key nil)
81
82(let ((all-kws "for\\|if\\|do\\|else\\|while\\|switch")
83 (exc-kws "\\|try\\|catch")
84 (thr-kws "\\|finally\\|synchronized")
85 (front "\\b\\(")
86 (back "\\)\\b[^_]"))
87 (setq c-C-conditional-key (concat front all-kws back)
88 c-C++-conditional-key (concat front all-kws exc-kws back)
89 c-Java-conditional-key (concat front all-kws exc-kws thr-kws back)))
90
91(defvar c-conditional-key c-C-conditional-key)
92(make-variable-buffer-local 'c-conditional-key)
93
94
95;; keywords describing method definition introductions
96(defvar c-method-key nil)
97(make-variable-buffer-local 'c-method-key)
98
99(defconst c-ObjC-method-key
100 (concat
101 "^\\s *[+-]\\s *"
102 "\\(([^)]*)\\)?" ; return type
103 ;; \\s- in objc syntax table does not include \n
104 ;; since it is considered the end of //-comments.
105 "[ \t\n]*" c-symbol-key))
106
107(defconst c-Java-method-key
108 (concat
109 "^\\s *[+-]\\s *"
110 "\\(([^)]*)\\)?" ; return type
111 ;; \\s- in java syntax table does not include \n
112 ;; since it is considered the end of //-comments.
113 "[ \t\n]*" c-symbol-key))
114
115
116;; comment starter definitions for various languages. language specific
117(defconst c-C-comment-start-regexp "/[*]")
118(defconst c-C++-comment-start-regexp "/[/*]")
119;; We need to match all 3 Java style comments
120;; 1) Traditional C block; 2) javadoc /** ...; 3) C++ style
121(defconst c-Java-comment-start-regexp "/\\(/\\|[*][*]?\\)")
122(defvar c-comment-start-regexp c-C-comment-start-regexp)
123(make-variable-buffer-local 'c-comment-start-regexp)
124
125
126
127;; Regexp describing a switch's case or default label for all languages
128(defconst c-switch-label-key "\\(\\(case[( \t]+\\S .*\\)\\|default[ \t]*\\):")
129;; Regexp describing any label.
130(defconst c-label-key (concat c-symbol-key ":\\([^:]\\|$\\)"))
131
132;; Regexp describing class inheritance declarations. TBD: this should
133;; be language specific, and only makes sense for C++
134(defconst c-inher-key
135 (concat "\\(\\<static\\>\\s +\\)?"
136 c-C++-class-key "[ \t]+" c-symbol-key
137 "\\([ \t]*:[ \t]*\\)\\s *[^;]"))
138
139;; Regexp describing C++ base classes in a derived class definition.
140;; TBD: this should be language specific, and only makes sense for C++
141(defvar c-baseclass-key
142 (concat
143 ":?[ \t]*\\(virtual[ \t]+\\)?\\("
144 c-protection-key "[ \t]+\\)" c-symbol-key))
145(make-variable-buffer-local 'c-baseclass-key)
146
147;; Regexp describing friend declarations in C++ classes.
148(defconst c-C++-friend-key
149 "friend[ \t]+\\|template[ \t]*<.+>[ \t]*friend[ \t]+")
150
151;; Regexp describing Java inheritance and throws clauses.
152(defconst c-Java-special-key "\\(implements\\|extends\\|throws\\)[^_]")
153
154;; Regexp describing the beginning of a Java top-level definition.
155(defconst c-Java-defun-prompt-regexp
156 "^[ \t]*\\(\\(\\(public\\|protected\\|private\\|const\\|abstract\\|synchronized\\|final\\|static\\|threadsafe\\|transient\\|native\\|volatile\\)\\s-+\\)*\\(\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*[][_$.a-zA-Z0-9]+\\|[[a-zA-Z]\\)\\s-*\\)\\s-+\\)\\)?\\(\\([[a-zA-Z][][_$.a-zA-Z0-9]*\\s-+\\)\\s-*\\)?\\([_a-zA-Z][^][ \t:;.,{}()=]*\\|\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)\\)\\s-*\\(([^);{}]*)\\)?\\([] \t]*\\)\\(\\s-*\\<throws\\>\\s-*\\(\\([_$a-zA-Z][_$.a-zA-Z0-9]*\\)[, \t\n\r\f]*\\)+\\)?\\s-*")
157
158
159
160;; internal state variables
161
162;; Internal state of hungry delete key feature
163(defvar c-hungry-delete-key nil)
164(make-variable-buffer-local 'c-hungry-delete-key)
165
166;; Internal state of auto newline feature.
167(defvar c-auto-newline nil)
168(make-variable-buffer-local 'c-auto-newline)
169
170;; Internal auto-newline/hungry-delete designation string for mode line.
171(defvar c-auto-hungry-string nil)
172(make-variable-buffer-local 'c-auto-hungry-string)
173
174;; Buffer local language-specific comment style flag.
175(defvar c-double-slash-is-comments-p nil)
176(make-variable-buffer-local 'c-double-slash-is-comments-p)
177
178;; Non-nil means K&R style argument declarations are valid.
179(defvar c-recognize-knr-p t)
180(make-variable-buffer-local 'c-recognize-knr-p)
181
182
183
184(defun c-use-java-style ()
185 "Institutes `java' indentation style.
186For use with the variable `java-mode-hook'."
187 (c-set-style "java"))
188
189(defvar c-styles-are-initialized nil)
190
191(defun c-common-init ()
192 ;; Common initializations for all modes.
193 (if c-styles-are-initialized
194 nil
195 (require 'cc-styles)
196 (c-initialize-builtin-style)
197 (if c-style-variables-are-local-p
198 (c-make-styles-buffer-local))
199 (setq c-styles-are-initialized t))
200 ;; these variables should always be buffer local; they do not affect
201 ;; indentation style.
202 (make-local-variable 'paragraph-start)
203 (make-local-variable 'paragraph-separate)
204 (make-local-variable 'paragraph-ignore-fill-prefix)
205 (make-local-variable 'require-final-newline)
206 (make-local-variable 'parse-sexp-ignore-comments)
207 (make-local-variable 'indent-line-function)
208 (make-local-variable 'indent-region-function)
209 (make-local-variable 'comment-start)
210 (make-local-variable 'comment-end)
211 (make-local-variable 'comment-column)
212 (make-local-variable 'comment-start-skip)
213 (make-local-variable 'comment-multi-line)
214 (make-local-variable 'outline-regexp)
215 (make-local-variable 'outline-level)
216 (make-local-variable 'adaptive-fill-regexp)
217 (make-local-variable 'imenu-generic-expression) ;set in the mode functions
218 ;; Emacs 19.30 and beyond only, AFAIK
219 (if (boundp 'fill-paragraph-function)
220 (progn
221 (make-local-variable 'fill-paragraph-function)
222 (setq fill-paragraph-function 'c-fill-paragraph)))
223 ;; now set their values
224 (setq paragraph-start (concat page-delimiter "\\|$")
225 paragraph-separate paragraph-start
226 paragraph-ignore-fill-prefix t
227 require-final-newline t
228 parse-sexp-ignore-comments t
229 indent-line-function 'c-indent-line
230 indent-region-function 'c-indent-region
231 outline-regexp "[^#\n\^M]"
232 outline-level 'c-outline-level
233 comment-column 32
234 comment-start-skip "/\\*+ *\\|// *"
235 adaptive-fill-regexp nil)
236 ;; we have to do something special for c-offsets-alist so that the
237 ;; buffer local value has its own alist structure.
238 (setq c-offsets-alist (copy-alist c-offsets-alist))
239 ;; setup the comment indent variable in a Emacs version portable way
240 ;; ignore any byte compiler warnings you might get here
241 (make-local-variable 'comment-indent-function)
242 (setq comment-indent-function 'c-comment-indent)
243 ;; add menus to menubar
244 (easy-menu-add (c-mode-menu mode-name))
245 ;; put auto-hungry designators onto minor-mode-alist, but only once
246 (or (assq 'c-auto-hungry-string minor-mode-alist)
247 (setq minor-mode-alist
248 (cons '(c-auto-hungry-string c-auto-hungry-string)
249 minor-mode-alist))))
250
251(defun c-postprocess-file-styles ()
252 "Function that post processes relevant file local variables.
253Currently, this function simply applies any style and offset settings
254found in the file's Local Variable list. It first applies any style
255setting found in `c-file-style', then it applies any offset settings
256it finds in `c-file-offsets'."
257 ;; apply file styles and offsets
258 (and c-file-style
259 (c-set-style c-file-style))
260 (and c-file-offsets
261 (mapcar
262 (function
263 (lambda (langentry)
264 (let ((langelem (car langentry))
265 (offset (cdr langentry)))
266 (c-set-offset langelem offset)
267 )))
268 c-file-offsets)))
269
270(add-hook 'hack-local-variables-hook 'c-postprocess-file-styles)
271
272
273;; Common routines
274(defsubst c-make-inherited-keymap ()
275 (let ((map (make-sparse-keymap)))
276 (cond
277 ;; XEmacs 19 & 20
278 ((fboundp 'set-keymap-parents)
279 (set-keymap-parents map c-mode-base-map))
280 ;; Emacs 19
281 ((fboundp 'set-keymap-parent)
282 (set-keymap-parent map c-mode-base-map))
283 ;; incompatible
284 (t (error "CC Mode is incompatible with this version of Emacs")))
285 map))
286
287(defun c-populate-syntax-table (table)
288 ;; Populate the syntax TABLE
289 ;; DO NOT TRY TO SET _ (UNDERSCORE) TO WORD CLASS!
290 (modify-syntax-entry ?_ "_" table)
291 (modify-syntax-entry ?\\ "\\" table)
292 (modify-syntax-entry ?+ "." table)
293 (modify-syntax-entry ?- "." table)
294 (modify-syntax-entry ?= "." table)
295 (modify-syntax-entry ?% "." table)
296 (modify-syntax-entry ?< "." table)
297 (modify-syntax-entry ?> "." table)
298 (modify-syntax-entry ?& "." table)
299 (modify-syntax-entry ?| "." table)
300 (modify-syntax-entry ?\' "\"" table))
301
302(defun c-setup-dual-comments (table)
303 ;; Set up TABLE to handle block and line style comments
304 (cond
305 ;; XEmacs 19 & 20
306 ((memq '8-bit c-emacs-features)
307 (modify-syntax-entry ?/ ". 1456" table)
308 (modify-syntax-entry ?* ". 23" table)
309 (modify-syntax-entry ?\n "> b" table)
310 ;; Give CR the same syntax as newline, for selective-display
311 (modify-syntax-entry ?\^m "> b" table))
312 ;; Emacs 19
313 ((memq '1-bit c-emacs-features)
314 (modify-syntax-entry ?/ ". 124b" table)
315 (modify-syntax-entry ?* ". 23" table)
316 (modify-syntax-entry ?\n "> b" table)
317 ;; Give CR the same syntax as newline, for selective-display
318 (modify-syntax-entry ?\^m "> b" table))
319 ;; incompatible
320 (t (error "CC Mode is incompatible with this version of Emacs"))
321 ))
322
323(defvar c-mode-base-map ()
324 "Keymap shared by all CC Mode related modes.")
325
326(if c-mode-base-map
327 nil
328 ;; TBD: should we even worry about naming this keymap. My vote: no,
329 ;; because Emacs and XEmacs do it differently.
330 (setq c-mode-base-map (make-sparse-keymap))
331 ;; put standard keybindings into MAP
332 ;; the following mappings correspond more or less directly to BOCM
333 (define-key c-mode-base-map "{" 'c-electric-brace)
334 (define-key c-mode-base-map "}" 'c-electric-brace)
335 (define-key c-mode-base-map ";" 'c-electric-semi&comma)
336 (define-key c-mode-base-map "#" 'c-electric-pound)
337 (define-key c-mode-base-map ":" 'c-electric-colon)
338 ;; Lucid Emacs 19.9 defined these two, the second of which was
339 ;; commented out...
340 ;; (define-key c-mode-base-map "\e{" 'c-insert-braces)
341 ;; Commented out electric square brackets because nobody likes them.
342 ;; (define-key c-mode-base-map "[" 'c-insert-brackets)
343 (define-key c-mode-base-map "\C-c\C-m" 'c-mark-function)
344 (define-key c-mode-base-map "\e\C-q" 'c-indent-exp)
345 (define-key c-mode-base-map "\ea" 'c-beginning-of-statement)
346 (define-key c-mode-base-map "\ee" 'c-end-of-statement)
347 (define-key c-mode-base-map "\C-c\C-n" 'c-forward-conditional)
348 (define-key c-mode-base-map "\C-c\C-p" 'c-backward-conditional)
349 (define-key c-mode-base-map "\C-c\C-u" 'c-up-conditional)
350 (define-key c-mode-base-map "\t" 'c-indent-command)
351 ;; Caution! Enter here at your own risk. We are trying to support
352 ;; several behaviors and it gets disgusting. :-(
353 ;;
354 ;; In XEmacs 19, Emacs 19, and Emacs 20, we use this to bind
355 ;; backwards deletion behavior to DEL, which both Delete and
356 ;; Backspace get translated to. There's no way to separate this
357 ;; behavior in a clean way, so deal with it! Besides, it's been
358 ;; this way since the dawn of BOCM.
359 (if (not (boundp 'delete-key-deletes-forward))
360 (define-key c-mode-base-map "\177" 'c-electric-backspace)
361 ;; However, XEmacs 20 actually achieved enlightenment. It is
362 ;; possible to sanely define both backward and forward deletion
363 ;; behavior under X separately (TTYs are forever beyond hope, but
364 ;; who cares? XEmacs 20 does the right thing with these too).
365 (define-key c-mode-base-map [delete] 'c-electric-delete)
366 (define-key c-mode-base-map [backspace] 'c-electric-backspace))
367 ;; these are new keybindings, with no counterpart to BOCM
368 (define-key c-mode-base-map "," 'c-electric-semi&comma)
369 (define-key c-mode-base-map "*" 'c-electric-star)
370 (define-key c-mode-base-map "\C-c\C-q" 'c-indent-defun)
371 (define-key c-mode-base-map "\C-c\C-\\" 'c-backslash-region)
372 ;; TBD: where if anywhere, to put c-backward|forward-into-nomenclature
373 (define-key c-mode-base-map "\C-c\C-a" 'c-toggle-auto-state)
374 (define-key c-mode-base-map "\C-c\C-b" 'c-submit-bug-report)
375 (define-key c-mode-base-map "\C-c\C-c" 'comment-region)
376 (define-key c-mode-base-map "\C-c\C-d" 'c-toggle-hungry-state)
377 (define-key c-mode-base-map "\C-c\C-e" 'c-macro-expand)
378 (define-key c-mode-base-map "\C-c\C-o" 'c-set-offset)
379 (define-key c-mode-base-map "\C-c\C-s" 'c-show-syntactic-information)
380 (define-key c-mode-base-map "\C-c\C-t" 'c-toggle-auto-hungry-state)
381 (define-key c-mode-base-map "\C-c." 'c-set-style)
382 ;; conflicts with OOBR
383 ;;(define-key c-mode-base-map "\C-c\C-v" 'c-version)
384 )
385
386;; menu support for both XEmacs and Emacs. If you don't have easymenu
387;; with your version of Emacs, you are incompatible!
388(require 'easymenu)
389
390(defvar c-c-menu nil)
391(defvar c-c++-menu nil)
392(defvar c-objc-menu nil)
393(defvar c-java-menu nil)
394
395(defun c-mode-menu (modestr)
396 (let ((m
397 '(["Comment Out Region" comment-region (mark)]
398 ["Macro Expand Region" c-macro-expand (mark)]
399 ["Backslashify" c-backslash-region (mark)]
400 ["Indent Expression" c-indent-exp
401 (memq (char-after) '(?\( ?\[ ?\{))]
402 ["Indent Line" c-indent-command t]
403 ["Fill Comment Paragraph" c-fill-paragraph t]
404 ["Up Conditional" c-up-conditional t]
405 ["Backward Conditional" c-backward-conditional t]
406 ["Forward Conditional" c-forward-conditional t]
407 ["Backward Statement" c-beginning-of-statement t]
408 ["Forward Statement" c-end-of-statement t]
409 )))
410 (cons modestr m)))
411
412
413
414;; Support for C
415
416(defvar c-mode-abbrev-table nil
417 "Abbrev table in use in c-mode buffers.")
418(define-abbrev-table 'c-mode-abbrev-table ())
419
420(defvar c-mode-map ()
421 "Keymap used in c-mode buffers.")
422(if c-mode-map
423 nil
424 (setq c-mode-map (c-make-inherited-keymap))
425 ;; add bindings which are only useful for C
426 )
427
428;;;###autoload
429(defvar c-mode-syntax-table nil
430 "Syntax table used in c-mode buffers.")
431(if c-mode-syntax-table
432 ()
433 (setq c-mode-syntax-table (make-syntax-table))
434 (c-populate-syntax-table c-mode-syntax-table)
435 ;; add extra comment syntax
436 (modify-syntax-entry ?/ ". 14" c-mode-syntax-table)
437 (modify-syntax-entry ?* ". 23" c-mode-syntax-table))
438
439(defun c-enable-//-in-c-mode ()
440 "Enables // as a comment delimiter in `c-mode'.
441ANSI C currently does *not* allow this, although many C compilers
442support optional C++ style comments. To use, call this function from
443your `.emacs' file before you visit any C files. The changes are
444global and affect all future `c-mode' buffers."
445 (c-setup-dual-comments c-mode-syntax-table)
446 (setq-default c-C-comment-start-regexp c-C++-comment-start-regexp))
447
448(easy-menu-define c-c-menu c-mode-map "C Mode Commands"
449 (c-mode-menu "C"))
450
451
452;; Support for C++
453
454(defvar c++-mode-abbrev-table nil
455 "Abbrev table in use in c++-mode buffers.")
456(define-abbrev-table 'c++-mode-abbrev-table ())
457
458(defvar c++-mode-map ()
459 "Keymap used in c++-mode buffers.")
460(if c++-mode-map
461 nil
462 (setq c++-mode-map (c-make-inherited-keymap))
463 ;; add bindings which are only useful for C++
464 (define-key c++-mode-map "\C-c:" 'c-scope-operator)
465 (define-key c++-mode-map "/" 'c-electric-slash)
466 (define-key c++-mode-map "<" 'c-electric-lt-gt)
467 (define-key c++-mode-map ">" 'c-electric-lt-gt))
468
469(defvar c++-mode-syntax-table nil
470 "Syntax table used in c++-mode buffers.")
471(if c++-mode-syntax-table
472 ()
473 (setq c++-mode-syntax-table (make-syntax-table))
474 (c-populate-syntax-table c++-mode-syntax-table)
475 ;; add extra comment syntax
476 (c-setup-dual-comments c++-mode-syntax-table)
477 ;; TBD: does it make sense for colon to be symbol class in C++?
478 ;; I'm not so sure, since c-label-key is busted on lines like:
479 ;; Foo::bar( i );
480 ;; maybe c-label-key should be fixed instead of commenting this out,
481 ;; but it also bothers me that this only seems appropriate for C++
482 ;; and not C.
483 ;;(modify-syntax-entry ?: "_" c++-mode-syntax-table)
484 )
485
486(easy-menu-define c-c++-menu c++-mode-map "C++ Mode Commands"
487 (c-mode-menu "C++"))
488
489
490;; Support for Objective-C
491
492(defvar objc-mode-abbrev-table nil
493 "Abbrev table in use in objc-mode buffers.")
494(define-abbrev-table 'objc-mode-abbrev-table ())
495
496(defvar objc-mode-map ()
497 "Keymap used in objc-mode buffers.")
498(if objc-mode-map
499 nil
500 (setq objc-mode-map (c-make-inherited-keymap))
501 ;; add bindings which are only useful for Objective-C
502 (define-key objc-mode-map "/" 'c-electric-slash))
503
504(defvar objc-mode-syntax-table nil
505 "Syntax table used in objc-mode buffers.")
506(if objc-mode-syntax-table
507 ()
508 (setq objc-mode-syntax-table (make-syntax-table))
509 (c-populate-syntax-table objc-mode-syntax-table)
510 ;; add extra comment syntax
511 (c-setup-dual-comments objc-mode-syntax-table)
512 ;; everyone gets these
513 (modify-syntax-entry ?@ "_" objc-mode-syntax-table)
514 )
515
516(easy-menu-define c-objc-menu objc-mode-map "ObjC Mode Commands"
517 (c-mode-menu "ObjC"))
518
519
520;; Support for Java
521
522(defvar java-mode-abbrev-table nil
523 "Abbrev table in use in java-mode buffers.")
524(define-abbrev-table 'java-mode-abbrev-table ())
525
526(defvar java-mode-map ()
527 "Keymap used in java-mode buffers.")
528(if java-mode-map
529 nil
530 (setq java-mode-map (c-make-inherited-keymap))
531 ;; add bindings which are only useful for Java
532 (define-key java-mode-map "/" 'c-electric-slash))
533
534(defvar java-mode-syntax-table nil
535 "Syntax table used in java-mode buffers.")
536(if java-mode-syntax-table
537 ()
538 (setq java-mode-syntax-table (make-syntax-table))
539 (c-populate-syntax-table java-mode-syntax-table)
540 ;; add extra comment syntax
541 (c-setup-dual-comments java-mode-syntax-table)
542 ;; everyone gets these
543 (modify-syntax-entry ?@ "_" java-mode-syntax-table)
544 )
545
546(easy-menu-define c-java-menu java-mode-map "Java Mode Commands"
547 (c-mode-menu "Java"))
548
549
550(provide 'cc-langs)
551;;; cc-langs.el ends here
diff --git a/lisp/progmodes/cc-menus.el b/lisp/progmodes/cc-menus.el
new file mode 100644
index 00000000000..3f190a419b1
--- /dev/null
+++ b/lisp/progmodes/cc-menus.el
@@ -0,0 +1,103 @@
1;;; cc-menus.el --- imenu support for CC Mode
2
3;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
4
5;; Authors: 1992-1997 Barry A. Warsaw
6;; 1987 Dave Detlefs and Stewart Clamen
7;; 1985 Richard M. Stallman
8;; Maintainer: cc-mode-help@python.org
9;; Created: 22-Apr-1997 (split from cc-mode.el)
10;; Version: 5.12
11;; Keywords: c languages oop
12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software; you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation; either version 2, or (at your option)
18;; any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs; see the file COPYING. If not, write to the
27;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28;; Boston, MA 02111-1307, USA.
29
30
31;; imenu integration
32(defvar cc-imenu-c++-generic-expression
33 (`
34 ((nil
35 (,
36 (concat
37 "^" ; beginning of line is required
38 "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
39 "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; type specs; there can be no
40 "\\([a-zA-Z0-9_:]+[ \t]+\\)?" ; more than 3 tokens, right?
41
42 "\\(" ; last type spec including */&
43 "[a-zA-Z0-9_:]+"
44 "\\([ \t]*[*&]+[ \t]*\\|[ \t]+\\)" ; either ptr/ref sign or ws
45 "\\)?" ; if there is a last type spec
46 "\\(" ; name, take into the imenu entry
47 "[a-zA-Z0-9_:~]+" ; member func, ctor or dtor...
48 ; (may not contain * because then
49 ; "a::operator char*" would
50 ; become "char*"!)
51 "\\|"
52 "\\([a-zA-Z0-9_:~]*::\\)?operator"
53 "[^a-zA-Z1-9_][^(]*" ; ...or operator
54 " \\)"
55 "[ \t]*([^)]*)[ \t\n]*[^ ;]" ; require something other than
56 ; a `;' after the (...) to
57 ; avoid prototypes. Can't
58 ; catch cases with () inside
59 ; the parentheses surrounding
60 ; the parameters. e.g.:
61 ; "int foo(int a=bar()) {...}"
62
63 )) 6)
64 ("Class"
65 (, (concat
66 "^" ; beginning of line is required
67 "\\(template[ \t]*<[^>]+>[ \t]*\\)?" ; there may be a "template <...>"
68 "class[ \t]+"
69 "\\([a-zA-Z0-9_]+\\)" ; the string we want to get
70 "[ \t]*[:{]"
71 )) 2)))
72 "Imenu generic expression for C++ mode. See `imenu-generic-expression'.")
73
74(defvar cc-imenu-c-generic-expression
75 cc-imenu-c++-generic-expression
76 "Imenu generic expression for C mode. See `imenu-generic-expression'.")
77
78;(defvar cc-imenu-objc-generic-expression
79; ())
80; Please contribute one!
81
82(defvar cc-imenu-java-generic-expression
83 (`
84 ((nil
85 (,
86 (concat
87 "^\\([ \t]\\)*"
88 "\\([A-Za-z0-9_-]+[ \t]+\\)?" ; type specs; there can be
89 "\\([A-Za-z0-9_-]+[ \t]+\\)?" ; more than 3 tokens, right?
90 "\\([A-Za-z0-9_-]+[ \t]*[[]?[]]?\\)"
91 "\\([ \t]\\)"
92 "\\([A-Za-z0-9_-]+\\)" ; the string we want to get
93 "\\([ \t]*\\)+("
94 "\\([a-zA-Z,_1-9\n \t]*[[]?[]]?\\)*" ; arguments
95 ")[ \t]*"
96 "[^;(]"
97 "[,a-zA-Z_1-9\n \t]*{"
98 )) 6)))
99 "Imenu generic expression for Java mode. See `imenu-generic-expression'.")
100
101
102(provide 'cc-menus)
103;;; cc-menus.el ends here
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
new file mode 100644
index 00000000000..b178a42e199
--- /dev/null
+++ b/lisp/progmodes/cc-mode.el
@@ -0,0 +1,344 @@
1;;; cc-mode.el --- major mode for editing C, C++, Objective-C, and Java code
2
3;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
4
5;; Authors: 1992-1997 Barry A. Warsaw
6;; 1987 Dave Detlefs and Stewart Clamen
7;; 1985 Richard M. Stallman
8;; Maintainer: cc-mode-help@python.org
9;; Created: a long, long, time ago. adapted from the original c-mode.el
10;; Version: 5.12
11;; Keywords: c languages oop
12
13;; NOTE: Read the commentary below for the right way to submit bug reports!
14;; NOTE: See the accompanying texinfo manual for details on using this mode!
15
16;; This file is part of GNU Emacs.
17
18;; GNU Emacs is free software; you can redistribute it and/or modify
19;; it under the terms of the GNU General Public License as published by
20;; the Free Software Foundation; either version 2, or (at your option)
21;; any later version.
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
29;; along with GNU Emacs; see the file COPYING. If not, write to the
30;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
31;; Boston, MA 02111-1307, USA.
32
33;;; Commentary:
34
35;; This package provides GNU Emacs major modes for editing C, C++,
36;; Objective-C, and Java code. As of the latest Emacs and XEmacs
37;; releases, it is the default package for editing these languages.
38;; This package is called "CC Mode", and should be spelled exactly
39;; this way. It supports K&R and ANSI C, ANSI C++, Objective-C, and
40;; Java, with a consistent indentation model across all modes. This
41;; indentation model is intuitive and very flexible, so that almost
42;; any desired style of indentation can be supported. Installation,
43;; usage, and programming details are contained in an accompanying
44;; texinfo manual.
45
46;; CC Mode's immediate ancestors were, c++-mode.el, cplus-md.el, and
47;; cplus-md1.el..
48
49;; NOTE: This mode does not perform font-locking (a.k.a syntactic
50;; coloring, keyword highlighting, etc.) for any of the supported
51;; modes. Typically this is done by a package called font-lock.el
52;; which I do *not* maintain. You should contact the Emacs
53;; maintainers for questions about coloring or highlighting in any
54;; language mode.
55
56;; To submit bug reports, type "C-c C-b". These will be sent to
57;; bug-gnu-emacs@prep.ai.mit.edu as well as cc-mode-help@python.org,
58;; and I'll read about them there (the former is mirrored as the
59;; Usenet newsgroup gnu.emacs.bug). Questions can sent to
60;; help-gnu-emacs@prep.ai.mit.edu (mirrored as gnu.emacs.help) and/or
61;; cc-mode-help@python.org. Please do not send bugs or questions to
62;; my personal account.
63
64;; YOU CAN IGNORE ALL BYTE-COMPILER WARNINGS. They are the result of
65;; the cross-Emacsen support. GNU Emacs 19 (from the FSF), GNU XEmacs
66;; 19 (formerly Lucid Emacs), and GNU Emacs 18 all do things
67;; differently and there's no way to shut the byte-compiler up at the
68;; necessary granularity. Let me say this again: YOU CAN IGNORE ALL
69;; BYTE-COMPILER WARNINGS (you'd be surprised at how many people don't
70;; follow this advice :-).
71
72;; Many, many thanks go out to all the folks on the beta test list.
73;; Without their patience, testing, insight, code contributions, and
74;; encouragement CC Mode would be a far inferior package.
75
76;; You can get the latest version of CC Mode, including PostScript
77;; documentation and separate individual files from:
78;;
79;; http://www.python.org/ftp/emacs/
80
81;; Or if you don't have access to the World Wide Web, through
82;; anonymous ftp from:
83;;
84;; ftp://ftp.python.org/pub/emacs
85
86;;; Code:
87
88(eval-when-compile
89 (require 'cc-menus))
90(require 'cc-defs)
91
92
93;;;###autoload
94(defun c-mode ()
95 "Major mode for editing K&R and ANSI C code.
96To submit a problem report, enter `\\[c-submit-bug-report]' from a
97c-mode buffer. This automatically sets up a mail buffer with version
98information already added. You just need to add a description of the
99problem, including a reproducible test case and send the message.
100
101To see what version of CC Mode you are running, enter `\\[c-version]'.
102
103The hook variable `c-mode-hook' is run with no args, if that value is
104bound and has a non-nil value. Also the hook `c-mode-common-hook' is
105run first.
106
107Key bindings:
108\\{c-mode-map}"
109 (interactive)
110 (c-load-all)
111 (kill-all-local-variables)
112 (set-syntax-table c-mode-syntax-table)
113 (setq major-mode 'c-mode
114 mode-name "C"
115 local-abbrev-table c-mode-abbrev-table)
116 (use-local-map c-mode-map)
117 (c-common-init)
118 (setq comment-start "/* "
119 comment-end " */"
120 comment-multi-line t
121 c-conditional-key c-C-conditional-key
122 c-class-key c-C-class-key
123 c-baseclass-key nil
124 c-comment-start-regexp c-C-comment-start-regexp
125 imenu-generic-expression cc-imenu-c-generic-expression)
126 (run-hooks 'c-mode-common-hook)
127 (run-hooks 'c-mode-hook)
128 (c-update-modeline))
129
130
131;;;###autoload
132(defun c++-mode ()
133 "Major mode for editing C++ code.
134To submit a problem report, enter `\\[c-submit-bug-report]' from a
135c++-mode buffer. This automatically sets up a mail buffer with
136version information already added. You just need to add a description
137of the problem, including a reproducible test case, and send the
138message.
139
140To see what version of CC Mode you are running, enter `\\[c-version]'.
141
142The hook variable `c++-mode-hook' is run with no args, if that
143variable is bound and has a non-nil value. Also the hook
144`c-mode-common-hook' is run first.
145
146Key bindings:
147\\{c++-mode-map}"
148 (interactive)
149 (c-load-all)
150 (kill-all-local-variables)
151 (set-syntax-table c++-mode-syntax-table)
152 (setq major-mode 'c++-mode
153 mode-name "C++"
154 local-abbrev-table c++-mode-abbrev-table)
155 (use-local-map c++-mode-map)
156 (c-common-init)
157 (setq comment-start "// "
158 comment-end ""
159 comment-multi-line nil
160 c-conditional-key c-C++-conditional-key
161 c-comment-start-regexp c-C++-comment-start-regexp
162 c-class-key c-C++-class-key
163 c-access-key c-C++-access-key
164 c-double-slash-is-comments-p t
165 c-recognize-knr-p nil
166 imenu-generic-expression cc-imenu-c++-generic-expression)
167 (run-hooks 'c-mode-common-hook)
168 (run-hooks 'c++-mode-hook)
169 (c-update-modeline))
170
171
172;;;###autoload
173(defun objc-mode ()
174 "Major mode for editing Objective C code.
175To submit a problem report, enter `\\[c-submit-bug-report]' from an
176objc-mode buffer. This automatically sets up a mail buffer with
177version information already added. You just need to add a description
178of the problem, including a reproducible test case, and send the
179message.
180
181To see what version of CC Mode you are running, enter `\\[c-version]'.
182
183The hook variable `objc-mode-hook' is run with no args, if that value
184is bound and has a non-nil value. Also the hook `c-mode-common-hook'
185is run first.
186
187Key bindings:
188\\{objc-mode-map}"
189 (interactive)
190 (c-load-all)
191 (kill-all-local-variables)
192 (set-syntax-table objc-mode-syntax-table)
193 (setq major-mode 'objc-mode
194 mode-name "ObjC"
195 local-abbrev-table objc-mode-abbrev-table)
196 (use-local-map objc-mode-map)
197 (c-common-init)
198 (setq comment-start "// "
199 comment-end ""
200 comment-multi-line nil
201 c-conditional-key c-C-conditional-key
202 c-comment-start-regexp c-C++-comment-start-regexp
203 c-class-key c-ObjC-class-key
204 c-baseclass-key nil
205 c-access-key c-ObjC-access-key
206 c-double-slash-is-comments-p t
207 c-method-key c-ObjC-method-key)
208 (run-hooks 'c-mode-common-hook)
209 (run-hooks 'objc-mode-hook)
210 (c-update-modeline))
211
212
213;;;###autoload
214(defun java-mode ()
215 "Major mode for editing Java code.
216To submit a problem report, enter `\\[c-submit-bug-report]' from an
217java-mode buffer. This automatically sets up a mail buffer with
218version information already added. You just need to add a description
219of the problem, including a reproducible test case and send the
220message.
221
222To see what version of CC Mode you are running, enter `\\[c-version]'.
223
224The hook variable `java-mode-hook' is run with no args, if that value
225is bound and has a non-nil value. Also the common hook
226`c-mode-common-hook' is run first. Note that this mode automatically
227sets the \"java\" style before calling any hooks so be careful if you
228set styles in `c-mode-common-hook'.
229
230Key bindings:
231\\{java-mode-map}"
232 (interactive)
233 (c-load-all)
234 (kill-all-local-variables)
235 (set-syntax-table java-mode-syntax-table)
236 (setq major-mode 'java-mode
237 mode-name "Java"
238 local-abbrev-table java-mode-abbrev-table)
239 (use-local-map java-mode-map)
240 (c-common-init)
241 (setq comment-start "// "
242 comment-end ""
243 comment-multi-line nil
244 c-conditional-key c-Java-conditional-key
245 c-comment-start-regexp c-Java-comment-start-regexp
246 c-class-key c-Java-class-key
247 c-method-key c-Java-method-key
248 c-double-slash-is-comments-p t
249 c-baseclass-key nil
250 c-recognize-knr-p nil
251 c-access-key c-Java-access-key
252 ;defun-prompt-regexp c-Java-defun-prompt-regexp
253 imenu-generic-expression cc-imenu-java-generic-expression
254 )
255 (c-set-style "java")
256 (run-hooks 'c-mode-common-hook)
257 (run-hooks 'java-mode-hook)
258 (c-update-modeline))
259
260
261;; defuns for submitting bug reports
262(defconst c-version "5.12"
263 "CC Mode version number.")
264
265(defconst c-mode-help-address
266 "bug-gnu-emacs@prep.ai.mit.edu, cc-mode-help@python.org"
267 "Address for CC Mode bug reports.")
268
269(defun c-version ()
270 "Echo the current version of CC Mode in the minibuffer."
271 (interactive)
272 (message "Using CC Mode version %s" c-version)
273 (c-keep-region-active))
274
275;; Get reporter-submit-bug-report when byte-compiling
276(eval-when-compile
277 (require 'reporter))
278
279(defun c-submit-bug-report ()
280 "Submit via mail a bug report on CC Mode."
281 (interactive)
282 (require 'cc-vars)
283 ;; load in reporter
284 (let ((reporter-prompt-for-summary-p t)
285 (reporter-dont-compact-list '(c-offsets-alist))
286 (style c-indentation-style)
287 (hook c-special-indent-hook)
288 (c-features c-emacs-features))
289 (and
290 (if (y-or-n-p "Do you want to submit a report on CC Mode? ")
291 t (message "") nil)
292 (require 'reporter)
293 (reporter-submit-bug-report
294 c-mode-help-address
295 (concat "CC Mode " c-version " ("
296 (cond ((eq major-mode 'c++-mode) "C++")
297 ((eq major-mode 'c-mode) "C")
298 ((eq major-mode 'objc-mode) "ObjC")
299 ((eq major-mode 'java-mode) "Java")
300 )
301 ")")
302 (let ((vars (list
303 ;; report only the vars that affect indentation
304 'c-basic-offset
305 'c-offsets-alist
306 'c-cleanup-list
307 'c-comment-only-line-offset
308 'c-backslash-column
309 'c-delete-function
310 'c-electric-pound-behavior
311 'c-hanging-braces-alist
312 'c-hanging-colons-alist
313 'c-hanging-comment-starter-p
314 'c-hanging-comment-ender-p
315 'c-indent-comments-syntactically-p
316 'c-tab-always-indent
317 'c-recognize-knr-p
318 'c-label-minimum-indentation
319 'defun-prompt-regexp
320 'tab-width
321 )))
322 (if (not (boundp 'defun-prompt-regexp))
323 (delq 'defun-prompt-regexp vars)
324 vars))
325 (function
326 (lambda ()
327 (insert
328 "Buffer Style: " style "\n\n"
329 (if hook
330 (concat "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n"
331 "c-special-indent-hook is set to '"
332 (format "%s" hook)
333 ".\nPerhaps this is your problem?\n"
334 "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n\n")
335 "\n")
336 (format "c-emacs-features: %s\n" c-features)
337 )))
338 nil
339 "Dear Barry,"
340 ))))
341
342
343(provide 'cc-mode)
344;;; cc-mode.el ends here
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
new file mode 100644
index 00000000000..975796d7b79
--- /dev/null
+++ b/lisp/progmodes/cc-styles.el
@@ -0,0 +1,617 @@
1;;; cc-styles.el --- support for styles in CC Mode
2
3;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
4
5;; Authors: 1992-1997 Barry A. Warsaw
6;; 1987 Dave Detlefs and Stewart Clamen
7;; 1985 Richard M. Stallman
8;; Maintainer: cc-mode-help@python.org
9;; Created: 22-Apr-1997 (split from cc-mode.el)
10;; Version: 5.12
11;; Keywords: c languages oop
12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software; you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation; either version 2, or (at your option)
18;; any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs; see the file COPYING. If not, write to the
27;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28;; Boston, MA 02111-1307, USA.
29
30
31
32(defconst c-style-alist
33 '(("gnu"
34 (c-basic-offset . 2)
35 (c-comment-only-line-offset . (0 . 0))
36 (c-offsets-alist . ((statement-block-intro . +)
37 (knr-argdecl-intro . 5)
38 (substatement-open . +)
39 (label . 0)
40 (statement-case-open . +)
41 (statement-cont . +)
42 (arglist-intro . c-lineup-arglist-intro-after-paren)
43 (arglist-close . c-lineup-arglist)
44 ))
45 (c-special-indent-hook . c-gnu-impose-minimum)
46 )
47 ("k&r"
48 (c-basic-offset . 5)
49 (c-comment-only-line-offset . 0)
50 (c-offsets-alist . ((statement-block-intro . +)
51 (knr-argdecl-intro . 0)
52 (substatement-open . 0)
53 (label . 0)
54 (statement-cont . +)
55 ))
56 )
57 ("bsd"
58 (c-basic-offset . 4)
59 (c-comment-only-line-offset . 0)
60 (c-offsets-alist . ((statement-block-intro . +)
61 (knr-argdecl-intro . +)
62 (substatement-open . 0)
63 (label . 0)
64 (statement-cont . +)
65 ))
66 )
67 ("stroustrup"
68 (c-basic-offset . 4)
69 (c-comment-only-line-offset . 0)
70 (c-offsets-alist . ((statement-block-intro . +)
71 (substatement-open . 0)
72 (label . 0)
73 (statement-cont . +)
74 ))
75 )
76 ("whitesmith"
77 (c-basic-offset . 4)
78 (c-comment-only-line-offset . 0)
79 (c-offsets-alist . ((statement-block-intro . +)
80 (knr-argdecl-intro . +)
81 (substatement-open . 0)
82 (label . 0)
83 (statement-cont . +)
84 ))
85
86 )
87 ("ellemtel"
88 (c-basic-offset . 3)
89 (c-comment-only-line-offset . 0)
90 (c-hanging-braces-alist . ((substatement-open before after)))
91 (c-offsets-alist . ((topmost-intro . 0)
92 (topmost-intro-cont . 0)
93 (substatement . +)
94 (substatement-open . 0)
95 (case-label . +)
96 (access-label . -)
97 (inclass . ++)
98 (inline-open . 0)
99 ))
100 )
101 ("linux"
102 (c-basic-offset . 8)
103 (c-comment-only-line-offset . 0)
104 (c-hanging-braces-alist . ((brace-list-open)
105 (substatement-open after)
106 (block-close . c-snug-do-while)))
107 (c-cleanup-list . (brace-else-brace))
108 (c-offsets-alist . ((statement-block-intro . +)
109 (knr-argdecl-intro . 0)
110 (substatement-open . 0)
111 (label . 0)
112 (statement-cont . +)
113 ))
114 )
115 ("python"
116 (indent-tabs-mode . t)
117 (fill-column . 72)
118 (c-basic-offset . 8)
119 (c-offsets-alist . ((substatement-open . 0)
120 ))
121 (c-hanging-braces-alist . ((brace-list-open)
122 (brace-list-intro)
123 (brace-list-close)
124 (substatement-open after)
125 (block-close . c-snug-do-while)
126 ))
127 )
128 ("java"
129 (c-basic-offset . 2)
130 (c-comment-only-line-offset . (0 . 0))
131 (c-offsets-alist . ((topmost-intro-cont . +)
132 (statement-block-intro . +)
133 (knr-argdecl-intro . 5)
134 (substatement-open . +)
135 (label . 0)
136 (statement-case-open . +)
137 (statement-cont . +)
138 (arglist-intro . c-lineup-arglist-intro-after-paren)
139 (arglist-close . c-lineup-arglist)
140 (access-label . 0)
141 (inher-cont . c-lineup-java-inher)
142 (func-decl-cont . c-lineup-java-throws)
143 ))
144
145 )
146 )
147 "Styles of indentation.
148Elements of this alist are of the form:
149
150 (STYLE-STRING [BASE-STYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
151
152where STYLE-STRING is a short descriptive string used to select a
153style, VARIABLE is any Emacs variable, and VALUE is the intended value
154for that variable when using the selected style.
155
156Optional BASE-STYLE if present, is a string and must follow
157STYLE-STRING. BASE-STYLE names a style that this style inherits from.
158By default, all styles inherit from the \"cc-mode\" style, which is
159computed at run time. Style loops generate errors.
160
161Two variables are treated specially. When VARIABLE is
162`c-offsets-alist', the VALUE is a list containing elements of the
163form:
164
165 (SYNTACTIC-SYMBOL . OFFSET)
166
167as described in `c-offsets-alist'. These are passed directly to
168`c-set-offset' so there is no need to set every syntactic symbol in
169your style, only those that are different from the default.
170
171When VARIABLE is `c-special-indent-hook', its VALUE is added to
172`c-special-indent-hook' using `add-hook'. If VALUE is a list, each
173element of the list is added with `add-hook'.
174
175Do not change this variable directly. Use the function `c-add-style'
176to add new styles or modify existing styles (it is not a good idea to
177modify existing styles -- you should create a new style that inherits
178the existing style.")
179
180
181;; Functions that manipulate styles
182(defun c-set-style-1 (conscell)
183 ;; Set the style for one variable
184 (let ((attr (car conscell))
185 (val (cdr conscell)))
186 (cond
187 ;; first special variable
188 ((eq attr 'c-offsets-alist)
189 (mapcar
190 (function
191 (lambda (langentry)
192 (let ((langelem (car langentry))
193 (offset (cdr langentry)))
194 (c-set-offset langelem offset)
195 )))
196 val))
197 ;; second special variable
198 ((eq attr 'c-special-indent-hook)
199 (if (listp val)
200 (while val
201 (add-hook 'c-special-indent-hook (car val))
202 (setq val (cdr val)))
203 (add-hook 'c-special-indent-hook val)))
204 ;; all other variables
205 (t (set attr val)))
206 ))
207
208(defun c-set-style-2 (style basestyles)
209 ;; Recursively set the base style. If no base style is given, the
210 ;; default base style is "cc-mode" and the recursion stops. Be sure
211 ;; to detect loops.
212 (if (not (string-equal style "cc-mode"))
213 (let ((base (if (stringp (car basestyles))
214 (downcase (car basestyles))
215 "cc-mode")))
216 (if (memq base basestyles)
217 (error "Style loop detected: %s in %s" base basestyles))
218 (c-set-style-2 base (cons base basestyles))))
219 (let ((vars (cdr (or (assoc (downcase style) c-style-alist)
220 (assoc (upcase style) c-style-alist)
221 (assoc style c-style-alist)
222 (error "Undefined style: %s" style)))))
223 (mapcar 'c-set-style-1 vars)))
224
225(defvar c-set-style-history nil)
226
227;;;###autoload
228(defun c-set-style (stylename)
229 "Set CC Mode variables to use one of several different indentation styles.
230STYLENAME is a string representing the desired style from the list of
231styles described in the variable `c-style-alist'. See that variable
232for details of setting up styles.
233
234The variable `c-indentation-style' always contains the buffer's current
235style name."
236 (interactive (list (let ((completion-ignore-case t)
237 (prompt (format "Which %s indentation style? "
238 mode-name)))
239 (completing-read prompt c-style-alist nil t
240 (cons c-indentation-style 0)
241 'c-set-style-history))))
242 (c-set-style-2 stylename nil)
243 (setq c-indentation-style stylename)
244 (c-keep-region-active))
245
246;;;###autoload
247(defun c-add-style (style descrip &optional set-p)
248 "Adds a style to `c-style-alist', or updates an existing one.
249STYLE is a string identifying the style to add or update. DESCRIP is
250an association list describing the style and must be of the form:
251
252 ([BASESTYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
253
254See the variable `c-style-alist' for the semantics of BASESTYLE,
255VARIABLE and VALUE. This function also sets the current style to
256STYLE using `c-set-style' if the optional SET-P flag is non-nil."
257 (interactive
258 (let ((stylename (completing-read "Style to add: " c-style-alist
259 nil nil nil 'c-set-style-history))
260 (description (eval-minibuffer "Style description: ")))
261 (list stylename description
262 (y-or-n-p "Set the style too? "))))
263 (setq style (downcase style))
264 (let ((s (assoc style c-style-alist)))
265 (if s
266 (setcdr s (copy-alist descrip)) ; replace
267 (setq c-style-alist (cons (cons style descrip) c-style-alist))))
268 (and set-p (c-set-style style)))
269
270
271
272(defconst c-offsets-alist
273 '((string . -1000)
274 (c . c-lineup-C-comments)
275 (defun-open . 0)
276 (defun-close . 0)
277 (defun-block-intro . +)
278 (class-open . 0)
279 (class-close . 0)
280 (inline-open . +)
281 (inline-close . 0)
282 (func-decl-cont . +)
283 (knr-argdecl-intro . +)
284 (knr-argdecl . 0)
285 (topmost-intro . 0)
286 (topmost-intro-cont . 0)
287 (member-init-intro . +)
288 (member-init-cont . 0)
289 (inher-intro . +)
290 (inher-cont . c-lineup-multi-inher)
291 (block-open . 0)
292 (block-close . 0)
293 (brace-list-open . 0)
294 (brace-list-close . 0)
295 (brace-list-intro . +)
296 (brace-list-entry . 0)
297 (statement . 0)
298 ;; some people might prefer
299 ;;(statement . c-lineup-runin-statements)
300 (statement-cont . +)
301 ;; some people might prefer
302 ;;(statement-cont . c-lineup-math)
303 (statement-block-intro . +)
304 (statement-case-intro . +)
305 (statement-case-open . 0)
306 (substatement . +)
307 (substatement-open . +)
308 (case-label . 0)
309 (access-label . -)
310 (label . 2)
311 (do-while-closure . 0)
312 (else-clause . 0)
313 (comment-intro . c-lineup-comment)
314 (arglist-intro . +)
315 (arglist-cont . 0)
316 (arglist-cont-nonempty . c-lineup-arglist)
317 (arglist-close . +)
318 (stream-op . c-lineup-streamop)
319 (inclass . +)
320 (cpp-macro . -1000)
321 (friend . 0)
322 (objc-method-intro . -1000)
323 (objc-method-args-cont . c-lineup-ObjC-method-args)
324 (objc-method-call-cont . c-lineup-ObjC-method-call)
325 (extern-lang-open . 0)
326 (extern-lang-close . 0)
327 (inextern-lang . +)
328 )
329 "Association list of syntactic element symbols and indentation offsets.
330As described below, each cons cell in this list has the form:
331
332 (SYNTACTIC-SYMBOL . OFFSET)
333
334When a line is indented, CC Mode first determines the syntactic
335context of the line by generating a list of symbols called syntactic
336elements. This list can contain more than one syntactic element and
337the global variable `c-syntactic-context' contains the context list
338for the line being indented. Each element in this list is actually a
339cons cell of the syntactic symbol and a buffer position. This buffer
340position is called the relative indent point for the line. Some
341syntactic symbols may not have a relative indent point associated with
342them.
343
344After the syntactic context list for a line is generated, CC Mode
345calculates the absolute indentation for the line by looking at each
346syntactic element in the list. First, it compares the syntactic
347element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'. When it
348finds a match, it adds the OFFSET to the column of the relative indent
349point. The sum of this calculation for each element in the syntactic
350list is the absolute offset for line being indented.
351
352If the syntactic element does not match any in the `c-offsets-alist',
353an error is generated if `c-strict-syntax-p' is non-nil, otherwise the
354element is ignored.
355
356Actually, OFFSET can be an integer, a function, a variable, or one of
357the following symbols: `+', `-', `++', `--', `*', or `/'. These
358latter designate positive or negative multiples of `c-basic-offset',
359respectively: 1, -1, 2, -2, 0.5, and -0.5. If OFFSET is a function, it
360is called with a single argument containing the cons of the syntactic
361element symbol and the relative indent point. The function should
362return an integer offset.
363
364Here is the current list of valid syntactic element symbols:
365
366 string -- inside multi-line string
367 c -- inside a multi-line C style block comment
368 defun-open -- brace that opens a function definition
369 defun-close -- brace that closes a function definition
370 defun-block-intro -- the first line in a top-level defun
371 class-open -- brace that opens a class definition
372 class-close -- brace that closes a class definition
373 inline-open -- brace that opens an in-class inline method
374 inline-close -- brace that closes an in-class inline method
375 func-decl-cont -- the region between a function definition's
376 argument list and the function opening brace
377 (excluding K&R argument declarations). In C, you
378 cannot put anything but whitespace and comments
379 between them; in C++ and Java, throws declarations
380 and other things can appear in this context.
381 knr-argdecl-intro -- first line of a K&R C argument declaration
382 knr-argdecl -- subsequent lines in a K&R C argument declaration
383 topmost-intro -- the first line in a topmost construct definition
384 topmost-intro-cont -- topmost definition continuation lines
385 member-init-intro -- first line in a member initialization list
386 member-init-cont -- subsequent member initialization list lines
387 inher-intro -- first line of a multiple inheritance list
388 inher-cont -- subsequent multiple inheritance lines
389 block-open -- statement block open brace
390 block-close -- statement block close brace
391 brace-list-open -- open brace of an enum or static array list
392 brace-list-close -- close brace of an enum or static array list
393 brace-list-intro -- first line in an enum or static array list
394 brace-list-entry -- subsequent lines in an enum or static array list
395 statement -- a C (or like) statement
396 statement-cont -- a continuation of a C (or like) statement
397 statement-block-intro -- the first line in a new statement block
398 statement-case-intro -- the first line in a case \"block\"
399 statement-case-open -- the first line in a case block starting with brace
400 substatement -- the first line after an if/while/for/do/else
401 substatement-open -- the brace that opens a substatement block
402 case-label -- a `case' or `default' label
403 access-label -- C++ private/protected/public access label
404 label -- any ordinary label
405 do-while-closure -- the `while' that ends a do/while construct
406 else-clause -- the `else' of an if/else construct
407 comment-intro -- a line containing only a comment introduction
408 arglist-intro -- the first line in an argument list
409 arglist-cont -- subsequent argument list lines when no
410 arguments follow on the same line as the
411 arglist opening paren
412 arglist-cont-nonempty -- subsequent argument list lines when at
413 least one argument follows on the same
414 line as the arglist opening paren
415 arglist-close -- the solo close paren of an argument list
416 stream-op -- lines continuing a stream operator construct
417 inclass -- the construct is nested inside a class definition
418 cpp-macro -- the start of a cpp macro
419 friend -- a C++ friend declaration
420 objc-method-intro -- the first line of an Objective-C method definition
421 objc-method-args-cont -- lines continuing an Objective-C method definition
422 objc-method-call-cont -- lines continuing an Objective-C method call
423 extern-lang-open -- brace that opens an external language block
424 extern-lang-close -- brace that closes an external language block
425 inextern-lang -- analogous to `inclass' syntactic symbol
426")
427
428(defun c-get-offset (langelem)
429 ;; Get offset from LANGELEM which is a cons cell of the form:
430 ;; (SYMBOL . RELPOS). The symbol is matched against
431 ;; c-offsets-alist and the offset found there is either returned,
432 ;; or added to the indentation at RELPOS. If RELPOS is nil, then
433 ;; the offset is simply returned.
434 (let* ((symbol (car langelem))
435 (relpos (cdr langelem))
436 (match (assq symbol c-offsets-alist))
437 (offset (cdr-safe match)))
438 ;; offset can be a number, a function, a variable, or one of the
439 ;; symbols + or -
440 (cond
441 ((not match)
442 (if c-strict-syntax-p
443 (error "don't know how to indent a %s" symbol)
444 (setq offset 0
445 relpos 0)))
446 ((eq offset '+) (setq offset c-basic-offset))
447 ((eq offset '-) (setq offset (- c-basic-offset)))
448 ((eq offset '++) (setq offset (* 2 c-basic-offset)))
449 ((eq offset '--) (setq offset (* 2 (- c-basic-offset))))
450 ((eq offset '*) (setq offset (/ c-basic-offset 2)))
451 ((eq offset '/) (setq offset (/ (- c-basic-offset) 2)))
452 ((functionp offset) (setq offset (funcall offset langelem)))
453 ((not (numberp offset)) (setq offset (symbol-value offset)))
454 )
455 (+ (if (and relpos
456 (< relpos (c-point 'bol)))
457 (save-excursion
458 (goto-char relpos)
459 (current-column))
460 0)
461 offset)))
462
463
464(defvar c-read-offset-history nil)
465
466(defun c-read-offset (langelem)
467 ;; read new offset value for LANGELEM from minibuffer. return a
468 ;; legal value only
469 (let* ((oldoff (cdr-safe (assq langelem c-offsets-alist)))
470 (defstr (format "(default %s): " oldoff))
471 (errmsg (concat "Offset must be int, func, var, "
472 "or in [+,-,++,--,*,/] "
473 defstr))
474 (prompt (concat "Offset " defstr))
475 offset input interned raw)
476 (while (not offset)
477 (setq input (completing-read prompt obarray 'fboundp nil nil
478 'c-read-offset-history)
479 offset (cond ((string-equal "" input) oldoff) ; default
480 ((string-equal "+" input) '+)
481 ((string-equal "-" input) '-)
482 ((string-equal "++" input) '++)
483 ((string-equal "--" input) '--)
484 ((string-equal "*" input) '*)
485 ((string-equal "/" input) '/)
486 ((string-match "^-?[0-9]+$" input)
487 (string-to-int input))
488 ;; a symbol with a function binding
489 ((fboundp (setq interned (intern input)))
490 interned)
491 ;; a lambda function
492 ((c-safe (functionp (setq raw (read input))))
493 raw)
494 ;; a symbol with variable binding
495 ((boundp interned) interned)
496 ;; error, but don't signal one, keep trying
497 ;; to read an input value
498 (t (ding)
499 (setq prompt errmsg)
500 nil))))
501 offset))
502
503(defun c-set-offset (symbol offset &optional add-p)
504 "Change the value of a syntactic element symbol in `c-offsets-alist'.
505SYMBOL is the syntactic element symbol to change and OFFSET is the new
506offset for that syntactic element. Optional ADD says to add SYMBOL to
507`c-offsets-alist' if it doesn't already appear there."
508 (interactive
509 (let* ((langelem
510 (intern (completing-read
511 (concat "Syntactic symbol to change"
512 (if current-prefix-arg " or add" "")
513 ": ")
514 (mapcar
515 #'(lambda (langelem)
516 (cons (format "%s" (car langelem)) nil))
517 c-offsets-alist)
518 nil (not current-prefix-arg)
519 ;; initial contents tries to be the last element
520 ;; on the syntactic analysis list for the current
521 ;; line
522 (let* ((syntax (c-guess-basic-syntax))
523 (len (length syntax))
524 (ic (format "%s" (car (nth (1- len) syntax)))))
525 (cons ic 0))
526 )))
527 (offset (c-read-offset langelem)))
528 (list langelem offset current-prefix-arg)))
529 ;; sanity check offset
530 (or (eq offset '+)
531 (eq offset '-)
532 (eq offset '++)
533 (eq offset '--)
534 (eq offset '*)
535 (eq offset '/)
536 (integerp offset)
537 (functionp offset)
538 (boundp offset)
539 (error "Offset must be int, func, var, or in [+,-,++,--,*,/]: %s"
540 offset))
541 (let ((entry (assq symbol c-offsets-alist)))
542 (if entry
543 (setcdr entry offset)
544 (if add-p
545 (setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
546 (error "%s is not a valid syntactic symbol." symbol))))
547 (c-keep-region-active))
548
549
550
551(defun c-initialize-builtin-style ()
552 ;; Dynamically append the default value of most variables. This is
553 ;; crucial because future c-set-style calls will always reset the
554 ;; variables first to the `cc-mode' style before instituting the new
555 ;; style. Only do this once!
556 (require 'cl)
557 (or (assoc "cc-mode" c-style-alist)
558 (progn
559 (c-add-style "cc-mode"
560 (mapcar
561 (function
562 (lambda (var)
563 (let ((val (symbol-value var)))
564 (cons var (if (atom val) val
565 (copy-tree val)
566 ))
567 )))
568 '(c-backslash-column
569 c-basic-offset
570 c-cleanup-list
571 c-comment-only-line-offset
572 c-electric-pound-behavior
573 c-hanging-braces-alist
574 c-hanging-colons-alist
575 c-hanging-comment-starter-p
576 c-hanging-comment-ender-p
577 c-offsets-alist
578 )))
579 ;; the default style is now GNU. This can be overridden in
580 ;; c-mode-common-hook or {c,c++,objc,java}-mode-hook.
581 (c-set-style c-site-default-style))))
582
583(defun c-make-styles-buffer-local ()
584 "Make all CC Mode style variables buffer local.
585If you edit primarily one style of C (or C++, Objective-C, Java) code,
586you probably want style variables to be global. This is the default.
587
588If you edit many different styles of C (or C++, Objective-C, Java) at
589the same time, you probably want the CC Mode style variables to be
590buffer local. If you do, then you will need to set any CC Mode style
591variables in a hook function (e.g. off of c-mode-common-hook), instead
592of at the top level of your ~/.emacs file.
593
594This function makes all the CC Mode style variables buffer local.
595Call it after CC Mode is loaded into your Emacs environment.
596Conversely, set the variable `c-style-variables-are-local-p' to t in
597your .emacs file, before CC Mode is loaded, and this function will be
598automatically called when CC Mode is loaded."
599 ;; style variables
600 (make-variable-buffer-local 'c-offsets-alist)
601 (make-variable-buffer-local 'c-basic-offset)
602 (make-variable-buffer-local 'c-file-style)
603 (make-variable-buffer-local 'c-file-offsets)
604 (make-variable-buffer-local 'c-comment-only-line-offset)
605 (make-variable-buffer-local 'c-cleanup-list)
606 (make-variable-buffer-local 'c-hanging-braces-alist)
607 (make-variable-buffer-local 'c-hanging-colons-alist)
608 (make-variable-buffer-local 'c-hanging-comment-starter-p)
609 (make-variable-buffer-local 'c-hanging-comment-ender-p)
610 (make-variable-buffer-local 'c-backslash-column)
611 (make-variable-buffer-local 'c-label-minimum-indentation)
612 (make-variable-buffer-local 'c-special-indent-hook)
613 (make-variable-buffer-local 'c-indentation-style))
614
615
616(provide 'cc-styles)
617;;; cc-styles.el ends here
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
new file mode 100644
index 00000000000..96e1b809ab8
--- /dev/null
+++ b/lisp/progmodes/cc-vars.el
@@ -0,0 +1,391 @@
1;;; cc-vars.el --- user customization variables for CC Mode
2
3;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
4
5;; Authors: 1992-1997 Barry A. Warsaw
6;; 1987 Dave Detlefs and Stewart Clamen
7;; 1985 Richard M. Stallman
8;; Maintainer: cc-mode-help@python.org
9;; Created: 22-Apr-1997 (split from cc-mode.el)
10;; Version: 5.12
11;; Keywords: c languages oop
12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software; you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation; either version 2, or (at your option)
18;; any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs; see the file COPYING. If not, write to the
27;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
28;; Boston, MA 02111-1307, USA.
29
30(require 'custom)
31
32
33(defcustom c-strict-syntax-p nil
34 "*If non-nil, all syntactic symbols must be found in `c-offsets-alist'.
35If the syntactic symbol for a particular line does not match a symbol
36in the offsets alist, an error is generated, otherwise no error is
37reported and the syntactic symbol is ignored."
38 :type 'boolean
39 :group 'c)
40
41(defcustom c-echo-syntactic-information-p nil
42 "*If non-nil, syntactic info is echoed when the line is indented."
43 :type 'boolean
44 :group 'c)
45
46(defcustom c-basic-offset 4
47 "*Amount of basic offset used by + and - symbols in `c-offsets-alist'."
48 :type 'integer
49 :group 'c)
50
51(defcustom c-tab-always-indent t
52 "*Controls the operation of the TAB key.
53If t, hitting TAB always just indents the current line. If nil,
54hitting TAB indents the current line if point is at the left margin or
55in the line's indentation, otherwise it insert a `real' tab character
56\(see note\). If other than nil or t, then tab is inserted only
57within literals -- defined as comments and strings -- and inside
58preprocessor directives, but line is always reindented.
59
60Note: The value of `indent-tabs-mode' will determine whether a real
61tab character will be inserted, or the equivalent number of space.
62When inserting a tab, actually the function stored in the variable
63`c-insert-tab-function' is called.
64
65Note: indentation of lines containing only comments is also controlled
66by the `c-comment-only-line-offset' variable."
67 :type '(radio
68 :extra-offset 8
69 :format "%{C Tab Always Indent%}:\n The TAB key:\n%v"
70 (const :tag "always indents, never inserts TAB" t)
71 (const :tag "indents in left margin, otherwise inserts TAB" nil)
72 (const :tag "inserts TAB in literals, otherwise indent" other))
73 :group 'c)
74
75(defcustom c-insert-tab-function 'insert-tab
76 "*Function used when inserting a tab for \\[TAB].
77Only used when `c-tab-always-indent' indicates a `real' tab character
78should be inserted. Value must be a function taking no arguments."
79 :type 'function
80 :group 'c)
81
82(defcustom c-comment-only-line-offset 0
83 "*Extra offset for line which contains only the start of a comment.
84Can contain an integer or a cons cell of the form:
85
86 (NON-ANCHORED-OFFSET . ANCHORED-OFFSET)
87
88Where NON-ANCHORED-OFFSET is the amount of offset given to
89non-column-zero anchored comment-only lines, and ANCHORED-OFFSET is
90the amount of offset to give column-zero anchored comment-only lines.
91Just an integer as value is equivalent to (<val> . -1000)."
92 :type '(choice (integer :tag "Non-anchored offset")
93 (cons :tag "Non-anchored & anchored offset"
94 :value (0 . 0)
95 :extra-offset 8
96 (integer :tag "Non-anchored offset")
97 (integer :tag "Anchored offset")))
98 :group 'c)
99
100(defcustom c-indent-comments-syntactically-p nil
101 "*Specifies how comment-only lines should be indented.
102When this variable is non-nil, comment-only lines are indented
103according to syntactic analysis via `c-offsets-alist', even when
104\\[indent-for-comment] is used."
105 :type 'boolean
106 :group 'c)
107
108(defcustom c-cleanup-list '(scope-operator)
109 "*List of various C/C++/ObjC constructs to \"clean up\".
110These clean ups only take place when the auto-newline feature is
111turned on, as evidenced by the `/a' or `/ah' appearing next to the
112mode name. Valid symbols are:
113
114 brace-else-brace -- cleans up `} else {' constructs by placing entire
115 construct on a single line. This clean up
116 only takes place when there is nothing but
117 white space between the braces and the `else'.
118 Clean up occurs when the open-brace after the
119 `else' is typed.
120 brace-elseif-brace -- similar to brace-else-brace, but cleans up
121 `} else if {' constructs.
122 empty-defun-braces -- cleans up empty defun braces by placing the
123 braces on the same line. Clean up occurs when
124 the defun closing brace is typed.
125 defun-close-semi -- cleans up the terminating semi-colon on defuns
126 by placing the semi-colon on the same line as
127 the closing brace. Clean up occurs when the
128 semi-colon is typed.
129 list-close-comma -- cleans up commas following braces in array
130 and aggregate initializers. Clean up occurs
131 when the comma is typed.
132 scope-operator -- cleans up double colons which may designate
133 a C++ scope operator split across multiple
134 lines. Note that certain C++ constructs can
135 generate ambiguous situations. This clean up
136 only takes place when there is nothing but
137 whitespace between colons. Clean up occurs
138 when the second colon is typed."
139 :type '(set
140 :extra-offset 8
141 (const :tag "Put `} else {' on one line" brace-else-brace)
142 (const :tag "Put `} else if {' on one line" brace-elseif-brace)
143 (const :tag "Put empty defun braces on one line" empty-defun-braces)
144 (const :tag "Put `},' in aggregates on one line" list-close-comma)
145 (const :tag "Put C++ style `::' on one line" scope-operator))
146 :group 'c)
147
148(defcustom c-hanging-braces-alist '((brace-list-open)
149 (substatement-open after)
150 (block-close . c-snug-do-while)
151 (extern-lang-open after)
152 )
153 "*Controls the insertion of newlines before and after braces.
154This variable contains an association list with elements of the
155following form: (SYNTACTIC-SYMBOL . ACTION).
156
157When a brace (either opening or closing) is inserted, the syntactic
158context it defines is looked up in this list, and if found, the
159associated ACTION is used to determine where newlines are inserted.
160If the context is not found, the default is to insert a newline both
161before and after the brace.
162
163SYNTACTIC-SYMBOL can be any of: defun-open, defun-close, class-open,
164class-close, inline-open, inline-close, block-open, block-close,
165substatement-open, statement-case-open, extern-lang-open,
166extern-lang-close, brace-list-open, brace-list-close,
167brace-list-intro, or brace-list-entry. See `c-offsets-alist' for
168details.
169
170ACTION can be either a function symbol or a list containing any
171combination of the symbols `before' or `after'. If the list is empty,
172no newlines are inserted either before or after the brace.
173
174When ACTION is a function symbol, the function is called with a two
175arguments: the syntactic symbol for the brace and the buffer position
176at which the brace was inserted. The function must return a list as
177described in the preceding paragraph. Note that during the call to
178the function, the variable `c-syntactic-context' is set to the entire
179syntactic context for the brace line."
180 :type '(repeat
181 (cons :format "%v"
182 (choice :tag "Syntax"
183 (const defun-open) (const defun-close)
184 (const class-open) (const class-close)
185 (const inline-open) (const inline-close)
186 (const block-open) (const block-close)
187 (const substatement-open) (const statement-case-open)
188 (const extern-lang-open) (const extern-lang-close)
189 (const brace-list-open) (const brace-list-close)
190 (const brace-list-intro) (const brace-list-entry))
191 (choice :tag "Action"
192 (set :format "Insert a newline %v"
193 :extra-offset 38
194 (const :tag "before brace" before)
195 (const :tag "after brace" after))
196 (function :format "Run function %v" :value c-)
197 )))
198 :group 'c)
199
200(defcustom c-hanging-colons-alist nil
201 "*Controls the insertion of newlines before and after certain colons.
202This variable contains an association list with elements of the
203following form: (SYNTACTIC-SYMBOL . ACTION).
204
205SYNTACTIC-SYMBOL can be any of: case-label, label, access-label,
206member-init-intro, or inher-intro.
207
208See the variable `c-hanging-braces-alist' for the semantics of this
209variable. Note however that making ACTION a function symbol is
210currently not supported for this variable."
211 :type '(repeat
212 (cons :format "%v"
213 (choice :tag "Syntax"
214 (const case-label) (const label) (const access-label)
215 (const member-init-intro) (const inher-intro))
216 (set :tag "Action"
217 :format "%t: %v"
218 :extra-offset 8
219 (const before) (const after))))
220 :group 'c)
221
222(defcustom c-hanging-semi&comma-criteria '(c-semi&comma-inside-parenlist)
223 "*List of functions that decide whether to insert a newline or not.
224The functions in this list are called, in order, whenever the
225auto-newline minor mode is activated (as evidenced by a `/a' or `/ah'
226string in the mode line), and a semicolon or comma is typed (see
227`c-electric-semi&comma'). Each function in this list is called with
228no arguments, and should return one of the following values:
229
230 nil -- no determination made, continue checking
231 'stop -- do not insert a newline, and stop checking
232 (anything else) -- insert a newline, and stop checking
233
234If every function in the list is called with no determination made,
235then no newline is inserted."
236 :type '(repeat function)
237 :group 'c)
238
239(defcustom c-hanging-comment-ender-p t
240 "*Controls what \\[fill-paragraph] does to C block comment enders.
241When set to nil, C block comment enders are left on their own line.
242When set to t, block comment enders will be placed at the end of the
243previous line (i.e. they `hang' on that line)."
244 :type 'boolean
245 :group 'c)
246
247(defcustom c-hanging-comment-starter-p t
248 "*Controls what \\[fill-paragraph] does to C block comment starters.
249When set to nil, C block comment starters are left on their own line.
250When set to t, text that follows a block comment starter will be
251placed on the same line as the block comment starter (i.e. the text
252`hangs' on that line)."
253 :type 'boolean
254 :group 'c)
255
256(defcustom c-backslash-column 48
257 "*Column to insert backslashes when macroizing a region."
258 :type 'integer
259 :group 'c)
260
261(defcustom c-special-indent-hook nil
262 "*Hook for user defined special indentation adjustments.
263This hook gets called after a line is indented by the mode."
264 :type 'hook
265 :group 'c)
266
267(defcustom c-backspace-function 'backward-delete-char-untabify
268 "*Function called by `c-electric-backspace' when deleting backwards."
269 :type 'function
270 :group 'c)
271
272(defcustom c-delete-function 'delete-char
273 "*Function called by `c-electric-delete' when deleting forwards."
274 :type 'function
275 :group 'c)
276
277(defcustom c-electric-pound-behavior nil
278 "*List of behaviors for electric pound insertion.
279Only currently supported behavior is `alignleft'."
280 :type '(set :extra-offset 8 (const alignleft))
281 :group 'c)
282
283(defcustom c-label-minimum-indentation 1
284 "*Minimum indentation for lines inside of top-level constructs.
285This variable typically only affects code using the `gnu' style, which
286mandates a minimum of one space in front of every line inside
287top-level constructs. Specifically, the function
288`c-gnu-impose-minimum' on your `c-special-indent-hook' is what
289enforces this."
290 :type 'integer
291 :group 'c)
292
293(defcustom c-progress-interval 5
294 "*Interval used to update progress status during long re-indentation.
295If a number, percentage complete gets updated after each interval of
296that many seconds. Set to nil to inhibit updating. This is only
297useful for Emacs 19."
298 :type 'integer
299 :group 'c)
300
301(defcustom c-site-default-style "gnu"
302 "Default style for your site.
303To change the default style at your site, you can set this variable to
304any style defined in `c-style-alist'. However, if CC Mode is usually
305loaded into your Emacs at compile time, you will need to set this
306variable in the `site-init.el' file before CC Mode is loaded, then
307re-dump Emacs."
308 :type 'string
309 :group 'c)
310
311(defcustom c-style-variables-are-local-p nil
312 "*Whether style variables should be buffer local by default.
313If non-nil, then all indentation style related variables will be made
314buffer local by default. If nil, they will remain global. Variables
315are made buffer local when this file is loaded, and once buffer
316localized, they cannot be made global again.
317
318The list of variables to buffer localize are:
319 c-offsets-alist
320 c-basic-offset
321 c-file-style
322 c-file-offsets
323 c-comment-only-line-offset
324 c-cleanup-list
325 c-hanging-braces-alist
326 c-hanging-colons-alist
327 c-hanging-comment-starter-p
328 c-hanging-comment-ender-p
329 c-backslash-column
330 c-label-minimum-indentation
331 c-special-indent-hook
332 c-indentation-style"
333 :type 'boolean
334 :group 'c)
335
336(defcustom c-mode-hook nil
337 "*Hook called by `c-mode'."
338 :type '(hook :format "%{C Mode Hook%}:\n%v")
339 :group 'c)
340
341(defcustom c++-mode-hook nil
342 "*Hook called by `c++-mode'."
343 :type 'hook
344 :group 'c)
345
346(defcustom objc-mode-hook nil
347 "*Hook called by `objc-mode'."
348 :type 'hook
349 :group 'c)
350
351(defcustom java-mode-hook nil
352 "*Hook called by `java-mode'."
353 :type 'hook
354 :group 'c)
355
356(defcustom c-mode-common-hook nil
357 "*Hook called by all CC Mode modes for common initializations."
358 :type '(hook :format "%{CC Mode Common Hook%}:\n%v")
359 :group 'c)
360
361
362
363;; Non-customizable variables, still part of the interface to CC Mode
364(defvar c-file-style nil
365 "Variable interface for setting style via File Local Variables.
366In a file's Local Variable section, you can set this variable to a
367string suitable for `c-set-style'. When the file is visited, CC Mode
368will set the style of the file to this value automatically.
369
370Note that file style settings are applied before file offset settings
371as designated in the variable `c-file-offsets'.")
372
373(defvar c-file-offsets nil
374 "Variable interface for setting offsets via File Local Variables.
375In a file's Local Variable section, you can set this variable to an
376association list similar to the values allowed in `c-offsets-alist'.
377When the file is visited, CC Mode will institute these offset settings
378automatically.
379
380Note that file offset settings are applied after file style settings
381as designated in the variable `c-file-style'.")
382
383(defvar c-syntactic-context nil
384 "Variable containing syntactic analysis list during indentation.")
385
386(defvar c-indentation-style c-site-default-style
387 "Name of style installed in the current buffer.")
388
389
390(provide 'cc-vars)
391;;; cc-vars.el ends here