*** empty log message ***
[bpt/emacs.git] / lisp / progmodes / cc-styles.el
CommitLineData
785eecbb
RS
1;;; cc-styles.el --- support for styles in CC Mode
2
0bacd8d0 3;; Copyright (C) 1985,87,92,93,94,95,96,97,98 Free Software Foundation, Inc.
785eecbb 4
0ec8351b
BW
5;; Authors: 1998 Barry A. Warsaw and Martin Stjernholm
6;; 1992-1997 Barry A. Warsaw
785eecbb
RS
7;; 1987 Dave Detlefs and Stewart Clamen
8;; 1985 Richard M. Stallman
0ec8351b 9;; Maintainer: bug-cc-mode@gnu.org
785eecbb 10;; Created: 22-Apr-1997 (split from cc-mode.el)
82aba9f4 11;; Version: See cc-mode.el
785eecbb
RS
12;; Keywords: c languages oop
13
14;; This file is part of GNU Emacs.
15
16;; GNU Emacs is free software; you can redistribute it and/or modify
17;; it under the terms of the GNU General Public License as published by
18;; the Free Software Foundation; either version 2, or (at your option)
19;; any later version.
20
21;; GNU Emacs is distributed in the hope that it will be useful,
22;; but WITHOUT ANY WARRANTY; without even the implied warranty of
23;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24;; GNU General Public License for more details.
25
26;; You should have received a copy of the GNU General Public License
27;; along with GNU Emacs; see the file COPYING. If not, write to the
28;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
29;; Boston, MA 02111-1307, USA.
30
31
0ec8351b
BW
32;; explicit compile-time dependencies
33(eval-when-compile
34 (require 'cc-defs))
35
785eecbb 36\f
0ec8351b 37;; Warning: don't eval-defun this constant or you'll break style inheritance.
785eecbb
RS
38(defconst c-style-alist
39 '(("gnu"
40 (c-basic-offset . 2)
41 (c-comment-only-line-offset . (0 . 0))
42 (c-offsets-alist . ((statement-block-intro . +)
43 (knr-argdecl-intro . 5)
44 (substatement-open . +)
45 (label . 0)
46 (statement-case-open . +)
47 (statement-cont . +)
48 (arglist-intro . c-lineup-arglist-intro-after-paren)
49 (arglist-close . c-lineup-arglist)
0ec8351b 50 (inline-open . 0)
785eecbb
RS
51 ))
52 (c-special-indent-hook . c-gnu-impose-minimum)
b402d19f
RS
53 (c-comment-continuation-stars . "")
54 (c-hanging-comment-ender-p . t)
785eecbb
RS
55 )
56 ("k&r"
57 (c-basic-offset . 5)
58 (c-comment-only-line-offset . 0)
59 (c-offsets-alist . ((statement-block-intro . +)
60 (knr-argdecl-intro . 0)
61 (substatement-open . 0)
62 (label . 0)
63 (statement-cont . +)
64 ))
65 )
66 ("bsd"
67 (c-basic-offset . 4)
68 (c-comment-only-line-offset . 0)
69 (c-offsets-alist . ((statement-block-intro . +)
70 (knr-argdecl-intro . +)
71 (substatement-open . 0)
72 (label . 0)
73 (statement-cont . +)
74 ))
75 )
76 ("stroustrup"
77 (c-basic-offset . 4)
78 (c-comment-only-line-offset . 0)
79 (c-offsets-alist . ((statement-block-intro . +)
80 (substatement-open . 0)
81 (label . 0)
82 (statement-cont . +)
83 ))
84 )
85 ("whitesmith"
86 (c-basic-offset . 4)
87 (c-comment-only-line-offset . 0)
88 (c-offsets-alist . ((statement-block-intro . +)
89 (knr-argdecl-intro . +)
90 (substatement-open . 0)
91 (label . 0)
92 (statement-cont . +)
93 ))
94
95 )
96 ("ellemtel"
97 (c-basic-offset . 3)
98 (c-comment-only-line-offset . 0)
99 (c-hanging-braces-alist . ((substatement-open before after)))
100 (c-offsets-alist . ((topmost-intro . 0)
101 (topmost-intro-cont . 0)
102 (substatement . +)
103 (substatement-open . 0)
104 (case-label . +)
105 (access-label . -)
106 (inclass . ++)
107 (inline-open . 0)
108 ))
109 )
110 ("linux"
111 (c-basic-offset . 8)
112 (c-comment-only-line-offset . 0)
113 (c-hanging-braces-alist . ((brace-list-open)
0ec8351b 114 (brace-entry-open)
785eecbb
RS
115 (substatement-open after)
116 (block-close . c-snug-do-while)))
117 (c-cleanup-list . (brace-else-brace))
118 (c-offsets-alist . ((statement-block-intro . +)
119 (knr-argdecl-intro . 0)
120 (substatement-open . 0)
121 (label . 0)
122 (statement-cont . +)
123 ))
124 )
125 ("python"
126 (indent-tabs-mode . t)
127 (fill-column . 72)
128 (c-basic-offset . 8)
129 (c-offsets-alist . ((substatement-open . 0)
62971612
RS
130 (inextern-lang . 0)
131 (arglist-intro . +)
132 (knr-argdecl-intro . +)
785eecbb
RS
133 ))
134 (c-hanging-braces-alist . ((brace-list-open)
135 (brace-list-intro)
136 (brace-list-close)
0ec8351b 137 (brace-entry-open)
785eecbb
RS
138 (substatement-open after)
139 (block-close . c-snug-do-while)
140 ))
62971612
RS
141 (c-comment-continuation-stars . "")
142 (c-hanging-comment-ender-p . nil)
143 (fill-column . 78)
785eecbb
RS
144 )
145 ("java"
0bacd8d0 146 (c-basic-offset . 4)
785eecbb 147 (c-comment-only-line-offset . (0 . 0))
63add9c9
RS
148 ;; the following preserves Javadoc starter lines
149 (c-hanging-comment-starter-p . nil)
0bacd8d0
RS
150 (c-offsets-alist . ((inline-open . 0)
151 (topmost-intro-cont . +)
785eecbb
RS
152 (statement-block-intro . +)
153 (knr-argdecl-intro . 5)
154 (substatement-open . +)
155 (label . 0)
156 (statement-case-open . +)
157 (statement-cont . +)
158 (arglist-intro . c-lineup-arglist-intro-after-paren)
159 (arglist-close . c-lineup-arglist)
160 (access-label . 0)
161 (inher-cont . c-lineup-java-inher)
162 (func-decl-cont . c-lineup-java-throws)
163 ))
164
165 )
166 )
167 "Styles of indentation.
168Elements of this alist are of the form:
169
170 (STYLE-STRING [BASE-STYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
171
172where STYLE-STRING is a short descriptive string used to select a
173style, VARIABLE is any Emacs variable, and VALUE is the intended value
174for that variable when using the selected style.
175
176Optional BASE-STYLE if present, is a string and must follow
177STYLE-STRING. BASE-STYLE names a style that this style inherits from.
178By default, all styles inherit from the \"cc-mode\" style, which is
179computed at run time. Style loops generate errors.
180
181Two variables are treated specially. When VARIABLE is
182`c-offsets-alist', the VALUE is a list containing elements of the
183form:
184
185 (SYNTACTIC-SYMBOL . OFFSET)
186
187as described in `c-offsets-alist'. These are passed directly to
188`c-set-offset' so there is no need to set every syntactic symbol in
189your style, only those that are different from the default.
190
191When VARIABLE is `c-special-indent-hook', its VALUE is added to
192`c-special-indent-hook' using `add-hook'. If VALUE is a list, each
193element of the list is added with `add-hook'.
194
195Do not change this variable directly. Use the function `c-add-style'
196to add new styles or modify existing styles (it is not a good idea to
197modify existing styles -- you should create a new style that inherits
198the existing style.")
199
200\f
201;; Functions that manipulate styles
202(defun c-set-style-1 (conscell)
203 ;; Set the style for one variable
204 (let ((attr (car conscell))
205 (val (cdr conscell)))
206 (cond
207 ;; first special variable
208 ((eq attr 'c-offsets-alist)
209 (mapcar
210 (function
211 (lambda (langentry)
212 (let ((langelem (car langentry))
213 (offset (cdr langentry)))
214 (c-set-offset langelem offset)
215 )))
216 val))
217 ;; second special variable
218 ((eq attr 'c-special-indent-hook)
219 (if (listp val)
220 (while val
221 (add-hook 'c-special-indent-hook (car val))
222 (setq val (cdr val)))
223 (add-hook 'c-special-indent-hook val)))
224 ;; all other variables
225 (t (set attr val)))
226 ))
227
228(defun c-set-style-2 (style basestyles)
229 ;; Recursively set the base style. If no base style is given, the
0bacd8d0
RS
230 ;; default base style is "user" (a.k.a. "cc-mode") and the recursion
231 ;; stops. Be sure to detect loops.
785eecbb
RS
232 (let ((vars (cdr (or (assoc (downcase style) c-style-alist)
233 (assoc (upcase style) c-style-alist)
234 (assoc style c-style-alist)
235 (error "Undefined style: %s" style)))))
0bacd8d0 236 (if (not (string-equal style "user"))
63add9c9
RS
237 (let ((base (if (stringp (car vars))
238 (prog1
239 (downcase (car vars))
240 (setq vars (cdr vars)))
0bacd8d0 241 "user")))
63add9c9
RS
242 (if (memq base basestyles)
243 (error "Style loop detected: %s in %s" base basestyles))
244 (c-set-style-2 base (cons base basestyles))))
785eecbb
RS
245 (mapcar 'c-set-style-1 vars)))
246
247(defvar c-set-style-history nil)
248
249;;;###autoload
250(defun c-set-style (stylename)
251 "Set CC Mode variables to use one of several different indentation styles.
252STYLENAME is a string representing the desired style from the list of
253styles described in the variable `c-style-alist'. See that variable
254for details of setting up styles.
255
256The variable `c-indentation-style' always contains the buffer's current
257style name."
258 (interactive (list (let ((completion-ignore-case t)
259 (prompt (format "Which %s indentation style? "
260 mode-name)))
261 (completing-read prompt c-style-alist nil t
262 (cons c-indentation-style 0)
263 'c-set-style-history))))
63add9c9 264 (c-initialize-builtin-style)
785eecbb
RS
265 (c-set-style-2 stylename nil)
266 (setq c-indentation-style stylename)
267 (c-keep-region-active))
268
269;;;###autoload
270(defun c-add-style (style descrip &optional set-p)
271 "Adds a style to `c-style-alist', or updates an existing one.
272STYLE is a string identifying the style to add or update. DESCRIP is
273an association list describing the style and must be of the form:
274
275 ([BASESTYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
276
277See the variable `c-style-alist' for the semantics of BASESTYLE,
278VARIABLE and VALUE. This function also sets the current style to
279STYLE using `c-set-style' if the optional SET-P flag is non-nil."
280 (interactive
281 (let ((stylename (completing-read "Style to add: " c-style-alist
282 nil nil nil 'c-set-style-history))
283 (description (eval-minibuffer "Style description: ")))
284 (list stylename description
285 (y-or-n-p "Set the style too? "))))
286 (setq style (downcase style))
287 (let ((s (assoc style c-style-alist)))
288 (if s
289 (setcdr s (copy-alist descrip)) ; replace
290 (setq c-style-alist (cons (cons style descrip) c-style-alist))))
291 (and set-p (c-set-style style)))
292
293
294\f
295(defconst c-offsets-alist
0ec8351b 296 '((string . c-lineup-dont-change)
785eecbb
RS
297 (c . c-lineup-C-comments)
298 (defun-open . 0)
299 (defun-close . 0)
300 (defun-block-intro . +)
301 (class-open . 0)
302 (class-close . 0)
303 (inline-open . +)
304 (inline-close . 0)
305 (func-decl-cont . +)
306 (knr-argdecl-intro . +)
307 (knr-argdecl . 0)
308 (topmost-intro . 0)
309 (topmost-intro-cont . 0)
310 (member-init-intro . +)
311 (member-init-cont . 0)
312 (inher-intro . +)
313 (inher-cont . c-lineup-multi-inher)
314 (block-open . 0)
315 (block-close . 0)
316 (brace-list-open . 0)
317 (brace-list-close . 0)
318 (brace-list-intro . +)
319 (brace-list-entry . 0)
0ec8351b 320 (brace-entry-open . 0)
785eecbb
RS
321 (statement . 0)
322 ;; some people might prefer
323 ;;(statement . c-lineup-runin-statements)
324 (statement-cont . +)
325 ;; some people might prefer
326 ;;(statement-cont . c-lineup-math)
327 (statement-block-intro . +)
328 (statement-case-intro . +)
329 (statement-case-open . 0)
330 (substatement . +)
331 (substatement-open . +)
332 (case-label . 0)
333 (access-label . -)
334 (label . 2)
335 (do-while-closure . 0)
336 (else-clause . 0)
0ec8351b 337 (catch-clause . 0)
785eecbb
RS
338 (comment-intro . c-lineup-comment)
339 (arglist-intro . +)
340 (arglist-cont . 0)
341 (arglist-cont-nonempty . c-lineup-arglist)
342 (arglist-close . +)
343 (stream-op . c-lineup-streamop)
344 (inclass . +)
345 (cpp-macro . -1000)
0bacd8d0 346 (cpp-macro-cont . c-lineup-dont-change)
785eecbb
RS
347 (friend . 0)
348 (objc-method-intro . -1000)
349 (objc-method-args-cont . c-lineup-ObjC-method-args)
350 (objc-method-call-cont . c-lineup-ObjC-method-call)
351 (extern-lang-open . 0)
352 (extern-lang-close . 0)
353 (inextern-lang . +)
0bacd8d0
RS
354 (namespace-open . 0)
355 (namespace-close . 0)
356 (innamespace . +)
3900d73b 357 (template-args-cont . +)
0ec8351b
BW
358 (inlambda . c-lineup-inexpr-block)
359 (lambda-intro-cont . +)
360 (inexpr-statement . 0)
361 (inexpr-class . +)
785eecbb
RS
362 )
363 "Association list of syntactic element symbols and indentation offsets.
364As described below, each cons cell in this list has the form:
365
366 (SYNTACTIC-SYMBOL . OFFSET)
367
368When a line is indented, CC Mode first determines the syntactic
369context of the line by generating a list of symbols called syntactic
370elements. This list can contain more than one syntactic element and
371the global variable `c-syntactic-context' contains the context list
372for the line being indented. Each element in this list is actually a
373cons cell of the syntactic symbol and a buffer position. This buffer
374position is called the relative indent point for the line. Some
375syntactic symbols may not have a relative indent point associated with
376them.
377
378After the syntactic context list for a line is generated, CC Mode
379calculates the absolute indentation for the line by looking at each
380syntactic element in the list. First, it compares the syntactic
381element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'. When it
382finds a match, it adds the OFFSET to the column of the relative indent
383point. The sum of this calculation for each element in the syntactic
384list is the absolute offset for line being indented.
385
386If the syntactic element does not match any in the `c-offsets-alist',
387an error is generated if `c-strict-syntax-p' is non-nil, otherwise the
388element is ignored.
389
390Actually, OFFSET can be an integer, a function, a variable, or one of
391the following symbols: `+', `-', `++', `--', `*', or `/'. These
392latter designate positive or negative multiples of `c-basic-offset',
393respectively: 1, -1, 2, -2, 0.5, and -0.5. If OFFSET is a function, it
394is called with a single argument containing the cons of the syntactic
395element symbol and the relative indent point. The function should
396return an integer offset.
397
0ec8351b
BW
398OFFSET can also be a list, in which case it is recursively evaluated
399using the semantics described above. The first element of the list to
400return a non-nil value succeeds. If none of the elements returns a
401non-nil value, then what happends depends on the value of
402`c-strict-syntax-p'. When `c-strict-syntax-p' is nil, then an offset
403of zero is used, otherwise an error is generated.
404
785eecbb
RS
405Here is the current list of valid syntactic element symbols:
406
407 string -- inside multi-line string
408 c -- inside a multi-line C style block comment
409 defun-open -- brace that opens a function definition
410 defun-close -- brace that closes a function definition
411 defun-block-intro -- the first line in a top-level defun
412 class-open -- brace that opens a class definition
413 class-close -- brace that closes a class definition
414 inline-open -- brace that opens an in-class inline method
415 inline-close -- brace that closes an in-class inline method
416 func-decl-cont -- the region between a function definition's
417 argument list and the function opening brace
418 (excluding K&R argument declarations). In C, you
419 cannot put anything but whitespace and comments
420 between them; in C++ and Java, throws declarations
421 and other things can appear in this context.
422 knr-argdecl-intro -- first line of a K&R C argument declaration
423 knr-argdecl -- subsequent lines in a K&R C argument declaration
424 topmost-intro -- the first line in a topmost construct definition
425 topmost-intro-cont -- topmost definition continuation lines
426 member-init-intro -- first line in a member initialization list
427 member-init-cont -- subsequent member initialization list lines
428 inher-intro -- first line of a multiple inheritance list
429 inher-cont -- subsequent multiple inheritance lines
430 block-open -- statement block open brace
431 block-close -- statement block close brace
432 brace-list-open -- open brace of an enum or static array list
433 brace-list-close -- close brace of an enum or static array list
434 brace-list-intro -- first line in an enum or static array list
435 brace-list-entry -- subsequent lines in an enum or static array list
0ec8351b
BW
436 brace-entry-open -- subsequent lines in an enum or static array
437 list that start with an open brace.
785eecbb
RS
438 statement -- a C (or like) statement
439 statement-cont -- a continuation of a C (or like) statement
440 statement-block-intro -- the first line in a new statement block
441 statement-case-intro -- the first line in a case \"block\"
442 statement-case-open -- the first line in a case block starting with brace
443 substatement -- the first line after an if/while/for/do/else
444 substatement-open -- the brace that opens a substatement block
445 case-label -- a `case' or `default' label
446 access-label -- C++ private/protected/public access label
447 label -- any ordinary label
448 do-while-closure -- the `while' that ends a do/while construct
449 else-clause -- the `else' of an if/else construct
0ec8351b 450 catch-clause -- the `catch' or `finally' of a try/catch construct
785eecbb
RS
451 comment-intro -- a line containing only a comment introduction
452 arglist-intro -- the first line in an argument list
453 arglist-cont -- subsequent argument list lines when no
454 arguments follow on the same line as the
455 arglist opening paren
456 arglist-cont-nonempty -- subsequent argument list lines when at
457 least one argument follows on the same
458 line as the arglist opening paren
459 arglist-close -- the solo close paren of an argument list
460 stream-op -- lines continuing a stream operator construct
461 inclass -- the construct is nested inside a class definition
0bacd8d0
RS
462 cpp-macro -- the start of a C preprocessor macro definition
463 cpp-macro-cont -- the second and subsequent lines in a
464 multi-line C preprocessor macro definition
785eecbb
RS
465 friend -- a C++ friend declaration
466 objc-method-intro -- the first line of an Objective-C method definition
467 objc-method-args-cont -- lines continuing an Objective-C method definition
468 objc-method-call-cont -- lines continuing an Objective-C method call
469 extern-lang-open -- brace that opens an external language block
470 extern-lang-close -- brace that closes an external language block
0bacd8d0
RS
471 inextern-lang -- analogous to `inclass' syntactic symbol,
472 but used inside, e.g. extern \"C\" constructs
473 namespace-open -- brace that opens a C++ namespace block
474 namespace-close -- brace that closes a C++ namespace block
475 innamespace -- analogous to `inextern-lang' syntactic
476 symbol, but used inside C++ namespace constructs
3900d73b 477 template-args-cont -- C++ template argument list continuations
0ec8351b
BW
478 inlambda -- in the header or body of a lambda function
479 lambda-intro-cont -- continuation of the header of a lambda function
480 inexpr-statement -- the statement is inside an expression
481 inexpr-class -- the class is inside an expression
785eecbb
RS
482")
483
0ec8351b
BW
484(defun c-evaluate-offset (offset langelem symbol)
485 ;; offset can be a number, a function, a variable, a list, or one of
486 ;; the symbols + or -
487 (cond
488 ((eq offset '+) (setq offset c-basic-offset))
489 ((eq offset '-) (setq offset (- c-basic-offset)))
490 ((eq offset '++) (setq offset (* 2 c-basic-offset)))
491 ((eq offset '--) (setq offset (* 2 (- c-basic-offset))))
492 ((eq offset '*) (setq offset (/ c-basic-offset 2)))
493 ((eq offset '/) (setq offset (/ (- c-basic-offset) 2)))
494 ((functionp offset) (setq offset (funcall offset langelem)))
495 ((listp offset)
496 (setq offset
497 (let (done)
498 (while (and (not done) offset)
499 (setq done (c-evaluate-offset (car offset) langelem symbol)
500 offset (cdr offset)))
501 (if (not done)
502 (if c-strict-syntax-p
503 (error "No offset found for syntactic symbol %s" symbol)
504 0)
505 done))))
506 ((not (numberp offset)) (setq offset (symbol-value offset)))
507 )
508 offset)
509
785eecbb
RS
510(defun c-get-offset (langelem)
511 ;; Get offset from LANGELEM which is a cons cell of the form:
512 ;; (SYMBOL . RELPOS). The symbol is matched against
513 ;; c-offsets-alist and the offset found there is either returned,
514 ;; or added to the indentation at RELPOS. If RELPOS is nil, then
515 ;; the offset is simply returned.
516 (let* ((symbol (car langelem))
517 (relpos (cdr langelem))
518 (match (assq symbol c-offsets-alist))
519 (offset (cdr-safe match)))
0ec8351b
BW
520 (if (not match)
521 (if c-strict-syntax-p
522 (error "No offset found for syntactic symbol %s" symbol)
523 (setq offset 0
524 relpos 0))
525 (setq offset (c-evaluate-offset offset langelem symbol)))
785eecbb
RS
526 (+ (if (and relpos
527 (< relpos (c-point 'bol)))
528 (save-excursion
529 (goto-char relpos)
530 (current-column))
531 0)
0ec8351b
BW
532 (c-evaluate-offset offset langelem symbol))
533 ))
785eecbb
RS
534
535\f
536(defvar c-read-offset-history nil)
537
538(defun c-read-offset (langelem)
539 ;; read new offset value for LANGELEM from minibuffer. return a
540 ;; legal value only
0ec8351b
BW
541 (let* ((oldoff (cdr-safe (assq langelem c-offsets-alist)))
542 (symname (symbol-name langelem))
543 (defstr (format "(default %s): " oldoff))
544 (errmsg (concat "Offset must be int, func, var, list, "
545 "or [+,-,++,--,*,/] "
546 defstr))
547 (prompt (concat symname " offset " defstr))
785eecbb
RS
548 offset input interned raw)
549 (while (not offset)
550 (setq input (completing-read prompt obarray 'fboundp nil nil
551 'c-read-offset-history)
552 offset (cond ((string-equal "" input) oldoff) ; default
553 ((string-equal "+" input) '+)
554 ((string-equal "-" input) '-)
555 ((string-equal "++" input) '++)
556 ((string-equal "--" input) '--)
557 ((string-equal "*" input) '*)
558 ((string-equal "/" input) '/)
559 ((string-match "^-?[0-9]+$" input)
560 (string-to-int input))
561 ;; a symbol with a function binding
562 ((fboundp (setq interned (intern input)))
563 interned)
564 ;; a lambda function
565 ((c-safe (functionp (setq raw (read input))))
566 raw)
567 ;; a symbol with variable binding
568 ((boundp interned) interned)
569 ;; error, but don't signal one, keep trying
570 ;; to read an input value
571 (t (ding)
572 (setq prompt errmsg)
573 nil))))
574 offset))
575
275a02d4 576;;;###autoload
785eecbb
RS
577(defun c-set-offset (symbol offset &optional add-p)
578 "Change the value of a syntactic element symbol in `c-offsets-alist'.
579SYMBOL is the syntactic element symbol to change and OFFSET is the new
580offset for that syntactic element. Optional ADD says to add SYMBOL to
581`c-offsets-alist' if it doesn't already appear there."
582 (interactive
583 (let* ((langelem
584 (intern (completing-read
585 (concat "Syntactic symbol to change"
586 (if current-prefix-arg " or add" "")
587 ": ")
588 (mapcar
589 #'(lambda (langelem)
590 (cons (format "%s" (car langelem)) nil))
591 c-offsets-alist)
592 nil (not current-prefix-arg)
593 ;; initial contents tries to be the last element
594 ;; on the syntactic analysis list for the current
595 ;; line
596 (let* ((syntax (c-guess-basic-syntax))
597 (len (length syntax))
598 (ic (format "%s" (car (nth (1- len) syntax)))))
599 (cons ic 0))
600 )))
601 (offset (c-read-offset langelem)))
602 (list langelem offset current-prefix-arg)))
603 ;; sanity check offset
604 (or (eq offset '+)
605 (eq offset '-)
606 (eq offset '++)
607 (eq offset '--)
608 (eq offset '*)
609 (eq offset '/)
610 (integerp offset)
611 (functionp offset)
0ec8351b 612 (listp offset)
785eecbb 613 (boundp offset)
0ec8351b 614 (error "Offset must be int, func, var, list, or in [+,-,++,--,*,/]: %s"
785eecbb
RS
615 offset))
616 (let ((entry (assq symbol c-offsets-alist)))
617 (if entry
618 (setcdr entry offset)
619 (if add-p
620 (setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
621 (error "%s is not a valid syntactic symbol." symbol))))
622 (c-keep-region-active))
623
785eecbb 624\f
0ec8351b
BW
625(defun c-copy-tree (tree)
626 (if (consp tree)
627 (cons (c-copy-tree (car tree))
628 (c-copy-tree (cdr tree)))
629 tree))
630
785eecbb
RS
631(defun c-initialize-builtin-style ()
632 ;; Dynamically append the default value of most variables. This is
633 ;; crucial because future c-set-style calls will always reset the
634 ;; variables first to the `cc-mode' style before instituting the new
635 ;; style. Only do this once!
0ec8351b
BW
636 (unless (get 'c-initialize-builtin-style 'is-run)
637 (put 'c-initialize-builtin-style 'is-run t)
638 (c-initialize-cc-mode)
639 (or (assoc "cc-mode" c-style-alist)
640 (assoc "user" c-style-alist)
641 (progn
642 (c-add-style "user"
643 (mapcar
644 (function
645 (lambda (var)
646 (let ((val (symbol-value var)))
647 (cons var (c-copy-tree val)))))
648 '(c-backslash-column
649 c-basic-offset
650 c-cleanup-list
651 c-comment-only-line-offset
652 c-electric-pound-behavior
653 c-hanging-braces-alist
654 c-hanging-colons-alist
655 c-hanging-comment-starter-p
656 c-hanging-comment-ender-p
657 c-offsets-alist
658 )))
659 (c-add-style "cc-mode" '("user"))
660 ))
661 (if c-style-variables-are-local-p
662 (c-make-styles-buffer-local))))
63add9c9 663
785eecbb 664
0bacd8d0 665(defun c-make-styles-buffer-local (&optional this-buf-only-p)
785eecbb
RS
666 "Make all CC Mode style variables buffer local.
667If you edit primarily one style of C (or C++, Objective-C, Java) code,
668you probably want style variables to be global. This is the default.
669
670If you edit many different styles of C (or C++, Objective-C, Java) at
671the same time, you probably want the CC Mode style variables to be
672buffer local. If you do, then you will need to set any CC Mode style
673variables in a hook function (e.g. off of c-mode-common-hook), instead
674of at the top level of your ~/.emacs file.
675
676This function makes all the CC Mode style variables buffer local.
677Call it after CC Mode is loaded into your Emacs environment.
678Conversely, set the variable `c-style-variables-are-local-p' to t in
679your .emacs file, before CC Mode is loaded, and this function will be
0bacd8d0
RS
680automatically called when CC Mode is loaded.
681
682Optional argument, when non-nil, means use `make-local-variable'
683instead of `make-variable-buffer-local'."
785eecbb 684 ;; style variables
0bacd8d0
RS
685 (let ((func (if this-buf-only-p
686 'make-local-variable
687 'make-variable-buffer-local))
688 (varsyms '(c-offsets-alist
689 c-basic-offset
690 c-file-style
691 c-file-offsets
692 c-comment-only-line-offset
693 c-cleanup-list
694 c-hanging-braces-alist
695 c-hanging-colons-alist
696 c-hanging-comment-starter-p
697 c-hanging-comment-ender-p
698 c-backslash-column
699 c-label-minimum-indentation
700 c-indentation-style)))
701 (mapcar func varsyms)
702 ;; Hooks must be handled specially
703 (if this-buf-only-p
704 (make-local-hook 'c-special-indent-hook)
705 (make-variable-buffer-local 'c-special-indent-hook))
706 ))
707
785eecbb
RS
708
709\f
710(provide 'cc-styles)
711;;; cc-styles.el ends here