(idl-mode): Support for CORBA's IDL language.
[bpt/emacs.git] / lisp / progmodes / cc-styles.el
CommitLineData
785eecbb
RS
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)
31b2af0a 10;; Version: 5.13
785eecbb
RS
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\f
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\f
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\f
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\f
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
275a02d4 503;;;###autoload
785eecbb
RS
504(defun c-set-offset (symbol offset &optional add-p)
505 "Change the value of a syntactic element symbol in `c-offsets-alist'.
506SYMBOL is the syntactic element symbol to change and OFFSET is the new
507offset for that syntactic element. Optional ADD says to add SYMBOL to
508`c-offsets-alist' if it doesn't already appear there."
509 (interactive
510 (let* ((langelem
511 (intern (completing-read
512 (concat "Syntactic symbol to change"
513 (if current-prefix-arg " or add" "")
514 ": ")
515 (mapcar
516 #'(lambda (langelem)
517 (cons (format "%s" (car langelem)) nil))
518 c-offsets-alist)
519 nil (not current-prefix-arg)
520 ;; initial contents tries to be the last element
521 ;; on the syntactic analysis list for the current
522 ;; line
523 (let* ((syntax (c-guess-basic-syntax))
524 (len (length syntax))
525 (ic (format "%s" (car (nth (1- len) syntax)))))
526 (cons ic 0))
527 )))
528 (offset (c-read-offset langelem)))
529 (list langelem offset current-prefix-arg)))
530 ;; sanity check offset
531 (or (eq offset '+)
532 (eq offset '-)
533 (eq offset '++)
534 (eq offset '--)
535 (eq offset '*)
536 (eq offset '/)
537 (integerp offset)
538 (functionp offset)
539 (boundp offset)
540 (error "Offset must be int, func, var, or in [+,-,++,--,*,/]: %s"
541 offset))
542 (let ((entry (assq symbol c-offsets-alist)))
543 (if entry
544 (setcdr entry offset)
545 (if add-p
546 (setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
547 (error "%s is not a valid syntactic symbol." symbol))))
548 (c-keep-region-active))
549
550
551\f
552(defun c-initialize-builtin-style ()
553 ;; Dynamically append the default value of most variables. This is
554 ;; crucial because future c-set-style calls will always reset the
555 ;; variables first to the `cc-mode' style before instituting the new
556 ;; style. Only do this once!
785eecbb
RS
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
31b2af0a 565 (copy-sequence val)))
785eecbb
RS
566 )))
567 '(c-backslash-column
568 c-basic-offset
569 c-cleanup-list
570 c-comment-only-line-offset
571 c-electric-pound-behavior
572 c-hanging-braces-alist
573 c-hanging-colons-alist
574 c-hanging-comment-starter-p
575 c-hanging-comment-ender-p
576 c-offsets-alist
577 )))
578 ;; the default style is now GNU. This can be overridden in
579 ;; c-mode-common-hook or {c,c++,objc,java}-mode-hook.
580 (c-set-style c-site-default-style))))
581
582(defun c-make-styles-buffer-local ()
583 "Make all CC Mode style variables buffer local.
584If you edit primarily one style of C (or C++, Objective-C, Java) code,
585you probably want style variables to be global. This is the default.
586
587If you edit many different styles of C (or C++, Objective-C, Java) at
588the same time, you probably want the CC Mode style variables to be
589buffer local. If you do, then you will need to set any CC Mode style
590variables in a hook function (e.g. off of c-mode-common-hook), instead
591of at the top level of your ~/.emacs file.
592
593This function makes all the CC Mode style variables buffer local.
594Call it after CC Mode is loaded into your Emacs environment.
595Conversely, set the variable `c-style-variables-are-local-p' to t in
596your .emacs file, before CC Mode is loaded, and this function will be
597automatically called when CC Mode is loaded."
598 ;; style variables
599 (make-variable-buffer-local 'c-offsets-alist)
600 (make-variable-buffer-local 'c-basic-offset)
601 (make-variable-buffer-local 'c-file-style)
602 (make-variable-buffer-local 'c-file-offsets)
603 (make-variable-buffer-local 'c-comment-only-line-offset)
604 (make-variable-buffer-local 'c-cleanup-list)
605 (make-variable-buffer-local 'c-hanging-braces-alist)
606 (make-variable-buffer-local 'c-hanging-colons-alist)
607 (make-variable-buffer-local 'c-hanging-comment-starter-p)
608 (make-variable-buffer-local 'c-hanging-comment-ender-p)
609 (make-variable-buffer-local 'c-backslash-column)
610 (make-variable-buffer-local 'c-label-minimum-indentation)
611 (make-variable-buffer-local 'c-special-indent-hook)
612 (make-variable-buffer-local 'c-indentation-style))
613
614\f
615(provide 'cc-styles)
616;;; cc-styles.el ends here