| 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: See cc-mode.el |
| 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 | (c-comment-continuation-stars . "") |
| 47 | (c-hanging-comment-ender-p . t) |
| 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 | (inextern-lang . 0) |
| 123 | (arglist-intro . +) |
| 124 | (knr-argdecl-intro . +) |
| 125 | )) |
| 126 | (c-hanging-braces-alist . ((brace-list-open) |
| 127 | (brace-list-intro) |
| 128 | (brace-list-close) |
| 129 | (substatement-open after) |
| 130 | (block-close . c-snug-do-while) |
| 131 | )) |
| 132 | (c-comment-continuation-stars . "") |
| 133 | (c-hanging-comment-ender-p . nil) |
| 134 | (fill-column . 78) |
| 135 | ) |
| 136 | ("java" |
| 137 | (c-basic-offset . 2) |
| 138 | (c-comment-only-line-offset . (0 . 0)) |
| 139 | ;; the following preserves Javadoc starter lines |
| 140 | (c-hanging-comment-starter-p . nil) |
| 141 | (c-offsets-alist . ((topmost-intro-cont . +) |
| 142 | (statement-block-intro . +) |
| 143 | (knr-argdecl-intro . 5) |
| 144 | (substatement-open . +) |
| 145 | (label . 0) |
| 146 | (statement-case-open . +) |
| 147 | (statement-cont . +) |
| 148 | (arglist-intro . c-lineup-arglist-intro-after-paren) |
| 149 | (arglist-close . c-lineup-arglist) |
| 150 | (access-label . 0) |
| 151 | (inher-cont . c-lineup-java-inher) |
| 152 | (func-decl-cont . c-lineup-java-throws) |
| 153 | )) |
| 154 | |
| 155 | ) |
| 156 | ) |
| 157 | "Styles of indentation. |
| 158 | Elements of this alist are of the form: |
| 159 | |
| 160 | (STYLE-STRING [BASE-STYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...]) |
| 161 | |
| 162 | where STYLE-STRING is a short descriptive string used to select a |
| 163 | style, VARIABLE is any Emacs variable, and VALUE is the intended value |
| 164 | for that variable when using the selected style. |
| 165 | |
| 166 | Optional BASE-STYLE if present, is a string and must follow |
| 167 | STYLE-STRING. BASE-STYLE names a style that this style inherits from. |
| 168 | By default, all styles inherit from the \"cc-mode\" style, which is |
| 169 | computed at run time. Style loops generate errors. |
| 170 | |
| 171 | Two variables are treated specially. When VARIABLE is |
| 172 | `c-offsets-alist', the VALUE is a list containing elements of the |
| 173 | form: |
| 174 | |
| 175 | (SYNTACTIC-SYMBOL . OFFSET) |
| 176 | |
| 177 | as described in `c-offsets-alist'. These are passed directly to |
| 178 | `c-set-offset' so there is no need to set every syntactic symbol in |
| 179 | your style, only those that are different from the default. |
| 180 | |
| 181 | When VARIABLE is `c-special-indent-hook', its VALUE is added to |
| 182 | `c-special-indent-hook' using `add-hook'. If VALUE is a list, each |
| 183 | element of the list is added with `add-hook'. |
| 184 | |
| 185 | Do not change this variable directly. Use the function `c-add-style' |
| 186 | to add new styles or modify existing styles (it is not a good idea to |
| 187 | modify existing styles -- you should create a new style that inherits |
| 188 | the existing style.") |
| 189 | |
| 190 | \f |
| 191 | ;; Functions that manipulate styles |
| 192 | (defun c-set-style-1 (conscell) |
| 193 | ;; Set the style for one variable |
| 194 | (let ((attr (car conscell)) |
| 195 | (val (cdr conscell))) |
| 196 | (cond |
| 197 | ;; first special variable |
| 198 | ((eq attr 'c-offsets-alist) |
| 199 | (mapcar |
| 200 | (function |
| 201 | (lambda (langentry) |
| 202 | (let ((langelem (car langentry)) |
| 203 | (offset (cdr langentry))) |
| 204 | (c-set-offset langelem offset) |
| 205 | ))) |
| 206 | val)) |
| 207 | ;; second special variable |
| 208 | ((eq attr 'c-special-indent-hook) |
| 209 | (if (listp val) |
| 210 | (while val |
| 211 | (add-hook 'c-special-indent-hook (car val)) |
| 212 | (setq val (cdr val))) |
| 213 | (add-hook 'c-special-indent-hook val))) |
| 214 | ;; all other variables |
| 215 | (t (set attr val))) |
| 216 | )) |
| 217 | |
| 218 | (defun c-set-style-2 (style basestyles) |
| 219 | ;; Recursively set the base style. If no base style is given, the |
| 220 | ;; default base style is "cc-mode" and the recursion stops. Be sure |
| 221 | ;; to detect loops. |
| 222 | (let ((vars (cdr (or (assoc (downcase style) c-style-alist) |
| 223 | (assoc (upcase style) c-style-alist) |
| 224 | (assoc style c-style-alist) |
| 225 | (error "Undefined style: %s" style))))) |
| 226 | (if (not (string-equal style "cc-mode")) |
| 227 | (let ((base (if (stringp (car vars)) |
| 228 | (prog1 |
| 229 | (downcase (car vars)) |
| 230 | (setq vars (cdr vars))) |
| 231 | "cc-mode"))) |
| 232 | (if (memq base basestyles) |
| 233 | (error "Style loop detected: %s in %s" base basestyles)) |
| 234 | (c-set-style-2 base (cons base basestyles)))) |
| 235 | (mapcar 'c-set-style-1 vars))) |
| 236 | |
| 237 | (defvar c-set-style-history nil) |
| 238 | |
| 239 | ;;;###autoload |
| 240 | (defun c-set-style (stylename) |
| 241 | "Set CC Mode variables to use one of several different indentation styles. |
| 242 | STYLENAME is a string representing the desired style from the list of |
| 243 | styles described in the variable `c-style-alist'. See that variable |
| 244 | for details of setting up styles. |
| 245 | |
| 246 | The variable `c-indentation-style' always contains the buffer's current |
| 247 | style name." |
| 248 | (interactive (list (let ((completion-ignore-case t) |
| 249 | (prompt (format "Which %s indentation style? " |
| 250 | mode-name))) |
| 251 | (completing-read prompt c-style-alist nil t |
| 252 | (cons c-indentation-style 0) |
| 253 | 'c-set-style-history)))) |
| 254 | (c-initialize-builtin-style) |
| 255 | (c-set-style-2 stylename nil) |
| 256 | (setq c-indentation-style stylename) |
| 257 | (c-keep-region-active)) |
| 258 | |
| 259 | ;;;###autoload |
| 260 | (defun c-add-style (style descrip &optional set-p) |
| 261 | "Adds a style to `c-style-alist', or updates an existing one. |
| 262 | STYLE is a string identifying the style to add or update. DESCRIP is |
| 263 | an association list describing the style and must be of the form: |
| 264 | |
| 265 | ([BASESTYLE] (VARIABLE . VALUE) [(VARIABLE . VALUE) ...]) |
| 266 | |
| 267 | See the variable `c-style-alist' for the semantics of BASESTYLE, |
| 268 | VARIABLE and VALUE. This function also sets the current style to |
| 269 | STYLE using `c-set-style' if the optional SET-P flag is non-nil." |
| 270 | (interactive |
| 271 | (let ((stylename (completing-read "Style to add: " c-style-alist |
| 272 | nil nil nil 'c-set-style-history)) |
| 273 | (description (eval-minibuffer "Style description: "))) |
| 274 | (list stylename description |
| 275 | (y-or-n-p "Set the style too? ")))) |
| 276 | (setq style (downcase style)) |
| 277 | (let ((s (assoc style c-style-alist))) |
| 278 | (if s |
| 279 | (setcdr s (copy-alist descrip)) ; replace |
| 280 | (setq c-style-alist (cons (cons style descrip) c-style-alist)))) |
| 281 | (and set-p (c-set-style style))) |
| 282 | |
| 283 | |
| 284 | \f |
| 285 | (defconst c-offsets-alist |
| 286 | '((string . -1000) |
| 287 | (c . c-lineup-C-comments) |
| 288 | (defun-open . 0) |
| 289 | (defun-close . 0) |
| 290 | (defun-block-intro . +) |
| 291 | (class-open . 0) |
| 292 | (class-close . 0) |
| 293 | (inline-open . +) |
| 294 | (inline-close . 0) |
| 295 | (func-decl-cont . +) |
| 296 | (knr-argdecl-intro . +) |
| 297 | (knr-argdecl . 0) |
| 298 | (topmost-intro . 0) |
| 299 | (topmost-intro-cont . 0) |
| 300 | (member-init-intro . +) |
| 301 | (member-init-cont . 0) |
| 302 | (inher-intro . +) |
| 303 | (inher-cont . c-lineup-multi-inher) |
| 304 | (block-open . 0) |
| 305 | (block-close . 0) |
| 306 | (brace-list-open . 0) |
| 307 | (brace-list-close . 0) |
| 308 | (brace-list-intro . +) |
| 309 | (brace-list-entry . 0) |
| 310 | (statement . 0) |
| 311 | ;; some people might prefer |
| 312 | ;;(statement . c-lineup-runin-statements) |
| 313 | (statement-cont . +) |
| 314 | ;; some people might prefer |
| 315 | ;;(statement-cont . c-lineup-math) |
| 316 | (statement-block-intro . +) |
| 317 | (statement-case-intro . +) |
| 318 | (statement-case-open . 0) |
| 319 | (substatement . +) |
| 320 | (substatement-open . +) |
| 321 | (case-label . 0) |
| 322 | (access-label . -) |
| 323 | (label . 2) |
| 324 | (do-while-closure . 0) |
| 325 | (else-clause . 0) |
| 326 | (comment-intro . c-lineup-comment) |
| 327 | (arglist-intro . +) |
| 328 | (arglist-cont . 0) |
| 329 | (arglist-cont-nonempty . c-lineup-arglist) |
| 330 | (arglist-close . +) |
| 331 | (stream-op . c-lineup-streamop) |
| 332 | (inclass . +) |
| 333 | (cpp-macro . -1000) |
| 334 | (friend . 0) |
| 335 | (objc-method-intro . -1000) |
| 336 | (objc-method-args-cont . c-lineup-ObjC-method-args) |
| 337 | (objc-method-call-cont . c-lineup-ObjC-method-call) |
| 338 | (extern-lang-open . 0) |
| 339 | (extern-lang-close . 0) |
| 340 | (inextern-lang . +) |
| 341 | (template-args-cont . +) |
| 342 | ) |
| 343 | "Association list of syntactic element symbols and indentation offsets. |
| 344 | As described below, each cons cell in this list has the form: |
| 345 | |
| 346 | (SYNTACTIC-SYMBOL . OFFSET) |
| 347 | |
| 348 | When a line is indented, CC Mode first determines the syntactic |
| 349 | context of the line by generating a list of symbols called syntactic |
| 350 | elements. This list can contain more than one syntactic element and |
| 351 | the global variable `c-syntactic-context' contains the context list |
| 352 | for the line being indented. Each element in this list is actually a |
| 353 | cons cell of the syntactic symbol and a buffer position. This buffer |
| 354 | position is called the relative indent point for the line. Some |
| 355 | syntactic symbols may not have a relative indent point associated with |
| 356 | them. |
| 357 | |
| 358 | After the syntactic context list for a line is generated, CC Mode |
| 359 | calculates the absolute indentation for the line by looking at each |
| 360 | syntactic element in the list. First, it compares the syntactic |
| 361 | element against the SYNTACTIC-SYMBOL's in `c-offsets-alist'. When it |
| 362 | finds a match, it adds the OFFSET to the column of the relative indent |
| 363 | point. The sum of this calculation for each element in the syntactic |
| 364 | list is the absolute offset for line being indented. |
| 365 | |
| 366 | If the syntactic element does not match any in the `c-offsets-alist', |
| 367 | an error is generated if `c-strict-syntax-p' is non-nil, otherwise the |
| 368 | element is ignored. |
| 369 | |
| 370 | Actually, OFFSET can be an integer, a function, a variable, or one of |
| 371 | the following symbols: `+', `-', `++', `--', `*', or `/'. These |
| 372 | latter designate positive or negative multiples of `c-basic-offset', |
| 373 | respectively: 1, -1, 2, -2, 0.5, and -0.5. If OFFSET is a function, it |
| 374 | is called with a single argument containing the cons of the syntactic |
| 375 | element symbol and the relative indent point. The function should |
| 376 | return an integer offset. |
| 377 | |
| 378 | Here is the current list of valid syntactic element symbols: |
| 379 | |
| 380 | string -- inside multi-line string |
| 381 | c -- inside a multi-line C style block comment |
| 382 | defun-open -- brace that opens a function definition |
| 383 | defun-close -- brace that closes a function definition |
| 384 | defun-block-intro -- the first line in a top-level defun |
| 385 | class-open -- brace that opens a class definition |
| 386 | class-close -- brace that closes a class definition |
| 387 | inline-open -- brace that opens an in-class inline method |
| 388 | inline-close -- brace that closes an in-class inline method |
| 389 | func-decl-cont -- the region between a function definition's |
| 390 | argument list and the function opening brace |
| 391 | (excluding K&R argument declarations). In C, you |
| 392 | cannot put anything but whitespace and comments |
| 393 | between them; in C++ and Java, throws declarations |
| 394 | and other things can appear in this context. |
| 395 | knr-argdecl-intro -- first line of a K&R C argument declaration |
| 396 | knr-argdecl -- subsequent lines in a K&R C argument declaration |
| 397 | topmost-intro -- the first line in a topmost construct definition |
| 398 | topmost-intro-cont -- topmost definition continuation lines |
| 399 | member-init-intro -- first line in a member initialization list |
| 400 | member-init-cont -- subsequent member initialization list lines |
| 401 | inher-intro -- first line of a multiple inheritance list |
| 402 | inher-cont -- subsequent multiple inheritance lines |
| 403 | block-open -- statement block open brace |
| 404 | block-close -- statement block close brace |
| 405 | brace-list-open -- open brace of an enum or static array list |
| 406 | brace-list-close -- close brace of an enum or static array list |
| 407 | brace-list-intro -- first line in an enum or static array list |
| 408 | brace-list-entry -- subsequent lines in an enum or static array list |
| 409 | statement -- a C (or like) statement |
| 410 | statement-cont -- a continuation of a C (or like) statement |
| 411 | statement-block-intro -- the first line in a new statement block |
| 412 | statement-case-intro -- the first line in a case \"block\" |
| 413 | statement-case-open -- the first line in a case block starting with brace |
| 414 | substatement -- the first line after an if/while/for/do/else |
| 415 | substatement-open -- the brace that opens a substatement block |
| 416 | case-label -- a `case' or `default' label |
| 417 | access-label -- C++ private/protected/public access label |
| 418 | label -- any ordinary label |
| 419 | do-while-closure -- the `while' that ends a do/while construct |
| 420 | else-clause -- the `else' of an if/else construct |
| 421 | comment-intro -- a line containing only a comment introduction |
| 422 | arglist-intro -- the first line in an argument list |
| 423 | arglist-cont -- subsequent argument list lines when no |
| 424 | arguments follow on the same line as the |
| 425 | arglist opening paren |
| 426 | arglist-cont-nonempty -- subsequent argument list lines when at |
| 427 | least one argument follows on the same |
| 428 | line as the arglist opening paren |
| 429 | arglist-close -- the solo close paren of an argument list |
| 430 | stream-op -- lines continuing a stream operator construct |
| 431 | inclass -- the construct is nested inside a class definition |
| 432 | cpp-macro -- the start of a cpp macro |
| 433 | friend -- a C++ friend declaration |
| 434 | objc-method-intro -- the first line of an Objective-C method definition |
| 435 | objc-method-args-cont -- lines continuing an Objective-C method definition |
| 436 | objc-method-call-cont -- lines continuing an Objective-C method call |
| 437 | extern-lang-open -- brace that opens an external language block |
| 438 | extern-lang-close -- brace that closes an external language block |
| 439 | inextern-lang -- analogous to `inclass' syntactic symbol |
| 440 | template-args-cont -- C++ template argument list continuations |
| 441 | ") |
| 442 | |
| 443 | (defun c-get-offset (langelem) |
| 444 | ;; Get offset from LANGELEM which is a cons cell of the form: |
| 445 | ;; (SYMBOL . RELPOS). The symbol is matched against |
| 446 | ;; c-offsets-alist and the offset found there is either returned, |
| 447 | ;; or added to the indentation at RELPOS. If RELPOS is nil, then |
| 448 | ;; the offset is simply returned. |
| 449 | (let* ((symbol (car langelem)) |
| 450 | (relpos (cdr langelem)) |
| 451 | (match (assq symbol c-offsets-alist)) |
| 452 | (offset (cdr-safe match))) |
| 453 | ;; offset can be a number, a function, a variable, or one of the |
| 454 | ;; symbols + or - |
| 455 | (cond |
| 456 | ((not match) |
| 457 | (if c-strict-syntax-p |
| 458 | (error "don't know how to indent a %s" symbol) |
| 459 | (setq offset 0 |
| 460 | relpos 0))) |
| 461 | ((eq offset '+) (setq offset c-basic-offset)) |
| 462 | ((eq offset '-) (setq offset (- c-basic-offset))) |
| 463 | ((eq offset '++) (setq offset (* 2 c-basic-offset))) |
| 464 | ((eq offset '--) (setq offset (* 2 (- c-basic-offset)))) |
| 465 | ((eq offset '*) (setq offset (/ c-basic-offset 2))) |
| 466 | ((eq offset '/) (setq offset (/ (- c-basic-offset) 2))) |
| 467 | ((functionp offset) (setq offset (funcall offset langelem))) |
| 468 | ((not (numberp offset)) (setq offset (symbol-value offset))) |
| 469 | ) |
| 470 | (+ (if (and relpos |
| 471 | (< relpos (c-point 'bol))) |
| 472 | (save-excursion |
| 473 | (goto-char relpos) |
| 474 | (current-column)) |
| 475 | 0) |
| 476 | offset))) |
| 477 | |
| 478 | \f |
| 479 | (defvar c-read-offset-history nil) |
| 480 | |
| 481 | (defun c-read-offset (langelem) |
| 482 | ;; read new offset value for LANGELEM from minibuffer. return a |
| 483 | ;; legal value only |
| 484 | (let* ((oldoff (cdr-safe (assq langelem c-offsets-alist))) |
| 485 | (defstr (format "(default %s): " oldoff)) |
| 486 | (errmsg (concat "Offset must be int, func, var, " |
| 487 | "or in [+,-,++,--,*,/] " |
| 488 | defstr)) |
| 489 | (prompt (concat "Offset " defstr)) |
| 490 | offset input interned raw) |
| 491 | (while (not offset) |
| 492 | (setq input (completing-read prompt obarray 'fboundp nil nil |
| 493 | 'c-read-offset-history) |
| 494 | offset (cond ((string-equal "" input) oldoff) ; default |
| 495 | ((string-equal "+" input) '+) |
| 496 | ((string-equal "-" input) '-) |
| 497 | ((string-equal "++" input) '++) |
| 498 | ((string-equal "--" input) '--) |
| 499 | ((string-equal "*" input) '*) |
| 500 | ((string-equal "/" input) '/) |
| 501 | ((string-match "^-?[0-9]+$" input) |
| 502 | (string-to-int input)) |
| 503 | ;; a symbol with a function binding |
| 504 | ((fboundp (setq interned (intern input))) |
| 505 | interned) |
| 506 | ;; a lambda function |
| 507 | ((c-safe (functionp (setq raw (read input)))) |
| 508 | raw) |
| 509 | ;; a symbol with variable binding |
| 510 | ((boundp interned) interned) |
| 511 | ;; error, but don't signal one, keep trying |
| 512 | ;; to read an input value |
| 513 | (t (ding) |
| 514 | (setq prompt errmsg) |
| 515 | nil)))) |
| 516 | offset)) |
| 517 | |
| 518 | ;;;###autoload |
| 519 | (defun c-set-offset (symbol offset &optional add-p) |
| 520 | "Change the value of a syntactic element symbol in `c-offsets-alist'. |
| 521 | SYMBOL is the syntactic element symbol to change and OFFSET is the new |
| 522 | offset for that syntactic element. Optional ADD says to add SYMBOL to |
| 523 | `c-offsets-alist' if it doesn't already appear there." |
| 524 | (interactive |
| 525 | (let* ((langelem |
| 526 | (intern (completing-read |
| 527 | (concat "Syntactic symbol to change" |
| 528 | (if current-prefix-arg " or add" "") |
| 529 | ": ") |
| 530 | (mapcar |
| 531 | #'(lambda (langelem) |
| 532 | (cons (format "%s" (car langelem)) nil)) |
| 533 | c-offsets-alist) |
| 534 | nil (not current-prefix-arg) |
| 535 | ;; initial contents tries to be the last element |
| 536 | ;; on the syntactic analysis list for the current |
| 537 | ;; line |
| 538 | (let* ((syntax (c-guess-basic-syntax)) |
| 539 | (len (length syntax)) |
| 540 | (ic (format "%s" (car (nth (1- len) syntax))))) |
| 541 | (cons ic 0)) |
| 542 | ))) |
| 543 | (offset (c-read-offset langelem))) |
| 544 | (list langelem offset current-prefix-arg))) |
| 545 | ;; sanity check offset |
| 546 | (or (eq offset '+) |
| 547 | (eq offset '-) |
| 548 | (eq offset '++) |
| 549 | (eq offset '--) |
| 550 | (eq offset '*) |
| 551 | (eq offset '/) |
| 552 | (integerp offset) |
| 553 | (functionp offset) |
| 554 | (boundp offset) |
| 555 | (error "Offset must be int, func, var, or in [+,-,++,--,*,/]: %s" |
| 556 | offset)) |
| 557 | (let ((entry (assq symbol c-offsets-alist))) |
| 558 | (if entry |
| 559 | (setcdr entry offset) |
| 560 | (if add-p |
| 561 | (setq c-offsets-alist (cons (cons symbol offset) c-offsets-alist)) |
| 562 | (error "%s is not a valid syntactic symbol." symbol)))) |
| 563 | (c-keep-region-active)) |
| 564 | |
| 565 | |
| 566 | \f |
| 567 | (defun c-initialize-builtin-style () |
| 568 | ;; Dynamically append the default value of most variables. This is |
| 569 | ;; crucial because future c-set-style calls will always reset the |
| 570 | ;; variables first to the `cc-mode' style before instituting the new |
| 571 | ;; style. Only do this once! |
| 572 | (or (assoc "cc-mode" c-style-alist) |
| 573 | (let (copyfunc) |
| 574 | ;; use built-in copy-tree if its there. |
| 575 | (if (and (fboundp 'copy-tree) |
| 576 | (functionp (symbol-function 'copy-tree))) |
| 577 | (setq copyfunc (symbol-function 'copy-tree)) |
| 578 | (setq copyfunc (lambda (tree) |
| 579 | (if (consp tree) |
| 580 | (cons (funcall copyfunc (car tree)) |
| 581 | (funcall copyfunc (cdr tree))) |
| 582 | tree)))) |
| 583 | (c-add-style "cc-mode" |
| 584 | (mapcar |
| 585 | (function |
| 586 | (lambda (var) |
| 587 | (let ((val (symbol-value var))) |
| 588 | (cons var (if (atom val) |
| 589 | val |
| 590 | (funcall copyfunc val) |
| 591 | )) |
| 592 | ))) |
| 593 | '(c-backslash-column |
| 594 | c-basic-offset |
| 595 | c-cleanup-list |
| 596 | c-comment-only-line-offset |
| 597 | c-electric-pound-behavior |
| 598 | c-hanging-braces-alist |
| 599 | c-hanging-colons-alist |
| 600 | c-hanging-comment-starter-p |
| 601 | c-hanging-comment-ender-p |
| 602 | c-offsets-alist |
| 603 | ))) |
| 604 | ;; the default style is now GNU. This can be overridden in |
| 605 | ;; c-mode-common-hook or {c,c++,objc,java}-mode-hook. |
| 606 | (c-set-style c-site-default-style))) |
| 607 | (if c-style-variables-are-local-p |
| 608 | (c-make-styles-buffer-local))) |
| 609 | |
| 610 | |
| 611 | (defun c-make-styles-buffer-local () |
| 612 | "Make all CC Mode style variables buffer local. |
| 613 | If you edit primarily one style of C (or C++, Objective-C, Java) code, |
| 614 | you probably want style variables to be global. This is the default. |
| 615 | |
| 616 | If you edit many different styles of C (or C++, Objective-C, Java) at |
| 617 | the same time, you probably want the CC Mode style variables to be |
| 618 | buffer local. If you do, then you will need to set any CC Mode style |
| 619 | variables in a hook function (e.g. off of c-mode-common-hook), instead |
| 620 | of at the top level of your ~/.emacs file. |
| 621 | |
| 622 | This function makes all the CC Mode style variables buffer local. |
| 623 | Call it after CC Mode is loaded into your Emacs environment. |
| 624 | Conversely, set the variable `c-style-variables-are-local-p' to t in |
| 625 | your .emacs file, before CC Mode is loaded, and this function will be |
| 626 | automatically called when CC Mode is loaded." |
| 627 | ;; style variables |
| 628 | (make-variable-buffer-local 'c-offsets-alist) |
| 629 | (make-variable-buffer-local 'c-basic-offset) |
| 630 | (make-variable-buffer-local 'c-file-style) |
| 631 | (make-variable-buffer-local 'c-file-offsets) |
| 632 | (make-variable-buffer-local 'c-comment-only-line-offset) |
| 633 | (make-variable-buffer-local 'c-cleanup-list) |
| 634 | (make-variable-buffer-local 'c-hanging-braces-alist) |
| 635 | (make-variable-buffer-local 'c-hanging-colons-alist) |
| 636 | (make-variable-buffer-local 'c-hanging-comment-starter-p) |
| 637 | (make-variable-buffer-local 'c-hanging-comment-ender-p) |
| 638 | (make-variable-buffer-local 'c-backslash-column) |
| 639 | (make-variable-buffer-local 'c-label-minimum-indentation) |
| 640 | (make-variable-buffer-local 'c-special-indent-hook) |
| 641 | (make-variable-buffer-local 'c-indentation-style)) |
| 642 | |
| 643 | \f |
| 644 | (provide 'cc-styles) |
| 645 | ;;; cc-styles.el ends here |