comparison lisp/cc-mode/cc-styles.el @ 165:5a88923fcbfe r20-3b9

Import from CVS: tag r20-3b9
author cvs
date Mon, 13 Aug 2007 09:44:42 +0200
parents
children 85ec50267440
comparison
equal deleted inserted replaced
164:4e0740e5aab2 165:5a88923fcbfe
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.11
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 (load-file "./cc-align.el"))
32
33
34 (defconst c-style-alist
35 '(("gnu"
36 (c-basic-offset . 2)
37 (c-comment-only-line-offset . (0 . 0))
38 (c-offsets-alist . ((statement-block-intro . +)
39 (knr-argdecl-intro . 5)
40 (substatement-open . +)
41 (label . 0)
42 (statement-case-open . +)
43 (statement-cont . +)
44 (arglist-intro . c-lineup-arglist-intro-after-paren)
45 (arglist-close . c-lineup-arglist)
46 ))
47 (c-special-indent-hook . c-gnu-impose-minimum)
48 )
49 ("k&r"
50 (c-basic-offset . 5)
51 (c-comment-only-line-offset . 0)
52 (c-offsets-alist . ((statement-block-intro . +)
53 (knr-argdecl-intro . 0)
54 (substatement-open . 0)
55 (label . 0)
56 (statement-cont . +)
57 ))
58 )
59 ("bsd"
60 (c-basic-offset . 4)
61 (c-comment-only-line-offset . 0)
62 (c-offsets-alist . ((statement-block-intro . +)
63 (knr-argdecl-intro . +)
64 (substatement-open . 0)
65 (label . 0)
66 (statement-cont . +)
67 ))
68 )
69 ("stroustrup"
70 (c-basic-offset . 4)
71 (c-comment-only-line-offset . 0)
72 (c-offsets-alist . ((statement-block-intro . +)
73 (substatement-open . 0)
74 (label . 0)
75 (statement-cont . +)
76 ))
77 )
78 ("whitesmith"
79 (c-basic-offset . 4)
80 (c-comment-only-line-offset . 0)
81 (c-offsets-alist . ((statement-block-intro . +)
82 (knr-argdecl-intro . +)
83 (substatement-open . 0)
84 (label . 0)
85 (statement-cont . +)
86 ))
87
88 )
89 ("ellemtel"
90 (c-basic-offset . 3)
91 (c-comment-only-line-offset . 0)
92 (c-hanging-braces-alist . ((substatement-open before after)))
93 (c-offsets-alist . ((topmost-intro . 0)
94 (topmost-intro-cont . 0)
95 (substatement . +)
96 (substatement-open . 0)
97 (case-label . +)
98 (access-label . -)
99 (inclass . ++)
100 (inline-open . 0)
101 ))
102 )
103 ("linux"
104 (c-basic-offset . 8)
105 (c-comment-only-line-offset . 0)
106 (c-hanging-braces-alist . ((brace-list-open)
107 (substatement-open after)
108 (block-close . c-snug-do-while)))
109 (c-cleanup-list . (brace-else-brace))
110 (c-offsets-alist . ((statement-block-intro . +)
111 (knr-argdecl-intro . 0)
112 (substatement-open . 0)
113 (label . 0)
114 (statement-cont . +)
115 ))
116 )
117 ("python"
118 (indent-tabs-mode . t)
119 (fill-column . 72)
120 (c-basic-offset . 8)
121 (c-offsets-alist . ((substatement-open . 0)
122 ))
123 (c-hanging-braces-alist . ((brace-list-open)
124 (brace-list-intro)
125 (brace-list-close)
126 (substatement-open after)
127 (block-close . c-snug-do-while)
128 ))
129 )
130 ("java"
131 (c-basic-offset . 2)
132 (c-comment-only-line-offset . (0 . 0))
133 (c-offsets-alist . ((topmost-intro-cont . +)
134 (statement-block-intro . +)
135 (knr-argdecl-intro . 5)
136 (substatement-open . +)
137 (label . 0)
138 (statement-case-open . +)
139 (statement-cont . +)
140 (arglist-intro . c-lineup-arglist-intro-after-paren)
141 (arglist-close . c-lineup-arglist)
142 (access-label . 0)
143 (inher-cont . c-lineup-java-inher)
144 (func-decl-cont . c-lineup-java-throws)
145 ))
146
147 )
148 )
149 "Styles of indentation.
150 Elements of this alist are of the form:
151
152 (STYLE-STRING [BASE-STYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
153
154 where STYLE-STRING is a short descriptive string used to select a
155 style, VARIABLE is any Emacs variable, and VALUE is the intended value
156 for that variable when using the selected style.
157
158 Optional BASE-STYLE if present, is a string and must follow
159 STYLE-STRING. BASE-STYLE names a style that this style inherits from.
160 By default, all styles inherit from the \"cc-mode\" style, which is
161 computed at run time. Style loops generate errors.
162
163 Two variables are treated specially. When VARIABLE is
164 `c-offsets-alist', the VALUE is a list containing elements of the
165 form:
166
167 (SYNTACTIC-SYMBOL . OFFSET)
168
169 as described in `c-offsets-alist'. These are passed directly to
170 `c-set-offset' so there is no need to set every syntactic symbol in
171 your style, only those that are different from the default.
172
173 When VARIABLE is `c-special-indent-hook', its VALUE is added to
174 `c-special-indent-hook' using `add-hook'. If VALUE is a list, each
175 element of the list is added with `add-hook'.
176
177 Do not change this variable directly. Use the function `c-add-style'
178 to add new styles or modify existing styles (it is not a good idea to
179 modify existing styles -- you should create a new style that inherits
180 the existing style.")
181
182
183 ;; Functions that manipulate styles
184 (defun c-set-style-1 (conscell)
185 ;; Set the style for one variable
186 (let ((attr (car conscell))
187 (val (cdr conscell)))
188 (cond
189 ;; first special variable
190 ((eq attr 'c-offsets-alist)
191 (mapcar
192 (function
193 (lambda (langentry)
194 (let ((langelem (car langentry))
195 (offset (cdr langentry)))
196 (c-set-offset langelem offset)
197 )))
198 val))
199 ;; second special variable
200 ((eq attr 'c-special-indent-hook)
201 (if (listp val)
202 (while val
203 (add-hook 'c-special-indent-hook (car val))
204 (setq val (cdr val)))
205 (add-hook 'c-special-indent-hook val)))
206 ;; all other variables
207 (t (set attr val)))
208 ))
209
210 (defun c-set-style-2 (style basestyles)
211 ;; Recursively set the base style. If no base style is given, the
212 ;; default base style is "cc-mode" and the recursion stops. Be sure
213 ;; to detect loops.
214 (if (not (string-equal style "cc-mode"))
215 (let ((base (if (stringp (car basestyles))
216 (downcase (car basestyles))
217 "cc-mode")))
218 (if (memq base basestyles)
219 (error "Style loop detected: %s in %s" base basestyles))
220 (c-set-style-2 base (cons base basestyles))))
221 (let ((vars (cdr (or (assoc (downcase style) c-style-alist)
222 (assoc (upcase style) c-style-alist)
223 (assoc style c-style-alist)
224 (error "Undefined style: %s" style)))))
225 (mapcar 'c-set-style-1 vars)))
226
227 (defvar c-set-style-history nil)
228
229 ;;;###autoload
230 (defun c-set-style (stylename)
231 "Set CC Mode variables to use one of several different indentation styles.
232 STYLENAME is a string representing the desired style from the list of
233 styles described in the variable `c-style-alist'. See that variable
234 for details of setting up styles.
235
236 The variable `c-indentation-style' always contains the buffer's current
237 style name."
238 (interactive (list (let ((completion-ignore-case t)
239 (prompt (format "Which %s indentation style? "
240 mode-name)))
241 (completing-read prompt c-style-alist nil t
242 (cons c-indentation-style 0)
243 'c-set-style-history))))
244 (c-set-style-2 stylename nil)
245 (setq c-indentation-style stylename)
246 (c-keep-region-active))
247
248 ;;;###autoload
249 (defun c-add-style (style descrip &optional set-p)
250 "Adds a style to `c-style-alist', or updates an existing one.
251 STYLE is a string identifying the style to add or update. DESCRIP is
252 an association list describing the style and must be of the form:
253
254 ([BASESTYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...])
255
256 See the variable `c-style-alist' for the semantics of BASESTYLE,
257 VARIABLE and VALUE. This function also sets the current style to
258 STYLE using `c-set-style' if the optional SET-P flag is non-nil."
259 (interactive
260 (let ((stylename (completing-read "Style to add: " c-style-alist
261 nil nil nil 'c-set-style-history))
262 (description (eval-minibuffer "Style description: ")))
263 (list stylename description
264 (y-or-n-p "Set the style too? "))))
265 (setq style (downcase style))
266 (let ((s (assoc style c-style-alist)))
267 (if s
268 (setcdr s (copy-alist descrip)) ; replace
269 (setq c-style-alist (cons (cons style descrip) c-style-alist))))
270 (and set-p (c-set-style style)))
271
272
273
274 (defconst c-offsets-alist
275 '((string . -1000)
276 (c . c-lineup-C-comments)
277 (defun-open . 0)
278 (defun-close . 0)
279 (defun-block-intro . +)
280 (class-open . 0)
281 (class-close . 0)
282 (inline-open . +)
283 (inline-close . 0)
284 (func-decl-cont . +)
285 (knr-argdecl-intro . +)
286 (knr-argdecl . 0)
287 (topmost-intro . 0)
288 (topmost-intro-cont . 0)
289 (member-init-intro . +)
290 (member-init-cont . 0)
291 (inher-intro . +)
292 (inher-cont . c-lineup-multi-inher)
293 (block-open . 0)
294 (block-close . 0)
295 (brace-list-open . 0)
296 (brace-list-close . 0)
297 (brace-list-intro . +)
298 (brace-list-entry . 0)
299 (statement . 0)
300 ;; some people might prefer
301 ;;(statement . c-lineup-runin-statements)
302 (statement-cont . +)
303 ;; some people might prefer
304 ;;(statement-cont . c-lineup-math)
305 (statement-block-intro . +)
306 (statement-case-intro . +)
307 (statement-case-open . 0)
308 (substatement . +)
309 (substatement-open . +)
310 (case-label . 0)
311 (access-label . -)
312 (label . 2)
313 (do-while-closure . 0)
314 (else-clause . 0)
315 (comment-intro . c-lineup-comment)
316 (arglist-intro . +)
317 (arglist-cont . 0)
318 (arglist-cont-nonempty . c-lineup-arglist)
319 (arglist-close . +)
320 (stream-op . c-lineup-streamop)
321 (inclass . +)
322 (cpp-macro . -1000)
323 (friend . 0)
324 (objc-method-intro . -1000)
325 (objc-method-args-cont . c-lineup-ObjC-method-args)
326 (objc-method-call-cont . c-lineup-ObjC-method-call)
327 (extern-lang-open . 0)
328 (extern-lang-close . 0)
329 (inextern-lang . +)
330 )
331 "Association list of syntactic element symbols and indentation offsets.
332 As described below, each cons cell in this list has the form:
333
334 (SYNTACTIC-SYMBOL . OFFSET)
335
336 When a line is indented, CC Mode first determines the syntactic
337 context of the line by generating a list of symbols called syntactic
338 elements. This list can contain more than one syntactic element and
339 the global variable `c-syntactic-context' contains the context list
340 for the line being indented. Each element in this list is actually a
341 cons cell of the syntactic symbol and a buffer position. This buffer
342 position is called the relative indent point for the line. Some
343 syntactic symbols may not have a relative indent point associated with
344 them.
345
346 After the syntactic context list for a line is generated, CC Mode
347 calculates the absolute indentation for the line by looking at each
348 syntactic element in the list. First, it compares the syntactic
349 element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'. When it
350 finds a match, it adds the OFFSET to the column of the relative indent
351 point. The sum of this calculation for each element in the syntactic
352 list is the absolute offset for line being indented.
353
354 If the syntactic element does not match any in the `c-offsets-alist',
355 an error is generated if `c-strict-syntax-p' is non-nil, otherwise the
356 element is ignored.
357
358 Actually, OFFSET can be an integer, a function, a variable, or one of
359 the following symbols: `+', `-', `++', `--', `*', or `/'. These
360 latter designate positive or negative multiples of `c-basic-offset',
361 respectively: 1, -1, 2, -2, 0.5, and -0.5. If OFFSET is a function, it
362 is called with a single argument containing the cons of the syntactic
363 element symbol and the relative indent point. The function should
364 return an integer offset.
365
366 Here is the current list of valid syntactic element symbols:
367
368 string -- inside multi-line string
369 c -- inside a multi-line C style block comment
370 defun-open -- brace that opens a function definition
371 defun-close -- brace that closes a function definition
372 defun-block-intro -- the first line in a top-level defun
373 class-open -- brace that opens a class definition
374 class-close -- brace that closes a class definition
375 inline-open -- brace that opens an in-class inline method
376 inline-close -- brace that closes an in-class inline method
377 func-decl-cont -- the region between a function definition's
378 argument list and the function opening brace
379 (excluding K&R argument declarations). In C, you
380 cannot put anything but whitespace and comments
381 between them; in C++ and Java, throws declarations
382 and other things can appear in this context.
383 knr-argdecl-intro -- first line of a K&R C argument declaration
384 knr-argdecl -- subsequent lines in a K&R C argument declaration
385 topmost-intro -- the first line in a topmost construct definition
386 topmost-intro-cont -- topmost definition continuation lines
387 member-init-intro -- first line in a member initialization list
388 member-init-cont -- subsequent member initialization list lines
389 inher-intro -- first line of a multiple inheritance list
390 inher-cont -- subsequent multiple inheritance lines
391 block-open -- statement block open brace
392 block-close -- statement block close brace
393 brace-list-open -- open brace of an enum or static array list
394 brace-list-close -- close brace of an enum or static array list
395 brace-list-intro -- first line in an enum or static array list
396 brace-list-entry -- subsequent lines in an enum or static array list
397 statement -- a C (or like) statement
398 statement-cont -- a continuation of a C (or like) statement
399 statement-block-intro -- the first line in a new statement block
400 statement-case-intro -- the first line in a case \"block\"
401 statement-case-open -- the first line in a case block starting with brace
402 substatement -- the first line after an if/while/for/do/else
403 substatement-open -- the brace that opens a substatement block
404 case-label -- a `case' or `default' label
405 access-label -- C++ private/protected/public access label
406 label -- any ordinary label
407 do-while-closure -- the `while' that ends a do/while construct
408 else-clause -- the `else' of an if/else construct
409 comment-intro -- a line containing only a comment introduction
410 arglist-intro -- the first line in an argument list
411 arglist-cont -- subsequent argument list lines when no
412 arguments follow on the same line as the
413 arglist opening paren
414 arglist-cont-nonempty -- subsequent argument list lines when at
415 least one argument follows on the same
416 line as the arglist opening paren
417 arglist-close -- the solo close paren of an argument list
418 stream-op -- lines continuing a stream operator construct
419 inclass -- the construct is nested inside a class definition
420 cpp-macro -- the start of a cpp macro
421 friend -- a C++ friend declaration
422 objc-method-intro -- the first line of an Objective-C method definition
423 objc-method-args-cont -- lines continuing an Objective-C method definition
424 objc-method-call-cont -- lines continuing an Objective-C method call
425 extern-lang-open -- brace that opens an external language block
426 extern-lang-close -- brace that closes an external language block
427 inextern-lang -- analogous to `inclass' syntactic symbol
428 ")
429
430 (defun c-get-offset (langelem)
431 ;; Get offset from LANGELEM which is a cons cell of the form:
432 ;; (SYMBOL . RELPOS). The symbol is matched against
433 ;; c-offsets-alist and the offset found there is either returned,
434 ;; or added to the indentation at RELPOS. If RELPOS is nil, then
435 ;; the offset is simply returned.
436 (let* ((symbol (car langelem))
437 (relpos (cdr langelem))
438 (match (assq symbol c-offsets-alist))
439 (offset (cdr-safe match)))
440 ;; offset can be a number, a function, a variable, or one of the
441 ;; symbols + or -
442 (cond
443 ((not match)
444 (if c-strict-syntax-p
445 (error "don't know how to indent a %s" symbol)
446 (setq offset 0
447 relpos 0)))
448 ((eq offset '+) (setq offset c-basic-offset))
449 ((eq offset '-) (setq offset (- c-basic-offset)))
450 ((eq offset '++) (setq offset (* 2 c-basic-offset)))
451 ((eq offset '--) (setq offset (* 2 (- c-basic-offset))))
452 ((eq offset '*) (setq offset (/ c-basic-offset 2)))
453 ((eq offset '/) (setq offset (/ (- c-basic-offset) 2)))
454 ((functionp offset) (setq offset (funcall offset langelem)))
455 ((not (numberp offset)) (setq offset (symbol-value offset)))
456 )
457 (+ (if (and relpos
458 (< relpos (c-point 'bol)))
459 (save-excursion
460 (goto-char relpos)
461 (current-column))
462 0)
463 offset)))
464
465
466 (defvar c-read-offset-history nil)
467
468 (defun c-read-offset (langelem)
469 ;; read new offset value for LANGELEM from minibuffer. return a
470 ;; legal value only
471 (let* ((oldoff (cdr-safe (assq langelem c-offsets-alist)))
472 (defstr (format "(default %s): " oldoff))
473 (errmsg (concat "Offset must be int, func, var, "
474 "or in [+,-,++,--,*,/] "
475 defstr))
476 (prompt (concat "Offset " defstr))
477 offset input interned raw)
478 (while (not offset)
479 (setq input (completing-read prompt obarray 'fboundp nil nil
480 'c-read-offset-history)
481 offset (cond ((string-equal "" input) oldoff) ; default
482 ((string-equal "+" input) '+)
483 ((string-equal "-" input) '-)
484 ((string-equal "++" input) '++)
485 ((string-equal "--" input) '--)
486 ((string-equal "*" input) '*)
487 ((string-equal "/" input) '/)
488 ((string-match "^-?[0-9]+$" input)
489 (string-to-int input))
490 ;; a symbol with a function binding
491 ((fboundp (setq interned (intern input)))
492 interned)
493 ;; a lambda function
494 ((c-safe (functionp (setq raw (read input))))
495 raw)
496 ;; a symbol with variable binding
497 ((boundp interned) interned)
498 ;; error, but don't signal one, keep trying
499 ;; to read an input value
500 (t (ding)
501 (setq prompt errmsg)
502 nil))))
503 offset))
504
505 (defun c-set-offset (symbol offset &optional add-p)
506 "Change the value of a syntactic element symbol in `c-offsets-alist'.
507 SYMBOL is the syntactic element symbol to change and OFFSET is the new
508 offset for that syntactic element. Optional ADD says to add SYMBOL to
509 `c-offsets-alist' if it doesn't already appear there."
510 (interactive
511 (let* ((langelem
512 (intern (completing-read
513 (concat "Syntactic symbol to change"
514 (if current-prefix-arg " or add" "")
515 ": ")
516 (mapcar
517 #'(lambda (langelem)
518 (cons (format "%s" (car langelem)) nil))
519 c-offsets-alist)
520 nil (not current-prefix-arg)
521 ;; initial contents tries to be the last element
522 ;; on the syntactic analysis list for the current
523 ;; line
524 (let* ((syntax (c-guess-basic-syntax))
525 (len (length syntax))
526 (ic (format "%s" (car (nth (1- len) syntax)))))
527 (cons ic 0))
528 )))
529 (offset (c-read-offset langelem)))
530 (list langelem offset current-prefix-arg)))
531 ;; sanity check offset
532 (or (eq offset '+)
533 (eq offset '-)
534 (eq offset '++)
535 (eq offset '--)
536 (eq offset '*)
537 (eq offset '/)
538 (integerp offset)
539 (functionp offset)
540 (boundp offset)
541 (error "Offset must be int, func, var, or in [+,-,++,--,*,/]: %s"
542 offset))
543 (let ((entry (assq symbol c-offsets-alist)))
544 (if entry
545 (setcdr entry offset)
546 (if add-p
547 (setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist))
548 (error "%s is not a valid syntactic symbol." symbol))))
549 (c-keep-region-active))
550
551
552
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!
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.
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.
587
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.
593
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."
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 (if c-style-variables-are-local-p
616 (c-make-styles-buffer-local))
617
618
619
620 (provide 'cc-styles)
621 ;;; cc-styles.el ends here