1 ;;; cc-styles.el --- support for styles in CC Mode
3 ;; Copyright (C) 1985,87,92,93,94,95,96,97 Free Software Foundation, Inc.
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)
11 ;; Keywords: c languages oop
13 ;; This file is part of GNU Emacs.
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)
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.
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.
32 (defconst c-style-alist
35 (c-comment-only-line-offset . (0 . 0))
36 (c-offsets-alist . ((statement-block-intro . +)
37 (knr-argdecl-intro . 5)
38 (substatement-open . +)
40 (statement-case-open . +)
42 (arglist-intro . c-lineup-arglist-intro-after-paren)
43 (arglist-close . c-lineup-arglist)
45 (c-special-indent-hook . c-gnu-impose-minimum)
49 (c-comment-only-line-offset . 0)
50 (c-offsets-alist . ((statement-block-intro . +)
51 (knr-argdecl-intro . 0)
52 (substatement-open . 0)
59 (c-comment-only-line-offset . 0)
60 (c-offsets-alist . ((statement-block-intro . +)
61 (knr-argdecl-intro . +)
62 (substatement-open . 0)
69 (c-comment-only-line-offset . 0)
70 (c-offsets-alist . ((statement-block-intro . +)
71 (substatement-open . 0)
78 (c-comment-only-line-offset . 0)
79 (c-offsets-alist . ((statement-block-intro . +)
80 (knr-argdecl-intro . +)
81 (substatement-open . 0)
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)
94 (substatement-open . 0)
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)
116 (indent-tabs-mode . t)
119 (c-offsets-alist . ((substatement-open . 0)
121 (c-hanging-braces-alist . ((brace-list-open)
124 (substatement-open after)
125 (block-close . c-snug-do-while)
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 . +)
136 (statement-case-open . +)
138 (arglist-intro . c-lineup-arglist-intro-after-paren)
139 (arglist-close . c-lineup-arglist)
141 (inher-cont . c-lineup-java-inher)
142 (func-decl-cont . c-lineup-java-throws)
147 "Styles of indentation.
148 Elements of this alist are of the form:
150 (STYLE-STRING [BASE-STYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
152 where STYLE-STRING is a short descriptive string used to select a
153 style, VARIABLE is any Emacs variable, and VALUE is the intended value
154 for that variable when using the selected style.
156 Optional BASE-STYLE if present, is a string and must follow
157 STYLE-STRING. BASE-STYLE names a style that this style inherits from.
158 By default, all styles inherit from the \"cc-mode\" style, which is
159 computed at run time. Style loops generate errors.
161 Two variables are treated specially. When VARIABLE is
162 `c-offsets-alist', the VALUE is a list containing elements of the
165 (SYNTACTIC-SYMBOL . OFFSET)
167 as 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
169 your style, only those that are different from the default.
171 When 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
173 element of the list is added with `add-hook'.
175 Do not change this variable directly. Use the function `c-add-style'
176 to add new styles or modify existing styles (it is not a good idea to
177 modify existing styles -- you should create a new style that inherits
178 the existing style.")
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)))
187 ;; first special variable
188 ((eq attr 'c-offsets-alist)
192 (let ((langelem (car langentry))
193 (offset (cdr langentry)))
194 (c-set-offset langelem offset)
197 ;; second special variable
198 ((eq attr 'c-special-indent-hook)
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
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
212 (if (not (string-equal style "cc-mode"))
213 (let ((base (if (stringp (car basestyles))
214 (downcase (car basestyles))
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)))
225 (defvar c-set-style-history nil)
228 (defun c-set-style (stylename)
229 "Set CC Mode variables to use one of several different indentation styles.
230 STYLENAME is a string representing the desired style from the list of
231 styles described in the variable `c-style-alist'. See that variable
232 for details of setting up styles.
234 The variable `c-indentation-style' always contains the buffer's current
236 (interactive (list (let ((completion-ignore-case t)
237 (prompt (format "Which %s indentation style? "
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))
247 (defun c-add-style (style descrip &optional set-p)
248 "Adds a style to `c-style-alist', or updates an existing one.
249 STYLE is a string identifying the style to add or update. DESCRIP is
250 an association list describing the style and must be of the form:
252 ([BASESTYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
254 See the variable `c-style-alist' for the semantics of BASESTYLE,
255 VARIABLE and VALUE. This function also sets the current style to
256 STYLE using `c-set-style' if the optional SET-P flag is non-nil."
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)))
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)))
272 (defconst c-offsets-alist
274 (c . c-lineup-C-comments)
277 (defun-block-intro . +)
283 (knr-argdecl-intro . +)
286 (topmost-intro-cont . 0)
287 (member-init-intro . +)
288 (member-init-cont . 0)
290 (inher-cont . c-lineup-multi-inher)
293 (brace-list-open . 0)
294 (brace-list-close . 0)
295 (brace-list-intro . +)
296 (brace-list-entry . 0)
298 ;; some people might prefer
299 ;;(statement . c-lineup-runin-statements)
301 ;; some people might prefer
302 ;;(statement-cont . c-lineup-math)
303 (statement-block-intro . +)
304 (statement-case-intro . +)
305 (statement-case-open . 0)
307 (substatement-open . +)
311 (do-while-closure . 0)
313 (comment-intro . c-lineup-comment)
316 (arglist-cont-nonempty . c-lineup-arglist)
318 (stream-op . c-lineup-streamop)
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)
329 "Association list of syntactic element symbols and indentation offsets.
330 As described below, each cons cell in this list has the form:
332 (SYNTACTIC-SYMBOL . OFFSET)
334 When a line is indented, CC Mode first determines the syntactic
335 context of the line by generating a list of symbols called syntactic
336 elements. This list can contain more than one syntactic element and
337 the global variable `c-syntactic-context' contains the context list
338 for the line being indented. Each element in this list is actually a
339 cons cell of the syntactic symbol and a buffer position. This buffer
340 position is called the relative indent point for the line. Some
341 syntactic symbols may not have a relative indent point associated with
344 After the syntactic context list for a line is generated, CC Mode
345 calculates the absolute indentation for the line by looking at each
346 syntactic element in the list. First, it compares the syntactic
347 element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'. When it
348 finds a match, it adds the OFFSET to the column of the relative indent
349 point. The sum of this calculation for each element in the syntactic
350 list is the absolute offset for line being indented.
352 If the syntactic element does not match any in the `c-offsets-alist',
353 an error is generated if `c-strict-syntax-p' is non-nil, otherwise the
356 Actually, OFFSET can be an integer, a function, a variable, or one of
357 the following symbols: `+', `-', `++', `--', `*', or `/'. These
358 latter designate positive or negative multiples of `c-basic-offset',
359 respectively: 1, -1, 2, -2, 0.5, and -0.5. If OFFSET is a function, it
360 is called with a single argument containing the cons of the syntactic
361 element symbol and the relative indent point. The function should
362 return an integer offset.
364 Here is the current list of valid syntactic element symbols:
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
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
442 (if c-strict-syntax-p
443 (error "don't know how to indent a %s" symbol)
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)))
456 (< relpos (c-point 'bol)))
464 (defvar c-read-offset-history nil)
466 (defun c-read-offset (langelem)
467 ;; read new offset value for LANGELEM from minibuffer. return a
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 [+,-,++,--,*,/] "
474 (prompt (concat "Offset " defstr))
475 offset input interned raw)
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)))
492 ((c-safe (functionp (setq raw (read input))))
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
503 (defun c-set-offset (symbol offset &optional add-p)
504 "Change the value of a syntactic element symbol in `c-offsets-alist'.
505 SYMBOL is the syntactic element symbol to change and OFFSET is the new
506 offset for that syntactic element. Optional ADD says to add SYMBOL to
507 `c-offsets-alist' if it doesn't already appear there."
510 (intern (completing-read
511 (concat "Syntactic symbol to change"
512 (if current-prefix-arg " or add" "")
516 (cons (format "%s" (car langelem)) nil))
518 nil (not current-prefix-arg)
519 ;; initial contents tries to be the last element
520 ;; on the syntactic analysis list for the current
522 (let* ((syntax (c-guess-basic-syntax))
523 (len (length syntax))
524 (ic (format "%s" (car (nth (1- len) syntax)))))
527 (offset (c-read-offset langelem)))
528 (list langelem offset current-prefix-arg)))
529 ;; sanity check offset
539 (error "Offset must be int, func, var, or in [+,-,++,--,*,/]: %s"
541 (let ((entry (assq symbol c-offsets-alist)))
543 (setcdr entry offset)
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))
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!
557 (or (assoc "cc-mode" c-style-alist)
559 (c-add-style "cc-mode"
563 (let ((val (symbol-value var)))
564 (cons var (if (atom val) val
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
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))))
583 (defun c-make-styles-buffer-local ()
584 "Make all CC Mode style variables buffer local.
585 If you edit primarily one style of C (or C++, Objective-C, Java) code,
586 you probably want style variables to be global. This is the default.
588 If you edit many different styles of C (or C++, Objective-C, Java) at
589 the same time, you probably want the CC Mode style variables to be
590 buffer local. If you do, then you will need to set any CC Mode style
591 variables in a hook function (e.g. off of c-mode-common-hook), instead
592 of at the top level of your ~/.emacs file.
594 This function makes all the CC Mode style variables buffer local.
595 Call it after CC Mode is loaded into your Emacs environment.
596 Conversely, set the variable `c-style-variables-are-local-p' to t in
597 your .emacs file, before CC Mode is loaded, and this function will be
598 automatically called when CC Mode is loaded."
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))
617 ;;; cc-styles.el ends here